├── .npmrc ├── examples ├── README.md ├── available.png ├── display-plotly.ipynb └── markdown-regression-testing.ipynb ├── static ├── logo.png ├── favicon.ico ├── favicon-16x16.png ├── favicon-32x32.png ├── mstile-150x150.png ├── apple-touch-icon.png ├── android-chrome-192x192.png ├── nprogress.css └── commuter.css ├── CURRENT.md ├── flow-typed └── npm │ ├── fs-extra_vx.x.x.js │ ├── flow-bin_v0.x.x.js │ ├── isomorphic-fetch_v2.x.x.js │ ├── font-awesome_vx.x.x.js │ ├── jsonfile_vx.x.x.js │ ├── nbschema_vx.x.x.js │ ├── babel-preset-flow_vx.x.x.js │ ├── s3-proxy_vx.x.x.js │ ├── nprogress_vx.x.x.js │ ├── prop-types_v15.x.x.js │ ├── body-parser_v1.x.x.js │ ├── supertest_vx.x.x.js │ ├── concurrently_vx.x.x.js │ ├── log_vx.x.x.js │ ├── d3-dsv_vx.x.x.js │ ├── lint-staged_vx.x.x.js │ ├── prettier_vx.x.x.js │ ├── husky_vx.x.x.js │ ├── node-fetch_v1.x.x.js │ ├── styled-jsx_vx.x.x.js │ ├── babel-cli_vx.x.x.js │ ├── bodybuilder_vx.x.x.js │ ├── morgan_v1.x.x.js │ ├── @nteract │ └── commuter-frontend_vx.x.x.js │ ├── flow-typed_vx.x.x.js │ ├── lerna_vx.x.x.js │ ├── winston_vx.x.x.js │ ├── express_v4.x.x.js │ └── chai_v4.x.x.js ├── bin.js ├── transforms ├── index.js └── PlotlyTransform.js ├── .flowconfig ├── backend ├── content-providers │ ├── s3 │ │ ├── index.js │ │ ├── files.js │ │ ├── contents.js │ │ └── s3.js │ └── local │ │ ├── index.js │ │ ├── files.js │ │ ├── contents.js │ │ └── fs.js ├── index.js ├── resources │ ├── nteract.metadata.schema.json │ ├── generateMapping.js │ └── commuter.es.mapping.json ├── discovery-providers │ ├── none │ │ └── index.js │ └── elasticsearch │ │ ├── index.js │ │ └── elasticSearch.js ├── routes │ ├── api │ │ └── index.js │ └── index.js ├── server.js └── config.js ├── components ├── body.js ├── contents │ ├── csv.js │ ├── json.js │ ├── html.js │ ├── directory-listing.js │ ├── index.js │ └── zeppelin.js ├── header.js └── browse-header.js ├── shims └── ajax.js ├── frontend.js ├── theme.js ├── __tests__ ├── routesUtil-spec.js └── s3test.js ├── OPS.md ├── pages ├── index.js ├── _document.js ├── view.js └── discover.js ├── next.config.js ├── .npmignore ├── ROADMAP.md ├── .gitignore ├── babel.config.js ├── LICENSE ├── CODE_OF_CONDUCT.md ├── package.json └── README.md /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock = false 2 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | These are examples, yay. 2 | 3 | ![](available.png) 4 | -------------------------------------------------------------------------------- /static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix-Skunkworks/commuter/master/static/logo.png -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix-Skunkworks/commuter/master/static/favicon.ico -------------------------------------------------------------------------------- /CURRENT.md: -------------------------------------------------------------------------------- 1 | Currently: 2 | 3 | * Ensure commuter is built and up to date 4 | * (Re) configure CI 5 | 6 | -------------------------------------------------------------------------------- /flow-typed/npm/fs-extra_vx.x.x.js: -------------------------------------------------------------------------------- 1 | declare module 'fs-extra' { 2 | declare module.exports: any; 3 | } 4 | -------------------------------------------------------------------------------- /bin.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | process.env.NODE_ENV = "production"; 4 | 5 | require("./lib/index.js"); 6 | -------------------------------------------------------------------------------- /examples/available.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix-Skunkworks/commuter/master/examples/available.png -------------------------------------------------------------------------------- /static/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix-Skunkworks/commuter/master/static/favicon-16x16.png -------------------------------------------------------------------------------- /static/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix-Skunkworks/commuter/master/static/favicon-32x32.png -------------------------------------------------------------------------------- /static/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix-Skunkworks/commuter/master/static/mstile-150x150.png -------------------------------------------------------------------------------- /static/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix-Skunkworks/commuter/master/static/apple-touch-icon.png -------------------------------------------------------------------------------- /static/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix-Skunkworks/commuter/master/static/android-chrome-192x192.png -------------------------------------------------------------------------------- /transforms/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import PlotlyTransform, { PlotlyNullTransform } from "./PlotlyTransform"; 3 | 4 | export { PlotlyNullTransform, PlotlyTransform }; 5 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | .*/node_modules/.* 3 | 4 | [include] 5 | 6 | [libs] 7 | flow-typed 8 | 9 | [options] 10 | suppress_comment= \\(.\\|\n\\)*\\$FlowFixMe 11 | -------------------------------------------------------------------------------- /flow-typed/npm/flow-bin_v0.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 6a5610678d4b01e13bbfbbc62bdaf583 2 | // flow-typed version: 3817bc6980/flow-bin_v0.x.x/flow_>=v0.25.x 3 | 4 | declare module "flow-bin" { 5 | declare module.exports: string; 6 | } 7 | -------------------------------------------------------------------------------- /backend/content-providers/s3/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import { createRouter as createContentsRouter } from "./contents"; 4 | import { createRouter as createFilesRouter } from "./files"; 5 | 6 | export { createContentsRouter, createFilesRouter }; 7 | -------------------------------------------------------------------------------- /backend/content-providers/local/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import { createRouter as createContentsRouter } from "./contents"; 4 | import { createRouter as createFilesRouter } from "./files"; 5 | 6 | export { createContentsRouter, createFilesRouter }; 7 | -------------------------------------------------------------------------------- /components/body.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import * as React from "react"; 3 | 4 | type BodyProps = { 5 | children?: React.Node 6 | }; 7 | 8 | const Body = (props: BodyProps) => { 9 | return props.children; 10 | }; 11 | 12 | export default Body; 13 | -------------------------------------------------------------------------------- /shims/ajax.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import { ajax } from "rxjs/ajax"; 4 | 5 | export function getJSON(url: string) { 6 | return ajax({ 7 | url, 8 | responseType: "json", 9 | createXHR: function() { 10 | return new XMLHttpRequest(); 11 | } 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /flow-typed/npm/isomorphic-fetch_v2.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 47370d221401bec823c43c3598266e26 2 | // flow-typed version: ec28077c25/isomorphic-fetch_v2.x.x/flow_>=v0.25.x 3 | 4 | 5 | declare module 'isomorphic-fetch' { 6 | declare module.exports: (input: string | Request | URL, init?: RequestOptions) => Promise; 7 | } 8 | -------------------------------------------------------------------------------- /backend/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | const log = require("log"); 3 | 4 | const createServer = require("./server"); 5 | 6 | createServer() 7 | .then(server => { 8 | const port = server.address().port; 9 | console.log(log); 10 | log.info("Commuter server listening on port " + port); 11 | }) 12 | .catch((e: Error) => { 13 | console.error(e); 14 | console.error(e.stack); 15 | process.exit(-10); 16 | }); 17 | -------------------------------------------------------------------------------- /backend/resources/nteract.metadata.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "nteract": { 3 | "properties": { 4 | "tags": { 5 | "type": "string", 6 | "description": "Meta data about the notebook" 7 | }, 8 | "description": { 9 | "description": "Short description about the notebook", 10 | "type": "string" 11 | }, 12 | "image": { 13 | "description": "Display image url", 14 | "type": "string" 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /frontend.js: -------------------------------------------------------------------------------- 1 | // Note: this module must remain compatible with the ECMAScript version of the 2 | // Server as it does _not_ get transpiled 3 | const next = require("next"); 4 | 5 | const dev = process.env.NODE_ENV !== "production" && !process.env.NOW; 6 | 7 | function createNextApp() { 8 | const app = next({ dev, dir: __dirname }); 9 | const handle = app.getRequestHandler(); 10 | 11 | return { 12 | app, 13 | handle 14 | }; 15 | } 16 | 17 | module.exports = { 18 | createNextApp 19 | }; 20 | -------------------------------------------------------------------------------- /backend/discovery-providers/none/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import type { $Request, $Response } from "express"; 4 | 5 | const express = require("express"); 6 | 7 | // eslint-disable-next-line no-unused-vars 8 | function createDiscoveryRouter(options?: Object): express.Router { 9 | const router = express.Router(); 10 | router.get("/*", (req: $Request, res: $Response) => { 11 | res.json({ 12 | results: [] 13 | }); 14 | }); 15 | return router; 16 | } 17 | 18 | export { createDiscoveryRouter }; 19 | -------------------------------------------------------------------------------- /components/contents/csv.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import * as React from "react"; 3 | 4 | // const d3 = Object.assign({}, require("d3-dsv")); 5 | // import DataTransform from "@nteract/transform-dataresource"; 6 | 7 | export default class CSVView extends React.Component<*> { 8 | shouldComponentUpdate() { 9 | return false; 10 | } 11 | 12 | render() { 13 | // const data = d3.csvParse(this.props.entry.content); 14 | return
No support for csv at this time
; 15 | // return ; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /flow-typed/npm/font-awesome_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: c647c7a73da0b343c9531f328e472a83 2 | // flow-typed version: <>/font-awesome_v^4.7.0/flow_v0.54.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'font-awesome' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'font-awesome' { 17 | declare module.exports: any; 18 | } 19 | -------------------------------------------------------------------------------- /theme.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | // styled-jsx can only take constants inside of template literals 4 | 5 | /* 6 | * Blue theme 7 | */ 8 | export const blueTheme = { 9 | active: "#324767", 10 | background: "#edf1f7", 11 | primary: "#a2b6d7", 12 | outline: "#c8d4e7", 13 | link: "#0366d6", 14 | bright: "#039be5" 15 | }; 16 | 17 | /* 18 | * Gray theme 19 | */ 20 | export const grayTheme = { 21 | active: "#111", 22 | background: "#eee", 23 | primary: "#ccc", 24 | outline: "#ddd" 25 | }; 26 | 27 | export const theme = blueTheme; 28 | 29 | // export const theme = grayTheme; 30 | -------------------------------------------------------------------------------- /backend/content-providers/s3/files.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | const express = require("express"), 4 | s3Proxy = require("s3-proxy"); 5 | 6 | // TODO: Flow type config 7 | export function createRouter(config: Object): express.Router { 8 | const router = express.Router(); 9 | 10 | router.get( 11 | "/*", 12 | s3Proxy({ 13 | bucket: config.s3.params.Bucket, 14 | prefix: config.s3BasePrefix, 15 | accessKeyId: config.s3.accessKeyId, 16 | secretAccessKey: config.s3.secretAccessKey, 17 | overrideCacheControl: "max-age=100000" 18 | }) 19 | ); 20 | return router; 21 | } 22 | -------------------------------------------------------------------------------- /__tests__/routesUtil-spec.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | const isDir = require("./../backend/content-providers/s3/contents").isDir; 3 | 4 | describe("Routes util tests", () => { 5 | test("returns isDir true", () => { 6 | expect(isDir("path/to/dir/")).toBe(true); 7 | }); 8 | 9 | test("returns isDir false", () => { 10 | expect(isDir("path/to/dir/file.text")).toBe(false); 11 | }); 12 | 13 | test("treats empty path as dir path", () => { 14 | expect(isDir("")).toBe(true); 15 | //s3 defaults to root 16 | expect(isDir(null)).toBe(true); 17 | expect(isDir(undefined)).toBe(true); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /OPS.md: -------------------------------------------------------------------------------- 1 | ## ElasticSearch Operations Manual 2 | 3 | ### Create a New Index 4 | 5 | ``` 6 | curl -XPOST http:///commuter -d @src/resources/commuter.es.mapping.json 7 | ``` 8 | 9 | ### Update Alias 10 | 11 | ``` 12 | curl -XPOST http:///_aliases -d ' 13 | { 14 | "actions": [ 15 | { "remove": { 16 | "alias": "commuter", 17 | "index": "" 18 | }}, 19 | { "add": { 20 | "alias": "commuter", 21 | "index": "" 22 | }} 23 | ] 24 | }' 25 | ``` 26 | 27 | ### Delete Index 28 | 29 | ``` 30 | curl -XDELETE http:///commuter 31 | ``` 32 | -------------------------------------------------------------------------------- /pages/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import * as React from "react"; 3 | import Link from "next/link"; 4 | 5 | class IndexPage extends React.Component<*> { 6 | static async getInitialProps(ctx: Object) { 7 | if (ctx.res) { 8 | // Server side, do a redirect using the HTTP response object 9 | ctx.res.writeHead(302, { Location: "/view/" }); 10 | ctx.res.end(); 11 | } else { 12 | // Client side redirect 13 | document.location.pathname = "/view/"; 14 | } 15 | return {}; 16 | } 17 | 18 | render() { 19 | return ( 20 | 21 | Redirecting to{" "} 22 | 23 | /view 24 | 25 | 26 | ); 27 | } 28 | } 29 | 30 | export default IndexPage; 31 | -------------------------------------------------------------------------------- /backend/discovery-providers/elasticsearch/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import type { $Request, $Response } from "express"; 4 | 5 | const express = require("express"); 6 | 7 | const { createDiscoveryService } = require("./elasticSearch"); 8 | 9 | function createDiscoveryRouter(discoveryOptions: Object) { 10 | const discoveryService = createDiscoveryService( 11 | discoveryOptions.elasticsearch 12 | ); 13 | 14 | const router = express.Router(); 15 | router.get("/*", (req: $Request, res: $Response) => { 16 | const successCb = data => res.json(data); 17 | 18 | const errorCb = err => 19 | res.status(err.statusCode).json({ message: err.message }); 20 | 21 | discoveryService.list(successCb, errorCb); 22 | }); 23 | return router; 24 | } 25 | 26 | export { createDiscoveryRouter }; 27 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require("webpack"); 2 | 3 | function webpackConfig(_config, options) { 4 | const config = _config; 5 | 6 | // No external CSS should get side-loaded by js 7 | // I'm looking at you vega-tooltip 8 | config.plugins.push(new webpack.IgnorePlugin(/\.(css|less)$/)); 9 | 10 | if (options.isServer) { 11 | config.plugins.push( 12 | new webpack.ProvidePlugin({ 13 | XMLHttpRequest: ["xmlhttprequest", "XMLHttpRequest"], 14 | "root.XMLHttpRequest": ["xmlhttprequest", "XMLHttpRequest"], 15 | "global.XMLHttpRequest": ["xmlhttprequest", "XMLHttpRequest"], 16 | "window.XMLHttpRequest": ["xmlhttprequest", "XMLHttpRequest"] 17 | }) 18 | ); 19 | } else { 20 | } 21 | 22 | return config; 23 | } 24 | 25 | module.exports = { 26 | webpack: webpackConfig 27 | }; 28 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | *.pid.lock 11 | 12 | # Directory for instrumented libs generated by jscoverage/JSCover 13 | lib-cov 14 | 15 | # Coverage directory used by tools like istanbul 16 | coverage 17 | 18 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 19 | .grunt 20 | 21 | # node-waf configuration 22 | .lock-wscript 23 | 24 | # Compiled binary addons (http://nodejs.org/api/addons.html) 25 | build/Release 26 | 27 | # Dependency directories 28 | node_modules 29 | jspm_packages 30 | 31 | # Buid directories 32 | dist 33 | 34 | # Optional npm cache directory 35 | .npm 36 | 37 | # Optional eslint cache 38 | .eslintcache 39 | 40 | # Optional REPL history 41 | .node_repl_history 42 | 43 | # Output of 'npm pack' 44 | *.tgz 45 | 46 | # Yarn Integrity file 47 | .yarn-integrity 48 | -------------------------------------------------------------------------------- /components/contents/json.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import * as React from "react"; 3 | import { JSONTransform } from "@nteract/transforms"; 4 | import Immutable from "immutable"; 5 | 6 | import ZeppelinView from "./zeppelin"; 7 | 8 | export default (props: *) => { 9 | const content = JSON.parse(props.entry.content); 10 | try { 11 | // Zeppelin notebooks are called note.json, we'll go ahead and render them 12 | if (props.entry.name === "note.json") { 13 | return ; 14 | } 15 | 16 | return ( 17 | 23 | ); 24 | } catch (e) { 25 | return ( 26 | 27 |

