Skip to content

Commit

Permalink
refactor: add partial user code checks
Browse files Browse the repository at this point in the history
  • Loading branch information
marionebl committed Oct 5, 2018
1 parent 13027b1 commit 97dbdbf
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 58 deletions.
2 changes: 1 addition & 1 deletion packages/api/package.json
Expand Up @@ -80,7 +80,7 @@
"require-from-string": "^2.0.1",
"resolve-pkg": "^1.0.0",
"string-hash": "^1.1.3",
"ts-transform-json-schema": "^1.1.1",
"ts-transform-json-schema": "^1.1.2",
"unindent": "^2.0.0",
"ws": "^4.0.0",
"yargs-parser": "^9.0.2",
Expand Down
9 changes: 9 additions & 0 deletions packages/api/src/is-content.ts
@@ -0,0 +1,9 @@
import { fromType } from "ts-transform-json-schema"
import * as T from './types';

const validateOptions = require("schema-utils");
const schema = fromType<T.HtmlContent>() as object;

export function isContent(data: unknown): data is T.HtmlContent {
return validateOptions(schema, data, 'html-content');
}
2 changes: 1 addition & 1 deletion packages/api/src/is-message.ts
Expand Up @@ -10,7 +10,7 @@ export function isMessage(data: unknown): data is T.QueueMessage {
} catch (err) {
const type = typeof data === "object" && data !== null ? (data as any).type || "unknown" : "unknown";
console.error(`Message of type ${type} is invalid: ${err.message}`);
console.log(`Invalid Message: ${JSON.stringify(data)}`);
// console.log(`Invalid Message: ${JSON.stringify(data)}`);
return false;
}
}
9 changes: 9 additions & 0 deletions packages/api/src/is-renderer.ts
@@ -0,0 +1,9 @@
import { fromType } from "ts-transform-json-schema";
import * as T from "./types";

const validateOptions = require("schema-utils");
const schema = fromType<T.Renderer>() as object;

export function isRenderer(data: unknown): data is T.Renderer {
return validateOptions(schema, data, "renderer");
}
34 changes: 16 additions & 18 deletions packages/api/src/routes/cover/cover.ts
@@ -1,10 +1,13 @@
import * as Path from "path";
import * as express from "express";
import * as resolveFrom from "resolve-from";

import { fromFs } from "../../from-fs";
import { html, HtmlContent } from "./html";
import { html } from "./html";
import { wait } from "../../wait";
import * as T from "../../types";
import * as resolveFrom from "resolve-from";
import { isContent } from "../../is-content";
// import {聽isRenderer } from "../../is-renderer";

const AggregateError = require("aggregate-error");

