diff --git a/package-lock.json b/package-lock.json index 4f63cf38..87bdf627 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3764,6 +3764,14 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/@lit-labs/task": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@lit-labs/task/-/task-2.0.0.tgz", + "integrity": "sha512-r567PcR6Koq7DoBwdnMWxyO3Ww9BkJshGmuviwhCcNRATSgDx/O6SEZ95oBfgxN6hKyoYT3lbtRzMPKhKRHUow==", + "dependencies": { + "@lit/reactive-element": "^1.1.0" + } + }, "node_modules/@lit/reactive-element": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.0.tgz", @@ -23805,6 +23813,7 @@ "version": "0.0.0", "license": "Apache-2.0", "dependencies": { + "@lit-labs/task": "^2.0.0", "@webcomponents/catalog-api": "^0.0.0", "lit": "^2.6.0", "lit-analyzer": "^1.2.1" @@ -23818,7 +23827,8 @@ "@11ty/eleventy": "^1.0.2", "@11ty/eleventy-navigation": "^0.3.5", "@webcomponents/internal-site-client": "^0.0.0", - "@webcomponents/internal-site-server": "^0.0.0" + "@webcomponents/internal-site-server": "^0.0.0", + "@webcomponents/internal-site-templates": "^0.0.0" } }, "packages/site-server": { @@ -23839,18 +23849,22 @@ "@types/marked": "^4.0.8", "@web/dev-server": "^0.1.34", "@webcomponents/internal-site-content": "^0.0.0", + "@webcomponents/internal-site-templates": "^0.0.0", "google-auth-library": "^8.7.0", "koa": "^2.13.4", + "koa-bodyparser": "^4.3.0", "koa-conditional-get": "^3.0.0", "koa-etag": "^4.0.0", "koa-static": "^5.0.0", "marked": "^4.2.5" }, "devDependencies": { + "@types/koa-bodyparser": "^4.3.10", "uvu": "^0.5.6" } }, "packages/site-templates": { + "name": "@webcomponents/internal-site-templates", "version": "0.0.0", "license": "Apache-2.0" } @@ -26774,6 +26788,14 @@ "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.0.0.tgz", "integrity": "sha512-ic93MBXfApIFTrup4a70M/+ddD8xdt2zxxj9sRwHQzhS9ag/syqkD8JPdTXsc1gUy2K8TTirhlCqyTEM/sifNw==" }, + "@lit-labs/task": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@lit-labs/task/-/task-2.0.0.tgz", + "integrity": "sha512-r567PcR6Koq7DoBwdnMWxyO3Ww9BkJshGmuviwhCcNRATSgDx/O6SEZ95oBfgxN6hKyoYT3lbtRzMPKhKRHUow==", + "requires": { + "@lit/reactive-element": "^1.1.0" + } + }, "@lit/reactive-element": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.0.tgz", @@ -27648,6 +27670,7 @@ "@webcomponents/internal-site-client": { "version": "file:packages/site-client", "requires": { + "@lit-labs/task": "^2.0.0", "@webcomponents/catalog-api": "^0.0.0", "lit": "^2.6.0", "lit-analyzer": "^1.2.1" @@ -27659,7 +27682,8 @@ "@11ty/eleventy": "^1.0.2", "@11ty/eleventy-navigation": "^0.3.5", "@webcomponents/internal-site-client": "^0.0.0", - "@webcomponents/internal-site-server": "^0.0.0" + "@webcomponents/internal-site-server": "^0.0.0", + "@webcomponents/internal-site-templates": "^0.0.0" } }, "@webcomponents/internal-site-server": { @@ -27672,14 +27696,17 @@ "@types/koa": "^2.13.5", "@types/koa__cors": "^3.3.0", "@types/koa__router": "^12.0.0", + "@types/koa-bodyparser": "*", "@types/koa-conditional-get": "^2.0.0", "@types/koa-etag": "^3.0.0", "@types/koa-static": "^4.0.2", "@types/marked": "^4.0.8", "@web/dev-server": "^0.1.34", "@webcomponents/internal-site-content": "^0.0.0", + "@webcomponents/internal-site-templates": "^0.0.0", "google-auth-library": "^8.7.0", "koa": "^2.13.4", + "koa-bodyparser": "^4.3.0", "koa-conditional-get": "^3.0.0", "koa-etag": "^4.0.0", "koa-static": "^5.0.0", diff --git a/packages/site-client/package.json b/packages/site-client/package.json index 014cf002..f9df9217 100644 --- a/packages/site-client/package.json +++ b/packages/site-client/package.json @@ -86,6 +86,7 @@ } }, "dependencies": { + "@lit-labs/task": "^2.0.0", "@webcomponents/catalog-api": "^0.0.0", "lit": "^2.6.0", "lit-analyzer": "^1.2.1" diff --git a/packages/site-client/src/pages/import/boot.ts b/packages/site-client/src/pages/import/boot.ts new file mode 100644 index 00000000..bc20e8c2 --- /dev/null +++ b/packages/site-client/src/pages/import/boot.ts @@ -0,0 +1,8 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import 'lit/experimental-hydrate-support.js'; +import './wco-catalog-import-page.js'; diff --git a/packages/site-client/src/pages/import/wco-catalog-import-page.ts b/packages/site-client/src/pages/import/wco-catalog-import-page.ts new file mode 100644 index 00000000..86021b79 --- /dev/null +++ b/packages/site-client/src/pages/import/wco-catalog-import-page.ts @@ -0,0 +1,59 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import {html} from 'lit'; +import {customElement, state} from 'lit/decorators.js'; +import {WCOPage} from '../../shared/wco-page.js'; +import {Task} from '@lit-labs/task'; + +@customElement('wco-catalog-import-page') +export class WCOCatalogImportPage extends WCOPage { + private _importTask = new Task(this, { + task: async ([packageName]: [packageName: string | undefined]) => { + console.log('_importTask', packageName); + + if (packageName !== undefined && packageName.trim().length > 0) { + const response = await fetch(`/catalog/import`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + packageName, + }), + }); + const result = await response.json(); + return result; + } + }, + args: () => [this._packageName] as [string], + }); + + @state() + private _packageName?: string; + + renderContent() { + return html` +
${JSON.stringify(value, undefined, 2)}`, + pending: () => html`
Importing package...
`, + })} + `; + } + + private _onPackageNameChange(e: Event) { + this._packageName = (e.target as HTMLInputElement).value; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'wco-catalog-import-page': WCOCatalogImportPage; + } +} diff --git a/packages/site-server/package.json b/packages/site-server/package.json index f8bda43c..786eb196 100644 --- a/packages/site-server/package.json +++ b/packages/site-server/package.json @@ -120,12 +120,14 @@ "@webcomponents/internal-site-templates": "^0.0.0", "google-auth-library": "^8.7.0", "koa": "^2.13.4", + "koa-bodyparser": "^4.3.0", "koa-conditional-get": "^3.0.0", "koa-etag": "^4.0.0", "koa-static": "^5.0.0", "marked": "^4.2.5" }, "devDependencies": { + "@types/koa-bodyparser": "^4.3.10", "uvu": "^0.5.6" } } diff --git a/packages/site-server/src/lib/catalog/router.ts b/packages/site-server/src/lib/catalog/router.ts index c2d76cc1..3958fff1 100644 --- a/packages/site-server/src/lib/catalog/router.ts +++ b/packages/site-server/src/lib/catalog/router.ts @@ -5,17 +5,23 @@ */ import Router from '@koa/router'; -import {handleCatalogRoute} from './routes/catalog/catalog-route.js'; -import {handleCatalogSearchRoute} from './routes/catalog/search-route.js'; -import {handleElementRoute} from './routes/element/element-route.js'; -// import cors from '@koa/cors'; +import {handleCatalogRoute} from './routes/catalog-page.js'; +import {handleCatalogImportRoute} from './routes/import-page.js'; +import {handleCatalogImportApiRoute} from './routes/import-api.js'; +import {handleElementRoute} from './routes/element-page.js'; +import {handleCatalogSearchRoute} from './routes/search-api.js'; +import bodyParser from 'koa-bodyparser'; export const catalogRouter = new Router(); -// catalogRouter.use(cors()); +// Needed for /import +catalogRouter.use(bodyParser()); catalogRouter.get('/', handleCatalogRoute); catalogRouter.get('/search', handleCatalogSearchRoute); +catalogRouter.get('/import', handleCatalogImportRoute); +catalogRouter.post('/import', handleCatalogImportApiRoute); + catalogRouter.get('/element/:path+', handleElementRoute); diff --git a/packages/site-server/src/lib/catalog/routes/catalog/catalog-route.ts b/packages/site-server/src/lib/catalog/routes/catalog-page.ts similarity index 100% rename from packages/site-server/src/lib/catalog/routes/catalog/catalog-route.ts rename to packages/site-server/src/lib/catalog/routes/catalog-page.ts diff --git a/packages/site-server/src/lib/catalog/routes/element/element-route.ts b/packages/site-server/src/lib/catalog/routes/element-page.ts similarity index 99% rename from packages/site-server/src/lib/catalog/routes/element/element-route.ts rename to packages/site-server/src/lib/catalog/routes/element-page.ts index d0de2082..7cfb984f 100644 --- a/packages/site-server/src/lib/catalog/routes/element/element-route.ts +++ b/packages/site-server/src/lib/catalog/routes/element-page.ts @@ -14,7 +14,7 @@ import Router from '@koa/router'; import {marked} from 'marked'; import {renderElementPage} from '@webcomponents/internal-site-client/lib/pages/element/shell.js'; -import {client} from '../../graphql.js'; +import {client} from '../graphql.js'; import type {ElementData} from '@webcomponents/internal-site-client/lib/pages/element/wco-element-page.js'; diff --git a/packages/site-server/src/lib/catalog/routes/import-api.ts b/packages/site-server/src/lib/catalog/routes/import-api.ts new file mode 100644 index 00000000..2f7cedb9 --- /dev/null +++ b/packages/site-server/src/lib/catalog/routes/import-api.ts @@ -0,0 +1,84 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import {DefaultContext, DefaultState, ParameterizedContext} from 'koa'; +import Router from '@koa/router'; +import {client} from '../graphql.js'; +import {gql} from '@apollo/client/core/index.js'; + +const importMutation = gql` + mutation ImportPackage($packageName: String!) { + importPackage(packageName: $packageName) { + ... on ReadablePackageInfo { + version { + ... on ReadablePackageVersion { + version + problems { + code + severity + message + filePath + } + customElements { + tagName + declaration + className + jsExport + } + } + ... on UnreadablePackageVersion { + version + status + problems { + code + severity + message + filePath + } + } + } + } + } + } +`; + +export const handleCatalogImportApiRoute = async ( + context: ParameterizedContext< + DefaultState, + DefaultContext & Router.RouterParamContext