Skip to content
This repository has been archived by the owner on Sep 7, 2020. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
🤫 Flow annotations improvements
  • Loading branch information
MoOx committed Mar 13, 2018
1 parent da5a3bb commit 9a91f4e
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 81 deletions.
87 changes: 45 additions & 42 deletions flow/interfaces/phenomic.js
Expand Up @@ -2,11 +2,11 @@ export type PhenomicDBEntryInput = {|
data: Object,
partial: Object
|};
export type PhenomicDBEntry = {
export type PhenomicDBEntry = {|
data: Object,
partial: Object,
id: string
};
|};

export type PhenomicDBEntryPartial = {
id: string
Expand All @@ -19,7 +19,9 @@ export type PhenomicDBEntryDetailed = {
export type PhenomicDBSubRegistry = Array<PhenomicDBEntry>;
export type PhenomicDBRegistry = { [key: string]: PhenomicDBSubRegistry };

export type PhenomicDB = {
export type PhenomicDB = {|
_getDatabase: () => PhenomicDBRegistry,
_setDatabase: PhenomicDBRegistry => void,
destroy: () => Promise<void>,
put: (
sub: null | string | Array<string>,
Expand All @@ -42,29 +44,28 @@ export type PhenomicDB = {
filter?: string,
filterValue?: string
) => Promise<Array<PhenomicDBEntryPartial>>
};
|};

export type PhenomicInputPlugins = {
export type PhenomicInputPlugins = {|
plugins?: Array<(arg: PhenomicInputConfig) => PhenomicPlugin>,
presets?: Array<(arg: PhenomicInputConfig) => PhenomicInputPlugins>
};
|};

export type PhenomicInputConfig = {
export type PhenomicInputConfig = {|
path?: string,
content?: string,
outdir?: string,
port?: number,
bundleName?: string,
plugins?: Array<(arg: PhenomicInputConfig) => PhenomicPlugin>,
presets?: Array<(arg: PhenomicInputConfig) => PhenomicInputPlugins>
};
...PhenomicInputPlugins
|};

export type PhenomicContentFile = {
export type PhenomicContentFile = {|
name: string,
fullpath: string
// exists: boolean,
// type: string
};
|};

type PhenomicTransformResult = {|
data: Object,
Expand All @@ -73,11 +74,11 @@ type PhenomicTransformResult = {|

type ReactCompo = Function;

export type PhenomicAppType = {
export type PhenomicAppType = {|
routes: React$Element<any>
};
|};

type PhenomicIntermediateHtmlPropsType = {
type PhenomicIntermediateHtmlPropsType = {|
WrappedApp: ReactCompo,
renderAsObject: (
app: React$Element<any>
Expand All @@ -86,105 +87,107 @@ type PhenomicIntermediateHtmlPropsType = {
state?: Object | null,
assets: PhenomicAssets
}
};
|};

export type PhenomicHtmlPropsType = {
export type PhenomicHtmlPropsType = {|
App: ReactCompo,
render: (
app: React$Element<any>
) => {
) => {|
assets: PhenomicAssets,
html: string,
Main: ReactCompo,
State: ReactCompo,
Style: ReactCompo,
Script: ReactCompo
}
};
|}
|};

export type PhenomicHtmlType = (
props: PhenomicHtmlPropsType
) => React$Element<any>;

export type PhenomicPluginRenderStaticType = ({
export type PhenomicPluginRenderStaticType = ({|
config: PhenomicConfig,
app: AppType,
assets: PhenomicAssets,
phenomicFetch: PhenomicFetch,
location: string
}) => Promise<Array<{ path: string, contents: string }>>;
|}) => Promise<Array<{| path: string, contents: string |}>>;

export type PhenomicPluginRenderDevServerType = ({
export type PhenomicPluginRenderDevServerType = ({|
config: PhenomicConfig,
assets: PhenomicAssets,
location: string
}) => string;
|}) => string;

export type PhenomicPluginRenderHTMLType = ({
export type PhenomicPluginRenderHTMLType = ({|
config: PhenomicConfig,
props: PhenomicIntermediateHtmlPropsType
}) => string;
|}) => string;

export type PhenomicPlugin = {
export type PhenomicPlugin = {|
name: string,
// transformer
supportedFileTypes?: Array<string>,
transform?: ({
transform?: ({|
config?: PhenomicConfig,
file: PhenomicContentFile,
contents: Buffer
}) => Promise<PhenomicTransformResult> | PhenomicTransformResult,
|}) => Promise<PhenomicTransformResult> | PhenomicTransformResult,
// api
define?: (api: express$Application, db: PhenomicDB) => mixed,
// collector
collect?: (db: PhenomicDB, fileName: string, parsed: Object) => Array<mixed>,
// bunder
buildForPrerendering?: Function,
buildForPrerendering?: PhenomicConfig => PhenomicAppType,
build?: PhenomicConfig => PhenomicAssets,
// renderer
getRoutes?: Function,
resolveURLs?: (routes, fetch: PhenomicFetch) => Array<string>,
getRoutes?: PhenomicAppType => void,
resolveURLs?: (routes: any, fetch: PhenomicFetch) => Array<string>,
renderStatic?: PhenomicPluginRenderStaticType,
renderDevServer?: PhenomicPluginRenderDevServerType,
// common
addDevServerMiddlewares?: (
config: PhenomicConfig
) => Array<express$Middleware | Promise<express$Middleware>>
};
addDevServerMiddlewares?: PhenomicConfig => Array<
express$Middleware | Promise<express$Middleware>
>,
beforeBuild?: PhenomicConfig => void
|};

export type PhenomicPlugins = Array<PhenomicPlugin>;

export type PhenomicPresets = Array<PhenomicPreset>;

export type PhenomicExtensions = PhenomicPreset;

export type PhenomicConfig = {
export type PhenomicConfig = {|
path: string,
content: string,
outdir: string,
port: number,
bundleName: string,
plugins: Array<PhenomicPlugin>
};
|};

export type PhenomicQueryConfig = {
export type PhenomicQueryConfig = {|
path?: string,
id?: string,
after?: string,
by?: string,
value?: string,
order?: string,
limit?: number
};
|};

export type PhenomicRoute = {
export type PhenomicRoute = {|
path: string,
params?: { [key: string]: any },
component: {
getQueries?: (props: { params: { [key: string]: any } }) => {
[key: string]: PhenomicQueryConfig
}
}
};
|};

export type PhenomicAssets = { [key: string]: string };

Expand Down
19 changes: 16 additions & 3 deletions packages/api-client/src/query.js
@@ -1,5 +1,17 @@
const debug = require("debug")("phenomic:api-client");

function removeUndefined<T: {}>(obj: T): T {
const newObj = {};
// $FlowFixMe stfu
Object.keys(obj).forEach(key => {
if (typeof obj[key] !== undefined) {
newObj[key] = obj[key];
}
});
// $FlowFixMe stfu
return newObj;
}

function query(config: PhenomicQueryConfig): PhenomicQueryConfig {
debug("query", config);

Expand All @@ -10,14 +22,15 @@ function query(config: PhenomicQueryConfig): PhenomicQueryConfig {
id: config.id
};
}
return {

return removeUndefined({
path: config.path,
by: config.by || "default",
value: config.by && config.value ? config.value : "1",
order: config.order ? config.order : "desc",
limit: config.limit ? parseInt(config.limit, 10) : undefined,
...(config.after !== undefined ? { after: config.after } : null)
};
after: config.after
});
}

export default query;
22 changes: 16 additions & 6 deletions packages/core/src/commands/build.js
Expand Up @@ -116,7 +116,7 @@ async function prerenderFileAndDependencies({
)
);
}
async function build(config) {
async function build(config: PhenomicConfig) {
console.log("⚡️ Hey! Let's get on with it");
debug("cleaning dist");
rimraf.sync("dist");
Expand All @@ -131,18 +131,26 @@ async function build(config) {
debug("server ready");
try {
const bundlers = config.plugins.filter(p => p.buildForPrerendering);
const bundler = bundlers[0]; // Build webpack
const bundler = bundlers[0];
await Promise.all(
config.plugins
.filter(plugin => plugin.beforeBuild)
.map(plugin => plugin.beforeBuild(config))
config.plugins.map(
plugin => plugin.beforeBuild && plugin.beforeBuild(config)
)
);
if (!bundler || !bundler.build) {
throw new Error("a bundler is required (plugin implementing `build`)");
}
const assets = await bundler.build(config);
debug("assets", assets);
console.log(
"📦 Webpack client build done " + (Date.now() - lastStamp) + "ms"
);
lastStamp = Date.now();
if (!bundler || !bundler.buildForPrerendering) {
throw new Error(
"a bundler is required (plugin implementing `buildForPrerendering`)"
);
}
const app = await bundler.buildForPrerendering(config);
debug("app", app);
console.log(
Expand All @@ -156,7 +164,9 @@ async function build(config) {
const renderers: PhenomicPlugins = config.plugins.filter(p => p.getRoutes);
const renderer = renderers[0];
if (!renderer || !renderer.getRoutes) {
throw new Error("a renderer is required (plugin implementing getRoutes)");
throw new Error(
"a renderer is required (plugin implementing `getRoutes`)"
);
}
const getRoutes = renderer.getRoutes;
const urlsResolvers: PhenomicPlugins = config.plugins.filter(
Expand Down
24 changes: 13 additions & 11 deletions packages/core/src/configuration/flattenConfiguration.js
@@ -1,3 +1,5 @@
import defaultConfig from "../defaultConfig.js";

const debug = require("debug")("phenomic:core:configuration");

const normalizePlugin = (plugin: PhenomicPlugin) => {
Expand Down Expand Up @@ -46,7 +48,7 @@ const normalizeModule = (module: any) => {
return module;
};

function flattenPresets(config?: PhenomicInputPlugins = {}): PhenomicPlugins {
function flattenPresets(config: PhenomicInputPlugins): PhenomicPlugins {
debug("flattenPresets", config);
const plugins = [
...(config.presets || [])
Expand All @@ -58,18 +60,18 @@ function flattenPresets(config?: PhenomicInputPlugins = {}): PhenomicPlugins {
return plugins;
}

function flattenConfiguration(
config: PhenomicInputConfig = {}
): PhenomicConfig {
// @todo ad validation here?
function flattenConfiguration(config: PhenomicInputConfig): PhenomicConfig {
debug("flattenConfiguration", config);
return {
path: config.path || "",
content: config.content || "",
outdir: config.outdir || "",
port: config.port || 8080,
bundleName: config.bundleName || "",
plugins: flattenPresets(config)
path: config.path || defaultConfig.path,
content: config.content || defaultConfig.content,
outdir: config.outdir || defaultConfig.outdir,
port: config.port || defaultConfig.port,
bundleName: config.bundleName || defaultConfig.bundleName,
plugins: flattenPresets({
plugins: config.plugins || [],
presets: config.presets || []
})
};
}

Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/defaultConfig.js
@@ -1,8 +1,9 @@
export default {
const defaultConfig: PhenomicConfig = {
path: process.cwd(),
content: "content",
outdir: "dist",
port: 3333,
bundleName: "phenomic.main",
plugins: []
};
export default defaultConfig;
10 changes: 4 additions & 6 deletions packages/core/src/index.js
@@ -1,6 +1,5 @@
import cosmiconfig from "cosmiconfig";

import defaultConfig from "./defaultConfig.js";
import flattenConfiguration from "./configuration/flattenConfiguration.js";
import start from "./commands/start.js";
import build from "./commands/build.js";
Expand All @@ -12,7 +11,7 @@ const shittyCatch = error => {
};

function normalizeConfiguration(
config: PhenomicInputConfig = {}
config?: PhenomicInputConfig
): Promise<PhenomicConfig> {
const configExplorer = cosmiconfig("phenomic", { cache: false });
return configExplorer
Expand All @@ -26,21 +25,20 @@ function normalizeConfiguration(
);
}
return flattenConfiguration({
...defaultConfig,
...result.config,
...config
...(config || {})
});
})
.catch(shittyCatch);
}

export default {
start(config: PhenomicInputConfig = {}) {
start(config?: PhenomicInputConfig) {
normalizeConfiguration(config)
.then(start)
.catch(shittyCatch);
},
build(config: PhenomicInputConfig = {}) {
build(config?: PhenomicInputConfig) {
normalizeConfiguration(config)
.then(build)
.catch(shittyCatch);
Expand Down

0 comments on commit 9a91f4e

Please sign in to comment.