Expand All @@ -26,31 +29,26 @@ export const cover = async (
const getModule = fromFs(fs);

const coverFile = resolveFrom(cwd, options.config.render);
const rawCover = getModule(COVER_PATH, coverFile);

if (typeof rawCover !== "object") {
throw new Error(
`Expected ${config.cover} to export an object, received ${typeof rawCover}`
);
}
const cover = getModule(COVER_PATH, coverFile) as T.Renderer;

const cover = rawCover as { [key: string]: unknown };
// TODO: Enable when ts-transform-json-schema supports functions
// if (!isRenderer(cover)) {
// return;
// }

const renderFile = resolveFrom(cwd, options.config.render);

const render =
typeof cover.render === "function"
? cover.render
: // TODO: Schema checks for renderer
getModule(RENDER_PATH, renderFile) as () => HtmlContent;
const render = cover.render || (getModule(RENDER_PATH, renderFile) as T.Renderer["render"]);

const content = await Promise.resolve(
render(cover, {
render!(cover, {
dirname: Path.dirname(config.cover)
})
);

// TODO: Schema checks for produced content
if (!isContent(content)) {
return;
}

res.send(
html(content, {
base: req.params.base || "/",
Expand Down
12 changes: 2 additions & 10 deletions packages/api/src/routes/cover/html.ts
@@ -1,22 +1,14 @@
import * as Url from "url";
import * as T from "../../types";

const unindent = require("unindent");

export interface HtmlContent {
head?: string;
css?: string;
before?: string;
html?: string;
after?: string;
js?: string;
}

export interface HtmlOptions {
base: string;
scripts?: boolean;
}

export function html(content: HtmlContent, options: HtmlOptions): string {
export function html(content: T.HtmlContent, options: HtmlOptions): string {
const prefix = Url.resolve(options.base, "api");

return unindent(`
Expand Down
22 changes: 12 additions & 10 deletions packages/api/src/routes/demo/demo.ts
Expand Up @@ -5,7 +5,8 @@ import * as resolveFrom from "resolve-from";
import * as T from "../../types";
import { wait } from "../../wait";
import { fromFs } from "../../from-fs";
import { html, HtmlContent } from "./html";
import { html } from "./html";
import { isContent } from "../../is-content";

const AggregateError = require("aggregate-error");

Expand Down Expand Up @@ -37,26 +38,27 @@ export const demo = async function demo(options: T.RouteOptions): Promise<expres
// TODO: verify bundle results
const getModule = fromFs(fs);
const bundle = getModule(BUNDLE_PATH, found.artifact) as { [id: string]: unknown };
const rawCompnent = getComponent(bundle, found);
const component = getComponent(bundle, found) as T.Renderer;

if (typeof rawCompnent !== "object") {
throw new Error(
`Expected ${found.artifact} to export an object, received ${typeof rawCompnent}`
);
}

const component = rawCompnent as { [key: string]: unknown };
// TODO: Enable when ts-transform-json-schema supports functions
// if (!isRenderer(rawCompnent)) {
// return;
// }

const renderFile = resolveFrom(cwd, options.config.render);

const render = typeof component.render === "function"
? component.render
: getModule(RENDER_PATH, renderFile) as () => HtmlContent;
: getModule(RENDER_PATH, renderFile) as () => T.HtmlContent;

const content = await Promise.resolve(
render(component, { dirname: Path.dirname(found.path) })
);

if (!isContent(content)) {
return;
}

res.send(html(content, found));
} catch (err) {
const error = Array.isArray(err) ? new AggregateError(err) : err;
Expand Down
13 changes: 3 additions & 10 deletions packages/api/src/routes/demo/html.ts
@@ -1,20 +1,13 @@
const unindent = require("unindent");
import * as T from "../../types";

export interface HtmlContent {
head?: string;
css?: string;
before?: string;
html?: string;
after?: string;
js?: string;
}
const unindent = require("unindent");

export interface HtmlOptions {
base: string;
scripts?: boolean;
}

export function html(content: HtmlContent, payload: unknown): string {
export function html(content: T.HtmlContent, payload: unknown): string {
const data = encodeURIComponent(JSON.stringify(payload));

return unindent(`
Expand Down
18 changes: 18 additions & 0 deletions packages/api/src/types.ts
Expand Up @@ -92,3 +92,21 @@ export interface RouteOptions {
config: Types.PatternplateConfig;
queue: MsgQueue;
}

export interface Renderer {
head: () => string;
default: () => void;
css?: () => string;
html?: () => string;
js?: () => string;
render?(input: Renderer, ctx: {dirname: string }): HtmlContent;
}

export interface HtmlContent {
head?: string;
css?: string;
before?: string;
html?: string;
after?: string;
js?: string;
}
3 changes: 2 additions & 1 deletion packages/api/tsconfig.json
Expand Up @@ -19,7 +19,8 @@
"required": true
}
}
]
],

},
"include": [
"src/**/*.ts"
Expand Down
35 changes: 28 additions & 7 deletions yarn.lock
Expand Up @@ -657,13 +657,6 @@
call-me-maybe "^1.0.1"
glob-to-regexp "^0.3.0"

"@patternplate/deploy-site@file:./packages/deploy":
version "2.5.18"
dependencies:
"@marionebl/sander" "^0.6.1"
execa "^0.9.0"
meow "^4.0.0"

"@patternplate/validate-manifest@3.0.3":
version "3.0.3"
resolved "https://registry.npmjs.org/@patternplate/validate-manifest/-/validate-manifest-3.0.3.tgz#131c509e52991d9ec67c0dc3dbcf4a61b503fc6d"
Expand Down Expand Up @@ -8663,6 +8656,10 @@ neo-async@^2.5.0:
version "2.5.1"
resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.5.1.tgz#acb909e327b1e87ec9ef15f41b8a269512ad41ee"

nested-error-stacks@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61"

nice-try@^1.0.4:
version "1.0.4"
resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4"
Expand Down Expand Up @@ -12019,6 +12016,26 @@ ts-transform-json-schema@^1.1.1:
resolve "^1.8.1"
typescript-json-schema "^0.32.0"

ts-transform-json-schema@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/ts-transform-json-schema/-/ts-transform-json-schema-1.1.2.tgz#5457c6e36d87270b96ee33b3ee0bfbd4f27c3e96"
dependencies:
"@types/read-pkg-up" "^3.0.1"
"@types/resolve" "0.0.8"
read-pkg-up "^4.0.0"
resolve "^1.8.1"
typescript-json-schema "^0.32.0"

tslib@^1.8.1:
version "1.9.3"
resolved "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"

tsutils@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.0.0.tgz#0c5070a17a0503e056da038c48b5a1870a50a9ad"
dependencies:
tslib "^1.8.1"

tty-browserify@0.0.0:
version "0.0.0"
resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
Expand Down Expand Up @@ -12057,6 +12074,10 @@ typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"

typescript-is@^0.7.8:
version "0.7.8"
resolved "https://registry.npmjs.org/typescript-is/-/typescript-is-0.7.8.tgz#bc4962515fa91debf6187e81137020f95d000484"

typescript-json-schema@^0.32.0:
version "0.32.0"
resolved "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.32.0.tgz#d95af55eaf01be6d44b280fdc3f9b3a264435642"
Expand Down

0 comments on commit 97dbdbf

Please sign in to comment.