Failed to parse Zeppelin Notebook

28 |
{e.toString()}
29 | {props.entry.content} 30 |
31 | ); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /ROADMAP.md: -------------------------------------------------------------------------------- 1 | ## ROADMAP 2 | 3 | This roadmap is organized into stages of development, leading towards a backend for (mostly) real-time collaboration. 4 | 5 | ### Stage I 6 | 7 | - [x] List and Load notebooks from S3 8 | - [x] Bucket, etc. loaded from configuration (e.g. `COMMUTER_BUCKET=xyz`) 9 | - [x] Roles or Amazon environment variables automatically picked up (via `aws-sdk`) 10 | - [x] Tree view of notebook content 11 | - [x] Render page using notebook-preview 12 | 13 | ### Stage II 14 | 15 | - [x] Save notebooks back to S3 16 | - [x] Delete notebooks 17 | 18 | ### Stage III 19 | 20 | - [x] Render page using nteract/nteract components 21 | - [ ] Configurable base path for commuter app 22 | - [ ] Start outlining an authentication and permissions strategy 23 | 24 | ### Stage IV 25 | 26 | - [ ] Create server side in-memory model of notebook and transient models, push to clients 27 | - [ ] Provide/use kernels from configured source (e.g. tmpnb.org, jupyterhub, or your private setup) 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | .DS_Store 6 | 7 | # Runtime data 8 | pids 9 | *.pid 10 | *.seed 11 | *.pid.lock 12 | 13 | # Directory for instrumented libs generated by jscoverage/JSCover 14 | lib-cov 15 | 16 | # Coverage directory used by tools like istanbul 17 | coverage 18 | 19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 20 | .grunt 21 | 22 | # node-waf configuration 23 | .lock-wscript 24 | 25 | # Compiled binary addons (http://nodejs.org/api/addons.html) 26 | build/Release 27 | 28 | # Dependency directories 29 | node_modules 30 | jspm_packages 31 | 32 | # Buid directories 33 | dist 34 | build 35 | lib 36 | 37 | # Optional npm cache directory 38 | .npm 39 | 40 | # Optional eslint cache 41 | .eslintcache 42 | 43 | # Optional REPL history 44 | .node_repl_history 45 | 46 | # Output of 'npm pack' 47 | *.tgz 48 | 49 | # Yarn Integrity file 50 | .yarn-integrity 51 | 52 | # xmark files 53 | .xmark.* 54 | 55 | .next 56 | -------------------------------------------------------------------------------- /backend/discovery-providers/elasticsearch/elasticSearch.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | const bodybuilder = require("bodybuilder"), 4 | elasticsearch = require("elasticsearch"); 5 | 6 | export type ESDiscoveryBackendOptions = { 7 | host: string, 8 | log: string 9 | }; 10 | 11 | function createDiscoveryService(options: ESDiscoveryBackendOptions) { 12 | const client = new elasticsearch.Client(options); 13 | 14 | const list = (cb: Function, error: Function) => 15 | client 16 | .search({ 17 | index: "commuter", 18 | type: "notebooks", 19 | body: bodybuilder() 20 | .sort("last_modified", "desc") 21 | .size(1000) 22 | .build() 23 | }) 24 | .then( 25 | resp => { 26 | cb({ results: resp.hits.hits.map(hit => hit._source) }); 27 | }, 28 | err => { 29 | error(err.message); 30 | } 31 | ); 32 | return { 33 | list 34 | }; 35 | } 36 | 37 | export { createDiscoveryService }; 38 | -------------------------------------------------------------------------------- /flow-typed/npm/jsonfile_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 046dd8bb055c254b64b17b116bbe46f5 2 | // flow-typed version: <>/jsonfile_v^3.0.1/flow_v0.54.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'jsonfile' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'jsonfile' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | 26 | 27 | // Filename aliases 28 | declare module 'jsonfile/index' { 29 | declare module.exports: $Exports<'jsonfile'>; 30 | } 31 | declare module 'jsonfile/index.js' { 32 | declare module.exports: $Exports<'jsonfile'>; 33 | } 34 | -------------------------------------------------------------------------------- /flow-typed/npm/nbschema_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 45b4a0d3cc67f1b53d87f27a7d1d491b 2 | // flow-typed version: <>/nbschema_v^0.1.0/flow_v0.54.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'nbschema' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'nbschema' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | 26 | 27 | // Filename aliases 28 | declare module 'nbschema/index' { 29 | declare module.exports: $Exports<'nbschema'>; 30 | } 31 | declare module 'nbschema/index.js' { 32 | declare module.exports: $Exports<'nbschema'>; 33 | } 34 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | if (api) { 3 | const env = api.env(); // eslint-disable-line no-unused-vars 4 | } 5 | 6 | const config = { 7 | presets: ["@babel/preset-env", "@babel/preset-react"], 8 | plugins: [ 9 | "styled-jsx/babel", 10 | "@babel/plugin-syntax-dynamic-import", 11 | "@babel/plugin-proposal-object-rest-spread", 12 | "@babel/plugin-proposal-class-properties", 13 | "@babel/plugin-proposal-export-default-from", 14 | [ 15 | "@babel/plugin-transform-runtime", 16 | { 17 | corejs: 2 18 | } 19 | ] 20 | ], 21 | overrides: [ 22 | { 23 | test: ["**/*.js", "**/*.jsx"], 24 | presets: ["@babel/preset-flow"], 25 | plugins: ["@babel/plugin-transform-flow-strip-types"] 26 | }, 27 | { 28 | test: ["**/*.ts", "**/*.tsx"], 29 | presets: ["@babel/preset-typescript"] 30 | } 31 | ] 32 | }; 33 | 34 | return config; 35 | }; 36 | -------------------------------------------------------------------------------- /components/contents/html.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import * as React from "react"; 3 | 4 | export default class HTMLView extends React.Component<*> { 5 | ifr: ?HTMLIFrameElement; 6 | 7 | shouldComponentUpdate() { 8 | return false; 9 | } 10 | 11 | render() { 12 | return ( 13 |
20 |