├── .travis.yml
├── docs
├── npm-start.png
└── create-cycle-app.png
├── .gitignore
├── lerna.json
├── packages
├── cycle-scripts
│ ├── template
│ │ ├── public
│ │ │ ├── favicon.ico
│ │ │ ├── favicon.png
│ │ │ └── index.html
│ │ ├── custom-typings.d.ts
│ │ ├── src
│ │ │ ├── javascript
│ │ │ │ ├── app.test.js
│ │ │ │ ├── index.js
│ │ │ │ └── app.jsx
│ │ │ └── typescript
│ │ │ │ ├── app.test.ts
│ │ │ │ ├── app.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── interfaces.ts
│ │ ├── config
│ │ │ ├── javascript.js
│ │ │ └── typescript.js
│ │ ├── tsconfig.json
│ │ └── gitignore
│ ├── scripts
│ │ ├── init.js
│ │ ├── test.js
│ │ ├── init
│ │ │ ├── questions.js
│ │ │ ├── success.js
│ │ │ └── setup.js
│ │ ├── eject.js
│ │ ├── start.js
│ │ ├── build.js
│ │ └── utils
│ │ │ └── createWebpackCompiler.js
│ ├── configs
│ │ ├── dependencies.js
│ │ ├── javascript
│ │ │ ├── webpack.config.prod.js
│ │ │ └── webpack.config.dev.js
│ │ ├── typescript
│ │ │ ├── webpack.config.prod.js
│ │ │ └── webpack.config.dev.js
│ │ └── webpackDevServer.config.js
│ ├── index.js
│ ├── LICENSE
│ ├── README.md
│ └── package.json
└── create-cycle-app
│ ├── README.md
│ ├── src
│ ├── shouldUseYarn.js
│ ├── isSafeToCreateApp.js
│ ├── getPackageName.js
│ ├── createAppDir.js
│ ├── createPackageJson.js
│ ├── initQuestions.js
│ ├── createApp.js
│ └── installScripts.js
│ ├── test
│ ├── unit
│ │ ├── initQuestions.spec.js
│ │ ├── getPackageName.spec.js
│ │ ├── createAppDir.spec.js
│ │ ├── createPackageJson.spec.js
│ │ ├── isSafeToCreateApp.spec.js
│ │ └── installScripts.spec.js
│ └── integration
│ │ ├── __snapshots__
│ │ └── createCycleApp.spec.js.snap
│ │ └── createCycleApp.spec.js
│ ├── index.js
│ ├── package.json
│ └── CHANGELOG.md
├── .github
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .editorconfig
├── AUTHORS.md
├── bin
└── update-authors.sh
├── CONTRIBUTING.md
├── LICENSE
├── package.json
└── README.md
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 'node'
4 |
--------------------------------------------------------------------------------
/docs/npm-start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyclejs-community/create-cycle-app/HEAD/docs/npm-start.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | *.log
3 |
4 | # Dependency directories
5 | node_modules
6 |
7 | # OS fs specifics
8 | .DS_Store
9 |
--------------------------------------------------------------------------------
/docs/create-cycle-app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyclejs-community/create-cycle-app/HEAD/docs/create-cycle-app.png
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "lerna": "2.0.0-beta.36",
3 | "packages": [
4 | "packages/*"
5 | ],
6 | "version": "independent"
7 | }
8 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/template/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyclejs-community/create-cycle-app/HEAD/packages/cycle-scripts/template/public/favicon.ico
--------------------------------------------------------------------------------
/packages/cycle-scripts/template/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyclejs-community/create-cycle-app/HEAD/packages/cycle-scripts/template/public/favicon.png
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | **Code to reproduce the issue:**
2 |
3 |
4 | **Expected behavior:**
5 |
6 |
7 | **Actual behavior:**
8 |
9 |
10 | **Versions of packages used:**
11 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/README.md:
--------------------------------------------------------------------------------
1 |
2 | # create-cycle-app
3 |
4 | Create [Cycle.js](https://cycle.js.org/) apps with no build configuration.
5 |
6 | [Learn more](https://github.com/cyclejs-community/create-cycle-app).
7 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/template/custom-typings.d.ts:
--------------------------------------------------------------------------------
1 | // tslint:disable-next-line
2 | ///
3 |
4 | declare var Snabbdom: any; //Automaticly imported into every file
5 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/template/src/javascript/app.test.js:
--------------------------------------------------------------------------------
1 | module.exports = replacements => `// import assert from 'assert'
2 |
3 | // describe('App', function () {
4 | // it('should test something', function () {
5 | // // TODO: Add your tests here
6 | // })
7 | // })
8 | `
9 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/template/src/typescript/app.test.ts:
--------------------------------------------------------------------------------
1 | module.exports = replacements => `// import assert from 'assert'
2 |
3 | // describe('App', function () {
4 | // it('should test something', function () {
5 | // // TODO: Add your tests here
6 | // })
7 | // })
8 | `
9 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/src/shouldUseYarn.js:
--------------------------------------------------------------------------------
1 | const execSync = require('child_process').execSync
2 |
3 | module.exports = function shouldUseYarn () {
4 | try {
5 | execSync('npm --version', { stdio: 'ignore' })
6 | return false
7 | } catch (e) {
8 | return true
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
5 |
6 | - [ ] I ran `npm test` for the package I'm modifying
7 | - [ ] I used `npm run commit` instead of `git commit`
8 | - [ ] I have rebased my branch onto master before merging
9 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/template/src/javascript/index.js:
--------------------------------------------------------------------------------
1 | module.exports = replacements => `import {run} from '${replacements.run}'
2 | import {makeDOMDriver} from '@cycle/dom'
3 | import {App} from './app'
4 |
5 | const main = App
6 |
7 | const drivers = {
8 | DOM: makeDOMDriver('#root')
9 | }
10 |
11 | run(main, drivers)
12 | `
13 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/template/src/javascript/app.jsx:
--------------------------------------------------------------------------------
1 | module.exports = replacements => `${replacements.import}
2 |
3 | export function App (sources) {
4 | const vtree$ = ${replacements.stream}.of(
5 |
My Awesome Cycle.js app
6 | )
7 | const sinks = {
8 | DOM: vtree$
9 | }
10 | return sinks
11 | }
12 | `
13 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/template/src/typescript/app.tsx:
--------------------------------------------------------------------------------
1 | module.exports = replacements => `${replacements.import}
2 | import {Sources, Sinks} from './interfaces'
3 |
4 | export function App(sources : Sources) : Sinks {
5 | const vtree$ = ${replacements.stream}.of(
6 | My Awesome Cycle.js app
7 | )
8 |
9 | return {
10 | DOM: vtree$
11 | }
12 | }
13 | `
14 |
--------------------------------------------------------------------------------
/AUTHORS.md:
--------------------------------------------------------------------------------
1 | # Authors
2 |
3 | #### Ordered by first contribution.
4 |
5 | - Geovani de Souza (geovanisouza92@gmail.com)
6 | - Nick Johnstone (ncwjohnstone@gmail.com)
7 | - Nick Balestra (nick@balestra.ch)
8 | - Cesar Figueroa (cesar.figueroa@me.com)
9 | - Justin Zimmerman (jzimmerman@redventures.com)
10 | - Steve Lee (steve@opendirective.com)
11 |
12 | #### Generated by bin/update-authors.sh.
13 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/template/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Cycle App
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/template/src/typescript/index.ts:
--------------------------------------------------------------------------------
1 | module.exports = replacements => `import {run} from '${replacements.run}'
2 | import {makeDOMDriver} from '@cycle/dom'
3 | import {Component} from './interfaces'
4 |
5 | import {App} from './app'
6 |
7 | const main : Component = App
8 |
9 | const drivers = {
10 | DOM: makeDOMDriver('#root')
11 | }
12 |
13 | run(main, drivers)
14 | `
15 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/scripts/init.js:
--------------------------------------------------------------------------------
1 | const questions = require('./init/questions')
2 | const setup = require('./init/setup')
3 |
4 | module.exports = function init (appPath, appName, options) {
5 | if (options.answers) {
6 | return setup(appPath, appName, options)
7 | }
8 | return questions(answers => {
9 | options.answers = answers
10 | setup(appPath, appName, options)
11 | })
12 | }
13 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/template/src/typescript/interfaces.ts:
--------------------------------------------------------------------------------
1 | module.exports = replacements => `${replacements.import}
2 | ${replacements.typeImport}
3 | import {DOMSource, VNode} from '@cycle/dom'
4 |
5 | export type Sources = {
6 | DOM : DOMSource;
7 | }
8 |
9 | export type Sinks = {
10 | DOM : ${replacements.streamType};
11 | }
12 |
13 | export type Component = (s : Sources) => Sinks;
14 | `
15 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/template/config/javascript.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | xstream: {
3 | run: '@cycle/run',
4 | import: 'import xs from \'xstream\'',
5 | stream: 'xs'
6 | },
7 | rxjs: {
8 | run: '@cycle/rxjs-run',
9 | import: 'import Rx from \'rxjs/Rx\'',
10 | stream: 'Rx.Observable'
11 | },
12 | most: {
13 | run: '@cycle/most-run',
14 | import: 'import * as most from \'most\'',
15 | stream: 'most'
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/template/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "module": "ES6",
5 | "moduleResolution": "node",
6 | "target": "ES5",
7 | "sourceMap": true,
8 | "jsx": "react",
9 | "jsxFactory": "Snabbdom.createElement",
10 | "noImplicitReturns": true,
11 | "strict": true,
12 | "allowJs": true,
13 | "lib": ["ES6", "ES5", "DOM"]
14 | },
15 | "exclude": ["node_modules"]
16 | }
17 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/src/isSafeToCreateApp.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const fs = require('fs')
4 |
5 | module.exports = function isSafeToCreateApp (appFolder) {
6 | const whitelist = [
7 | '.DS_Store',
8 | 'Thumbs.db',
9 | '.git',
10 | '.gitignore',
11 | '.idea',
12 | 'README.md',
13 | 'LICENSE'
14 | ]
15 | return fs.readdirSync(appFolder)
16 | .every((file) => {
17 | return whitelist.indexOf(file) >= 0
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/src/getPackageName.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const path = require('path')
4 |
5 | const packageRegex = /(@[\w-]+\/)?[\w-]+/
6 |
7 | module.exports = function getPackageName (installPackage) {
8 | if (/.tgz$/.test(installPackage)) {
9 | return installPackage.match(/^(.*)-.*tgz$/)[1]
10 | } else if (/^\.\/|\//.test(installPackage)) {
11 | return require(path.resolve(installPackage, 'package.json')).name
12 | } else {
13 | return installPackage.match(packageRegex)[0]
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/scripts/test.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const path = require('path')
4 | const spawn = require('cross-spawn')
5 | const chalk = require('chalk')
6 |
7 | const mocha = path.resolve(process.cwd(), 'node_modules', '.bin', 'mocha')
8 |
9 | const args = [
10 | '--colors',
11 | '--require',
12 | 'babel-register',
13 | !process.env.CI && (console.log(chalk.green.bold('Enabling watch mode')) || '--watch'),
14 | 'src/**/*.test.js'
15 | ].filter(Boolean)
16 |
17 | spawn(mocha, args, {stdio: 'inherit'})
18 |
--------------------------------------------------------------------------------
/bin/update-authors.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Update AUTHORS.md based on git history.
3 |
4 | git log --reverse --format='%aN (%aE)' | perl -we '
5 | BEGIN {
6 | %seen = (), @authors = ();
7 | }
8 | while (<>) {
9 | next if $seen{$_};
10 | next if /(support\@greenkeeper.io)/;
11 | $seen{$_} = push @authors, "- ", $_;
12 | }
13 | END {
14 | print "# Authors\n\n";
15 | print "#### Ordered by first contribution.\n\n";
16 | print @authors, "\n";
17 | print "#### Generated by bin/update-authors.sh.\n";
18 | }
19 | ' > AUTHORS.md
20 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/configs/dependencies.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | basics: [
3 | '@cycle/dom@18.3.0'
4 | ],
5 | language: {
6 | javascript: [],
7 | typescript: [
8 | 'typescript@2.5.3',
9 | 'awesome-typescript-loader@3.2.3'
10 | ]
11 | },
12 | streamLib: {
13 | xstream: [
14 | '@cycle/run@3.3.0',
15 | 'xstream@11.0.0'
16 | ],
17 | rxjs: [
18 | '@cycle/rxjs-run@7.1.0',
19 | 'rxjs@5.4.3'
20 | ],
21 | most: [
22 | '@cycle/most-run@7.2.0',
23 | 'most@1.7.2'
24 | ]
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/src/createAppDir.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const chalk = require('chalk')
4 | const console = require('console')
5 | const fs = require('fs')
6 |
7 | const isSafeToCreateApp = require('./isSafeToCreateApp')
8 |
9 | module.exports = function createProjectIn (appPath) {
10 | if (!fs.existsSync(appPath)) {
11 | fs.mkdirSync(appPath)
12 | return
13 | }
14 |
15 | if (isSafeToCreateApp(appPath)) {
16 | return
17 | } else {
18 | console.log(chalk.red(`The directory \`${appPath}\` contains file(s) that could conflict. Aborting.`))
19 | process.exit(1)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/index.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | 'use strict'
3 |
4 | const spawn = require('cross-spawn')
5 | const script = process.argv[2]
6 | const args = process.argv.slice(3)
7 |
8 | switch (script) {
9 | case 'start':
10 | case 'test':
11 | case 'build':
12 | case 'eject':
13 | const result = spawn.sync(
14 | 'node',
15 | [require.resolve('./scripts/' + script)].concat(args),
16 | {stdio: 'inherit'}
17 | )
18 | process.exit(result.status)
19 | break
20 | default:
21 | console.log('Unknown script "' + script + '".')
22 | console.log('Perhaps you need to upgrade cycle-scripts?')
23 | break
24 | }
25 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | First of all, thank you for contributing. It’s appreciated.
2 |
3 | # To submit a pull request
4 |
5 | 1. Open a GitHub issue before doing significant amount of work.
6 | 2. Clone the repo. If it was already cloned, then git pull to get the latest from master.
7 | 4. Run `npm install`.
8 | 5. Write code.
9 | 6. Run `npm test` to lint and test. Don’t commit before fixing all errors and warnings.
10 | 7. Commit using `npm run commit` and follow the CLI instructions.
11 | 8. Make a pull request.
12 |
13 | # To release new versions
14 |
15 | 1. Check that you have npm publishing rights before anything else.
16 | 2. Run `npm run check-release`.
17 | 3. Run `npm run release`.
18 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/test/unit/initQuestions.spec.js:
--------------------------------------------------------------------------------
1 | const initQuestions = require('../../src/initQuestions')
2 | jest.mock('inquirer')
3 | const inquirer = require('inquirer')
4 |
5 | describe('initQuedstion module', () => {
6 | describe('when calling it', () => {
7 | test('should prompt for question', () => {
8 | const callback = jest.fn()
9 | const answer = {language: 'javascript', streamLib: 'xstream'}
10 | inquirer.prompt.mockReturnValue({
11 | then: jest.fn(answers => callback(answer))
12 | })
13 | initQuestions(callback)
14 | expect(callback).toBeCalledWith(answer)
15 | expect(inquirer.prompt).toBeCalled()
16 | })
17 | })
18 | })
19 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/test/integration/__snapshots__/createCycleApp.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`create-cycle-app when invoked with the the correct arguments it generate a correct package.json file 1`] = `
4 | "{
5 | "name": "MYCYCLEAPP",
6 | "version": "0.1.0",
7 | "private": true,
8 | "devDependencies": {
9 | "cycle-scripts": "1.0.3"
10 | },
11 | "dependencies": {},
12 | "scripts": {
13 | "start": "cycle-scripts start",
14 | "test": "cycle-scripts test",
15 | "build": "cycle-scripts build",
16 | "eject": "cycle-scripts eject"
17 | },
18 | "babel": {
19 | "presets": [
20 | "es2015"
21 | ]
22 | }
23 | }"
24 | `;
25 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/template/config/typescript.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | xstream: {
3 | run: '@cycle/run',
4 | import: 'import xs from \'xstream\'',
5 | typeImport: 'import {Stream} from \'xstream\'',
6 | stream: 'xs',
7 | streamType: 'Stream'
8 | },
9 | rxjs: {
10 | run: '@cycle/rxjs-run',
11 | import: 'import * as Rx from \'rxjs\'',
12 | typeImport: 'import {Observable} from \'rxjs\'',
13 | stream: 'Rx.Observable',
14 | streamType: 'Observable'
15 | },
16 | most: {
17 | run: '@cycle/most-run',
18 | import: 'import * as most from \'most\'',
19 | typeImport: 'import {Stream} from \'most\'',
20 | stream: 'most',
21 | streamType: 'Stream'
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/src/createPackageJson.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const chalk = require('chalk')
4 | const console = require('console')
5 | const fs = require('fs')
6 | const path = require('path')
7 |
8 | module.exports = function createPackageJson (appPath, appName) {
9 | // Prepare package.json
10 | const content = {
11 | name: appName,
12 | version: '0.1.0',
13 | private: true
14 | }
15 | const packageJsonContent = JSON.stringify(content, null, 2)
16 |
17 | // Write package.json in the app folder
18 | console.log(chalk.green(`Creating a new Cycle.js app in ${appPath}.`))
19 | console.log()
20 | fs.writeFileSync(
21 | path.join(appPath, 'package.json'),
22 | packageJsonContent
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | ISC License
2 |
3 | Copyright (c) 2016-present, Geovani Souza
4 |
5 | Permission to use, copy, modify, and/or distribute this software for any
6 | purpose with or without fee is hereby granted, provided that the above
7 | copyright notice and this permission notice appear in all copies.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/test/unit/getPackageName.spec.js:
--------------------------------------------------------------------------------
1 | const getPackageName = require('../../src/getPackageName')
2 |
3 | describe('getPackageName module', () => {
4 | test('should return the unaltered package name if alrady given', () => {
5 | expect(getPackageName('cycle-scripts')).toBe('cycle-scripts')
6 | expect(getPackageName('are-we-there-yet-1.1.2.tgz')).toBe('are-we-there-yet')
7 | expect(getPackageName('cycle-scripts@next')).toBe('cycle-scripts')
8 | })
9 | test('should return the correct package name if inside a .tgz', () => {
10 | expect(getPackageName('are-we-there-yet-1.1.2.tgz')).toBe('are-we-there-yet')
11 | })
12 | test('should return the correct package name if uses a @/ naming', () => {
13 | expect(getPackageName('cycle-scripts@next')).toBe('cycle-scripts')
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/test/unit/createAppDir.spec.js:
--------------------------------------------------------------------------------
1 | jest.mock('fs')
2 | const fs = require('fs')
3 | jest.mock('../../src/isSafeToCreateApp')
4 | const isSafeToCreateApp = require('../../src/isSafeToCreateApp')
5 |
6 | const createAppDir = require('../../src/createAppDir')
7 |
8 | describe('createAppDir module', () => {
9 | afterEach(() => {
10 | fs.existsSync.mockClear()
11 | isSafeToCreateApp.mockClear()
12 | })
13 |
14 | describe('when calling it and the directory does not exist', () => {
15 | test('should create it', (done) => {
16 | fs.existsSync.mockReturnValue(false)
17 | createAppDir('./appFolder')
18 | expect(fs.existsSync).toBeCalledWith('./appFolder')
19 | expect(fs.mkdirSync).toBeCalledWith('./appFolder')
20 | expect(isSafeToCreateApp).not.toBeCalled()
21 | done()
22 | })
23 | })
24 | })
25 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/test/unit/createPackageJson.spec.js:
--------------------------------------------------------------------------------
1 | const createPackageJson = require('../../src/createPackageJson')
2 | jest.mock('fs')
3 | const fs = require('fs')
4 | jest.mock('console')
5 | const console = require('console')
6 | const chalk = require('chalk')
7 |
8 | describe('createPackageJson module', () => {
9 | describe('when calling it', () => {
10 | test('should correctly prepare package.json and write it to disk', () => {
11 | createPackageJson('testPath', 'testName')
12 |
13 | expect(fs.writeFileSync.mock.calls[0][0]).toBe('testPath/package.json')
14 | expect(fs.writeFileSync.mock.calls[0][1]).toBe(JSON.stringify({
15 | name: 'testName',
16 | version: '0.1.0',
17 | private: true
18 | }, null, 2))
19 | expect(console.log).toHaveBeenCalledTimes(2)
20 | expect(console.log).toHaveBeenCalledWith(chalk.green('Creating a new Cycle.js app in testPath.'))
21 | })
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/template/gitignore:
--------------------------------------------------------------------------------
1 | ### https://raw.github.com/github/gitignore/abad92dac5a4306f72242dae3bca6e277bce3615/Node.gitignore
2 |
3 | # Logs
4 | logs
5 | *.log
6 | npm-debug.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # node-waf configuration
27 | .lock-wscript
28 |
29 | # Compiled binary addons (http://nodejs.org/api/addons.html)
30 | build/Release
31 |
32 | # Dependency directories
33 | node_modules
34 | jspm_packages
35 |
36 | # Optional npm cache directory
37 | .npm
38 |
39 | # Optional eslint cache
40 | .eslintcache
41 |
42 | # Optional REPL history
43 | .node_repl_history
44 |
45 | # Output of 'npm pack'
46 | *.tgz
47 |
48 | build
49 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/test/unit/isSafeToCreateApp.spec.js:
--------------------------------------------------------------------------------
1 | jest.mock('fs')
2 | const fs = require('fs')
3 | const isSafeToCreateApp = require('../../src/isSafeToCreateApp')
4 | const whiteList = [
5 | '.DS_Store',
6 | 'Thumbs.db',
7 | '.git',
8 | '.gitignore',
9 | '.idea',
10 | 'README.md',
11 | 'LICENSE'
12 | ]
13 |
14 | describe('isSafeToCreateApp module', () => {
15 | describe('when calling it with a directory containing files not white-listened', () => {
16 | test('should return false', () => {
17 | fs.readdirSync.mockImplementation(() => whiteList.concat('index.js'))
18 | const isSafe = isSafeToCreateApp('./someFolder')
19 | expect(isSafe).toBe(false)
20 | })
21 | })
22 |
23 | describe('when calling it with a directory containing only white-listened files', () => {
24 | test('should return true', () => {
25 | fs.readdirSync.mockImplementation(() => whiteList)
26 | const isSafe = isSafeToCreateApp('./someFolder')
27 | expect(isSafe).toBe(true)
28 | })
29 | })
30 | })
31 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/scripts/init/questions.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const inquirer = require('inquirer')
4 |
5 | const questions = [
6 | {
7 | type: 'list',
8 | name: 'language',
9 | default: 0,
10 | choices: [
11 | {
12 | name: 'JavaScript',
13 | value: 'javascript'
14 | },
15 | {
16 | name: 'TypeScript',
17 | value: 'typescript'
18 | }
19 | ],
20 | message: 'Which language do you want to use to write your cycle app?'
21 | },
22 | {
23 | type: 'list',
24 | name: 'streamLib',
25 | default: 0,
26 | choices: [
27 | {
28 | name: 'XStream, tailored for Cycle.js',
29 | value: 'xstream'
30 | },
31 | {
32 | name: 'Most.js, a blazing fast stream library',
33 | value: 'most'
34 | },
35 | {
36 | name: 'RxJS',
37 | value: 'rxjs'
38 | }
39 | ],
40 | message: 'Which reactive stream library do you want to use?'
41 | }
42 | ]
43 |
44 | module.exports = callback => inquirer.prompt(questions).then(callback)
45 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/src/initQuestions.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const inquirer = require('inquirer')
4 |
5 | const initQuestions = [
6 | {
7 | type: 'list',
8 | name: 'language',
9 | default: 0,
10 | choices: [
11 | {
12 | name: 'JavaScript',
13 | value: 'javascript'
14 | },
15 | {
16 | name: 'TypeScript',
17 | value: 'typescript'
18 | }
19 | ],
20 | message: 'Which language do you want to use to write your cycle app?'
21 | },
22 | {
23 | type: 'list',
24 | name: 'streamLib',
25 | default: 0,
26 | choices: [
27 | {
28 | name: 'XStream, tailored for Cycle.js',
29 | value: 'xstream'
30 | },
31 | {
32 | name: 'Most.js, a blazing fast stream library',
33 | value: 'most'
34 | },
35 | {
36 | name: 'RxJS',
37 | value: 'rxjs'
38 | }
39 | ],
40 | message: 'Which reactive stream library do you want to use?'
41 | }
42 | ]
43 |
44 | module.exports = cb => {
45 | inquirer.prompt(initQuestions).then(cb)
46 | }
47 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2017 Nick Balestra
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/README.md:
--------------------------------------------------------------------------------
1 | # cycle-scripts
2 |
3 | [Cycle-app](https://github.com/cyclejs-community/create-cycle-app) core flavor.
4 |
5 | ## Language
6 |
7 | ES6 ( Babel ) configured with:
8 | * [ES2015 preset](https://babeljs.io/docs/plugins/preset-es2015/)
9 |
10 | ## Bundler
11 |
12 | Webpack configured with
13 | * [Webpack dev server](https://webpack.github.io/docs/webpack-dev-server.html)
14 | * [Hot Module Replacement](https://webpack.github.io/docs/hot-module-replacement-with-webpack.html)
15 |
16 | ## Scripts
17 |
18 | - `npm start`: Start development server listening on port 8000
19 | - `npm test`: Run the default test tool
20 | - `npm run build`: Generate a production-ready build content, on the `build` folder (this folder is *gitignored*)
21 | - `npm run eject`: Copy flavor's dependencies and configurations to the project folder, update `package.json` and remove the dependency on the flavored `cycle-scripts`. This is irreversible.
22 |
23 |
24 | ## Boilerplate:
25 |
26 | The flavor generate the following file structure:
27 |
28 | ```
29 | my-awesome-cycle-app/
30 | ├── node_modules/
31 | ├── public/
32 | │ ├── favicon.ico
33 | │ └── index.html
34 | ├── src/
35 | │ ├── app.js
36 | │ ├── app.test.js
37 | │ └── index.js
38 | └── package.json
39 | ```
40 |
41 | ### Config files
42 | * .babelrc (Added on the root after running the eject script)
43 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "create-cycle-app",
3 | "version": "3.0.0",
4 | "description": "Create Cycle.js apps with zero configuration.",
5 | "private": true,
6 | "scripts": {
7 | "update-authors": "./bin/update-authors.sh",
8 | "precommit": "standard && npm run test",
9 | "postinstall": "lerna bootstrap",
10 | "test": "lerna run test",
11 | "publish": "lerna publish",
12 | "updated": "lerna updated"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+https://github.com/cyclejs-community/create-cycle-app.git"
17 | },
18 | "author": "Geovani Souza ",
19 | "contributors": [
20 | {
21 | "name": "Geovani Souza",
22 | "email": "geovanisouza92@gmail.com"
23 | },
24 | {
25 | "name": "Nick Balestra",
26 | "email": "nick@balestra.ch"
27 | }
28 | ],
29 | "license": "ISC",
30 | "bugs": {
31 | "url": "https://github.com/cyclejs-community/create-cycle-app/issues"
32 | },
33 | "homepage": "https://github.com/cyclejs-community/create-cycle-app#readme",
34 | "standard": {
35 | "globals": [
36 | "describe",
37 | "test",
38 | "it",
39 | "expect",
40 | "jest",
41 | "beforeEach",
42 | "afterEach"
43 | ]
44 | },
45 | "devDependencies": {
46 | "husky": "^0.13.1",
47 | "lerna": "2.0.0-beta.36",
48 | "standard": "^8.3.0"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/scripts/init/success.js:
--------------------------------------------------------------------------------
1 | const chalk = require('chalk')
2 |
3 | module.exports = (appName, appPath) => {
4 | console.log()
5 | console.log(`Success! Created ${appName} at ${appPath}`)
6 | console.log('Inside that directory, you can run several commands:')
7 | console.log()
8 | console.log(chalk.cyan(' npm start'))
9 | console.log(' Starts the development server')
10 | console.log()
11 | console.log(chalk.cyan(' npm test'))
12 | console.log(' Start the test runner')
13 | console.log()
14 | console.log(chalk.cyan(' npm run build'))
15 | console.log(' Bundles the app into static files for production')
16 | console.log()
17 | console.log(chalk.cyan(' npm run eject'))
18 | console.log(' Removes this tool and copies build dependencies, configuration files')
19 | console.log(' and scripts into the app directory. If you do this, you can\'t go back!')
20 | console.log()
21 | console.log('We suggest that you begin by typing:')
22 | console.log()
23 | console.log(chalk.cyan(` cd ${appName}`))
24 | console.log(chalk.cyan(' npm start'))
25 | console.log()
26 | console.log('If you have questions, issues or feedback about Cycle.js and create-cycle-app, please, join us on the Gitter:')
27 | console.log()
28 | console.log(chalk.cyan(' https://gitter.im/cyclejs/cyclejs'))
29 | console.log()
30 | console.log('Happy cycling!')
31 | console.log()
32 | }
33 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/index.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | 'use strict'
3 |
4 | const path = require('path')
5 | const chalk = require('chalk')
6 | const argv = require('minimist')(process.argv.slice(2))
7 | const createApp = require('./src/createApp')
8 | const VERSION = require(path.resolve(__dirname, 'package.json')).version
9 |
10 | const validCommands = {
11 | 'verbose': true,
12 | 'flavor': true,
13 | 'yarn': true,
14 | 'pnpm': true,
15 | 'forceprompt': true
16 | }
17 |
18 | // Command line prelude (version and usage)
19 | const commands = argv._
20 | if (commands.length === 0) {
21 | if (argv.version) {
22 | console.log(chalk.green(`create-cycle-app version: ${VERSION}`))
23 | process.exit()
24 | }
25 | console.error(chalk.red('Usage: create-cycle-app [--flavor] [--verbose] [--yarn | --pnpm]'))
26 | process.exit(1)
27 | }
28 |
29 | Object.keys(argv)
30 | .filter(cmd => cmd !== '_')
31 | .every(cmd => {
32 | if (!validCommands[cmd]) {
33 | console.error(chalk.red(`Invalid command: ${cmd}`))
34 | process.exit(1)
35 | return false
36 | }
37 | return true
38 | })
39 |
40 | const flavor = argv.flavor || 'core'
41 | const verbose = argv.verbose || false
42 | const cli = argv.yarn ? 'yarn' : (argv.pnpm ? 'pnpm' : 'npm')
43 | const forceprompt = argv.forceprompt || false
44 | const name = commands[0]
45 |
46 | // Parse the command line options and run the setup
47 | createApp(name, verbose, flavor, cli, forceprompt)
48 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cycle-scripts",
3 | "version": "2.1.1",
4 | "description": "create-cycle-app core flavor",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Maybe later\""
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/cyclejs-community/create-cycle-app.git"
12 | },
13 | "author": "Nick Balestra ",
14 | "contributors": [
15 | {
16 | "name": "Geovani Souza",
17 | "email": "geovanisouza92@gmail.com"
18 | },
19 | {
20 | "name": "Nick Balestra",
21 | "email": "nick@balestra.ch"
22 | }
23 | ],
24 | "license": "MIT",
25 | "bugs": {
26 | "url": "https://github.com/cyclejs-community/create-cycle-app/issues"
27 | },
28 | "homepage": "https://github.com/cyclejs-community/create-cycle-app#readme",
29 | "bin": {
30 | "cycle-scripts": "./index.js"
31 | },
32 | "dependencies": {
33 | "babel-core": "^6.26.0",
34 | "babel-loader": "^7.1.2",
35 | "babel-plugin-transform-object-rest-spread": "^6.26.0",
36 | "babel-plugin-transform-react-jsx": "^6.24.1",
37 | "babel-preset-env": "^1.6.0",
38 | "chalk": "^2.1.0",
39 | "cross-spawn": "^5.1.0",
40 | "fs-extra": "^4.0.2",
41 | "html-webpack-plugin": "^2.30.1",
42 | "inquirer": "^3.3.0",
43 | "jest": "^21.2.1",
44 | "react-dev-utils": "^4.1.0",
45 | "snabbdom-pragma": "^2.5.0",
46 | "webpack": "^3.6.0",
47 | "webpack-dev-server": "^2.9.1"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "create-cycle-app",
3 | "version": "5.0.0",
4 | "description": "Create Cycle.js with no build configuration.",
5 | "scripts": {
6 | "test": "exit 0 || jest"
7 | },
8 | "keywords": [],
9 | "author": "Geovani Souza ",
10 | "contributors": [
11 | {
12 | "name": "Geovani Souza",
13 | "email": "geovanisouza92@gmail.com"
14 | },
15 | {
16 | "name": "Nick Balestra",
17 | "email": "nick@balestra.ch"
18 | }
19 | ],
20 | "license": "ISC",
21 | "bin": {
22 | "create-cycle-app": "./index.js"
23 | },
24 | "dependencies": {
25 | "@cycle/dom": "^18.3.0",
26 | "@cycle/http": "^14.4.0",
27 | "@cycle/isolate": "^3.1.0",
28 | "@cycle/run": "^3.3.0",
29 | "@cycle/time": "^0.10.1",
30 | "chalk": "^2.1.0",
31 | "cross-spawn": "^5.1.0",
32 | "cycle-onionify": "^4.0.0",
33 | "inquirer": "^3.3.0",
34 | "minimist": "^1.2.0",
35 | "xstream": "^11.0.0"
36 | },
37 | "devDependencies": {
38 | "cycle-restart": "^0.2.2",
39 | "cyclejs-test-helpers": "^1.4.0",
40 | "fs-extra": "^4.0.2",
41 | "html-looks-like": "^1.0.3",
42 | "jest": "^21.2.1",
43 | "jsverify": "^0.8.3",
44 | "snabbdom-to-html": "^3.3.0"
45 | },
46 | "repository": {
47 | "type": "git",
48 | "url": "git+https://github.com/cyclejs-community/create-cycle-app.git"
49 | },
50 | "bugs": {
51 | "url": "https://github.com/cyclejs-community/create-cycle-app/issues"
52 | },
53 | "homepage": "https://github.com/cyclejs-community/create-cycle-app#readme"
54 | }
55 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/src/createApp.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const path = require('path')
4 |
5 | const createAppDir = require('./createAppDir')
6 | const initQuestions = require('./initQuestions')
7 | const installScripts = require('./installScripts')
8 | const createPackageJson = require('./createPackageJson')
9 | const shouldUseYarn = require('./shouldUseYarn')
10 |
11 | module.exports = function createApp (name, verbose, flavor, cli, forceprompt) {
12 | // The path where the cycle app will be created
13 | const appPath = path.resolve(name)
14 | // The name of the cycle app to create
15 | const appName = path.basename(appPath)
16 | // Which CLi to use (yarn or npm)
17 | if (shouldUseYarn()) {
18 | cli = 'yarn'
19 | }
20 | // console.log(cli)
21 | // If no --flavor is passed (flavor === 'core')
22 | // We prompt for language and stream library
23 | // We set the flavor to be 'cycle-scripts'
24 | if (flavor === 'core') {
25 | flavor = 'cycle-scripts-one-fits-all@>=6.0.0'
26 | }
27 | if (forceprompt) {
28 | if (flavor === 'core') {
29 | flavor = 'cycle-scripts@>=2.0.0'
30 | }
31 | initQuestions(answers => {
32 | createAppDir(appPath)
33 | createPackageJson(appPath, appName)
34 | installScripts(appPath, appName, { flavor, verbose, answers, cli })
35 | })
36 | // If a --flavor is passed we don't prompt the user
37 | // We delegate every task to the flavor's init() method itself.
38 | } else {
39 | createAppDir(appPath)
40 | createPackageJson(appPath, appName)
41 | installScripts(appPath, appName, { flavor, verbose, answers: false, cli })
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/test/integration/createCycleApp.spec.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs-extra')
2 | const path = require('path')
3 | const appName = path.resolve(__dirname, 'MYCYCLEAPP')
4 | const spawn = require('cross-spawn')
5 |
6 | describe('create-cycle-app', () => {
7 | describe('when invoked with the wrong arguments', () => {
8 | test('should throw an error', () => {
9 | expect(
10 | spawn.sync('node', [
11 | path.resolve(__dirname, '../../index.js'),
12 | appName,
13 | '--flavour',
14 | 'cycle-scripts@1.0.3',
15 | '--noyarn'
16 | ])
17 | ).toThrowError()
18 | })
19 |
20 | test('should throw an error', () => {
21 | expect(
22 | spawn.sync('node', [
23 | path.resolve(__dirname, '../../index.js'),
24 | appName,
25 | '--verbos'
26 | ])
27 | ).toThrowError()
28 | })
29 | })
30 |
31 | describe('when invoked with the the correct arguments', () => {
32 | let dir
33 |
34 | beforeEach((done) => {
35 | spawn.sync('node', [
36 | path.resolve(__dirname, '../../index.js'),
37 | appName,
38 | '--flavor',
39 | 'cycle-scripts@1.0.3'
40 | ])
41 | dir = fs.readdirSync(appName)
42 | done()
43 | })
44 |
45 | afterEach(() => {
46 | fs.removeSync(appName)
47 | })
48 |
49 | test('it generate the correct folder structure and install dependencies', () => {
50 | expect(dir).toEqual(expect.arrayContaining([
51 | '.gitignore',
52 | 'node_modules',
53 | 'package.json',
54 | 'public',
55 | 'src'
56 | ]))
57 | })
58 |
59 | test('it generate a correct package.json file', () => {
60 | expect(fs.readFileSync(path.join(appName, 'package.json'), 'UTF8')).toMatchSnapshot()
61 | })
62 | })
63 | })
64 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/src/installScripts.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const chalk = require('chalk')
4 | const spawn = require('cross-spawn')
5 | const console = require('console')
6 | const path = require('path')
7 |
8 | const getPackageName = require('./getPackageName')
9 |
10 | module.exports = function installScripts (appFolder, appName, options) {
11 | const verbose = options.verbose
12 | const flavor = options.flavor
13 | const cli = options.cli
14 |
15 | // Check if the the the flavor to be used is local
16 | const local = /^\.\/|^\//.test(flavor)
17 | // Get the right name of the flavor package
18 | const packageName = getPackageName(flavor)
19 | // Install dependencies
20 | const npmArgs = [
21 | 'install',
22 | verbose && '--verbose',
23 | '--save-dev',
24 | '--save-exact',
25 | flavor
26 | ].filter(a => a)
27 |
28 | const args = {
29 | npm: npmArgs,
30 | pnpm: npmArgs,
31 | yarn: [
32 | 'add',
33 | '--exact',
34 | '--dev',
35 | verbose && '--verbose',
36 | local ? 'file:' + flavor : flavor
37 | ].filter(a => a)
38 | }
39 |
40 | // Trigger npm installation
41 | console.log(chalk.green('Installing packages. This might take a couple minutes.'))
42 | console.log(chalk.green(`Installing ${packageName} from ${(local ? 'local' : cli)} ...`))
43 | console.log()
44 |
45 | const proc = spawn(cli, args[cli], {stdio: 'inherit', cwd: appFolder})
46 | proc.on('error', (e) => console.log(e))
47 | proc.on('close', function (code) {
48 | if (code !== 0) {
49 | console.error(chalk.red(`${cli} \`${args[cli].join(' ')}\` failed`))
50 | return
51 | }
52 |
53 | const initScriptPath = path.resolve(
54 | appFolder,
55 | 'node_modules',
56 | packageName,
57 | 'scripts',
58 | 'init.js'
59 | )
60 | const init = require(initScriptPath)
61 |
62 | // Execute the flavor's specific initialization
63 | init(appFolder, appName, options)
64 | })
65 | }
66 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/scripts/eject.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const fs = require('fs-extra')
4 | const path = require('path')
5 | const chalk = require('chalk')
6 | const inquirer = require('inquirer')
7 |
8 | const appPath = path.join(process.cwd())
9 | const appScriptsPath = path.join(process.cwd(), 'scripts')
10 | const flavorPackageJson = require(path.join(__dirname, '..', 'package.json'))
11 | const appPackageJson = require(path.join(appPath, 'package.json'))
12 | const language = appPackageJson.cca.language
13 |
14 | const ejectConfirmation = {
15 | type: 'confirm',
16 | name: 'doEject',
17 | default: false,
18 | message: 'Are you sure you want to eject? This action is permanent.'
19 | }
20 |
21 | // Ask the user for confirmation before ejecting.
22 | inquirer.prompt([ejectConfirmation]).then(answers => {
23 | // Abort in case of negative answer (default)
24 | if (!answers.doEject) {
25 | console.log(chalk.cyan('Eject aborted!'))
26 | return process.exit(0)
27 | }
28 |
29 | // STEP 1 - Prepare package.json
30 | // Declaring new scripts
31 | const scripts = {
32 | start: 'node scripts/start.js',
33 | test: 'node scripts/test.js',
34 | build: 'node scripts/build.js'
35 | }
36 | // Remove flavor from devpendencies
37 | delete appPackageJson.devDependencies[flavorPackageJson.name]
38 | // Remove cca settings
39 | delete appPackageJson.cca
40 | // Flavor's dependencies -> application devDependency.
41 | // We merge flavor's dependencies with application's devDepependencies
42 | const devDependencies = Object.assign(
43 | {},
44 | appPackageJson.devDependencies,
45 | flavorPackageJson.dependencies
46 | )
47 | // New package.json content
48 | const packageJsonContent = Object.assign(
49 | {},
50 | appPackageJson,
51 | {
52 | scripts,
53 | devDependencies
54 | }
55 | )
56 | // Overide application's package.json with the new content
57 | fs.writeFileSync(
58 | path.join(appPath, 'package.json'),
59 | JSON.stringify(packageJsonContent, null, 2)
60 | )
61 |
62 | // STEP 2 - Copy scripts
63 | function copyScript (script) {
64 | fs.copySync(path.join(__dirname, script), path.join(appScriptsPath, script))
65 | }
66 | // Make sure appScriptsPath exists
67 | fs.ensureDirSync(appScriptsPath)
68 | // Copy over start, test and build scripts
69 | copyScript('start.js')
70 | copyScript('test.js')
71 | copyScript('build.js')
72 |
73 | // STEP 3 - Copy utils
74 | fs.copySync(path.join(__dirname, 'utils'), path.join(appScriptsPath, 'utils'))
75 |
76 | // STEP 4 - Copy configs
77 | fs.copySync(path.join(__dirname, '../', 'configs', language), path.join(appPath, 'configs'))
78 | fs.copySync(path.join(__dirname, '../', 'configs', 'webpackDevServer.config.js'), path.join(appPath, 'configs', 'webpackDevServer.config.js'))
79 |
80 | // TODO sucess message
81 | })
82 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/test/unit/installScripts.spec.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | jest.mock('cross-spawn')
3 | const spawn = require('cross-spawn')
4 | spawn.mockImplementation(() => ({ on: jest.fn() }))
5 | jest.mock('../../src/getPackageName')
6 | const getPackageName = require('../../src/getPackageName')
7 | jest.mock('console')
8 | const consoleMock = require('console')
9 | const installScripts = require('../../src/installScripts')
10 | // installScripts(appFolder, appName, { flavor, verbose, answers: false })
11 | describe('installScripts module', () => {
12 | test('should be a function with arity 3', () => {
13 | expect(typeof installScripts).toBe('function')
14 | expect(installScripts.length).toBe(3)
15 | })
16 |
17 | describe('when invoked with a flavor published on npm', () => {
18 | getPackageName.mockImplementation(name => name)
19 | installScripts('./', 'appName', { flavor: 'cycle-scripts', cli: 'npm' })
20 |
21 | test('should call getPackageName with the name of the npm module', () => {
22 | expect(getPackageName).toBeCalledWith('cycle-scripts')
23 | })
24 |
25 | test('should call spawn with the correct arguments', () => {
26 | expect(spawn).toBeCalledWith(
27 | 'npm',
28 | [
29 | 'install',
30 | '--save-dev',
31 | '--save-exact',
32 | 'cycle-scripts'
33 | ],
34 | {'cwd': './', 'stdio': 'inherit'}
35 | )
36 | })
37 |
38 | test('should console log the correct information', () => {
39 | expect(consoleMock.log.mock.calls[0][0]).toContain(
40 | 'Installing packages. This might take a couple minutes.',
41 | )
42 | expect(consoleMock.log.mock.calls[1][0]).toContain(
43 | 'Installing cycle-scripts from npm ...',
44 | )
45 | expect(consoleMock.log.mock.calls[2][0]).toBe()
46 | })
47 | })
48 |
49 | describe('when invoked with a local flavor', () => {
50 | getPackageName.mockImplementation(name => path.basename(name))
51 | installScripts('./', 'appName', { flavor: './cycle-scripts', cli: 'npm' })
52 |
53 | test('should console log the correct information', () => {
54 | expect(consoleMock.log.mock.calls[4][0]).toContain(
55 | 'Installing cycle-scripts from local',
56 | )
57 | })
58 |
59 | test('should call spawn with the correct arguments', () => {
60 | expect(spawn.mock.calls[1][1][3]).toContain('./cycle-scripts')
61 | })
62 | })
63 |
64 | describe('when invoked with a verbose flag', () => {
65 | getPackageName.mockImplementation(name => name)
66 | installScripts('./', 'appName', { flavor: 'cycle-scripts', verbose: true, cli: 'npm' })
67 |
68 | test('should call spawn with the correct arguments', () => {
69 | expect(spawn.mock.calls[2]).toMatchObject([
70 | 'npm',
71 | [
72 | 'install',
73 | '--verbose',
74 | '--save-dev',
75 | '--save-exact',
76 | 'cycle-scripts'
77 | ],
78 | {'cwd': './', 'stdio': 'inherit'}
79 | ])
80 | })
81 | })
82 | })
83 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/scripts/start.js:
--------------------------------------------------------------------------------
1 | /**
2 | * BSD License
3 | * For create-react-app software
4 | *
5 | * Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
6 | * Redistribution and use in source and binary forms, with or without modification,
7 | * are permitted provided that the following conditions are met:
8 | *
9 | * Redistributions of source code must retain the above copyright notice, this
10 | * list of conditions and the following disclaimer.
11 | *
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | * this list of conditions and the following disclaimer in the documentation
14 | * and/or other materials provided with the distribution.
15 | *
16 | * Neither the name Facebook nor the names of its contributors may be used to
17 | * endorse or promote products derived from this software without specific
18 | * prior written permission.
19 | *
20 | *
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
25 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 | */
32 |
33 | 'use strict'
34 |
35 | const WebpackDevServer = require('webpack-dev-server')
36 | const chalk = require('chalk')
37 | const path = require('path')
38 |
39 | const devServerConfig = require('../configs/webpackDevServer.config')
40 | const createWebpackCompiler = require('./utils/createWebpackCompiler')
41 | const openBrowser = require('react-dev-utils/openBrowser')
42 | const notEjected = require(path.join(process.cwd(), 'package.json')).cca
43 |
44 | const config = require(path.join(
45 | '../configs/',
46 | notEjected
47 | ? notEjected.language
48 | : '',
49 | 'webpack.config.dev')
50 | )
51 | process.env.NODE_ENV = 'development'
52 |
53 | const cli = 'npm'
54 | const protocol = devServerConfig.https ? 'https' : 'http'
55 | const host = devServerConfig.host
56 | const port = devServerConfig.port
57 |
58 | function run (port) {
59 | const compiler = createWebpackCompiler(
60 | config,
61 | function onReady (showInstructions) {
62 | if (!showInstructions) {
63 | return
64 | }
65 | console.log()
66 | console.log('The app is running at:')
67 | console.log()
68 | console.log(` ${chalk.cyan(`${protocol}://${host}:${port}/`)}`)
69 | console.log()
70 | console.log('Note that the development build is not optimized.')
71 | console.log(
72 | `To create a production build, use ${chalk.cyan(`${cli} run build`)}.`
73 | )
74 | console.log()
75 | }
76 | )
77 |
78 | const devServer = new WebpackDevServer(compiler, devServerConfig)
79 |
80 | devServer.listen(port, err => {
81 | if (err) {
82 | return console.log(err)
83 | }
84 |
85 | console.log(chalk.cyan('Starting the development server...'))
86 | console.log()
87 |
88 | openBrowser(`${protocol}://${host}:${port}/`)
89 | })
90 | }
91 |
92 | run(port)
93 |
--------------------------------------------------------------------------------
/packages/create-cycle-app/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # v2.0.0 (2016-11-01)
2 | ---
3 |
4 |
5 | ## Breaking Changes
6 |
7 | - feat(create-cycle-app): Allow to select stream library only for core flavors [ea188047](https://github.com/cyclejs-community/create-cycle-app/commits/ea1880479f7e846fe1ff3eef388774ec74c383fb)
8 |
9 |
10 | # v1.0.0 (2016-10-21)
11 | ---
12 |
13 |
14 | ## Breaking Changes
15 |
16 | - feat(create-cycle-app): Removed communityFlavors registry [5031510e](https://github.com/cyclejs-community/create-cycle-app/commits/5031510e01f3774687d11c698d4de9844768ed91)
17 | - feat(create-cycle-app): Discovery now search for flavors on npm [51689bb8](https://github.com/cyclejs-community/create-cycle-app/commits/51689bb890d9c4465bb62891219b3fe6ba50ee78)
18 |
19 | ## Features
20 |
21 | - feat(create-cycle-app): Added dependency [3b09d484](https://github.com/cyclejs-community/create-cycle-app/commits/3b09d484ae04643d6a61287ad9390b305bc7f243)
22 |
23 |
24 | # v0.5.0 (2016-10-19)
25 | ---
26 |
27 |
28 | ## Features
29 |
30 | - feat(create-cycle-app): Change interaction while asking the flavor [829456e4](https://github.com/cyclejs-community/create-cycle-app/commits/829456e4689555cadb73be758f2c33ea1d080601)
31 | - feat(create-cycle-app): Separating flavors list from code [396d9427](https://github.com/cyclejs-community/create-cycle-app/commits/396d94279ee2564593f6561145f6346fcf2e9077)
32 | - feat(create-cycle-app): community vs core flavor discovery mechanism [38314428](https://github.com/cyclejs-community/create-cycle-app/commits/38314428c229b7924080da0d82f20adcdc78f79c)
33 | - feat(create-cycle-app): Added community registry file [747e7a7b](https://github.com/cyclejs-community/create-cycle-app/commits/747e7a7ba9a38554b4747e4176a2528a16d000c9)
34 |
35 |
36 | # v0.4.4 (2016-10-10)
37 | ---
38 |
39 |
40 | ## Bug Fixes
41 |
42 | - fix(create-cycle-app): bin script [1ea5dac1](https://github.com/geovanisouza92/create-cycle-app/commits/1ea5dac1addd67cefce3b0bdcf3c6b6fca5ed0e7)
43 |
44 |
45 | # v0.4.3 (2016-10-09)
46 | ---
47 |
48 |
49 | ## Bug Fixes
50 |
51 | - fix(create-cycle-app): Flavor resolution [0024e346](https://github.com/geovanisouza92/create-cycle-app/commits/0024e346bb43cb95edc491e3626dc983c097f4c5)
52 |
53 |
54 | # v0.4.2 (2016-10-09)
55 | ---
56 |
57 |
58 | ## Bug Fixes
59 |
60 | - fix(create-cycle-app): Missing shebang [ff853d86](https://github.com/geovanisouza92/create-cycle-app/commits/ff853d86a8408c071a884023fe67937a27bcfa42)
61 | - fix(create-cycle-app): Handling various syntaxes of flavor [ce1c0873](https://github.com/geovanisouza92/create-cycle-app/commits/ce1c087305b326ecb774ec45c91cec85c0104ed5)
62 |
63 |
64 | # v0.4.1 (2016-10-09)
65 | ---
66 |
67 |
68 | ## Bug Fixes
69 |
70 | - fix(create-cycle-app): Path resolution for installation from file or folder [1585f2f9](https://github.com/geovanisouza92/create-cycle-app/commits/1585f2f9d9a524d6fb57a82dd3206b568f30dc37)
71 |
72 |
73 | # v0.4.0 (2016-10-09)
74 | ---
75 |
76 |
77 | ## Features
78 |
79 | - feat(create-cycle-app): Select the stream library + some refactoring [c6aca323](https://github.com/geovanisouza92/create-cycle-app/commits/c6aca323e12acefdb868f9504d22b808635f2fe3)
80 |
81 |
82 | # v0.3.0 (2016-10-09)
83 | ---
84 |
85 |
86 | ## Features
87 |
88 | - feat(create-cycle-app): Auto discover flavors [87d3ed59](https://github.com/geovanisouza92/create-cycle-app/commits/87d3ed599bea37164d5aadf912836357c96dfe53)
89 |
90 |
91 | # v0.2.0 (2016-10-08)
92 | ---
93 |
94 |
95 | ## Features
96 |
97 | - feat(create-cycle-app): Adding the proper create-cycle-app command/script [70ffc405](https://github.com/geovanisouza92/create-cycle-app/commits/70ffc405e4a26dffafc6b75d7ff091df94c81bc7)
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/packages/cycle-scripts/configs/javascript/webpack.config.prod.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // Silence webpack2 deprecation warnings
4 | // https://github.com/vuejs/vue-loader/issues/666
5 | process.noDeprecation = true
6 |
7 | const path = require('path')
8 | const HtmlWebpackPlugin = require('html-webpack-plugin')
9 | const webpack = require('webpack')
10 |
11 | // Paths to be used for webpack configuration
12 | const paths = {
13 | appSrc: path.join(process.cwd(), 'src'),
14 | appIndex: path.join(process.cwd(), 'src', 'index.js'),
15 | appBuild: path.join(process.cwd(), 'build'),
16 | public: '/'
17 | }
18 |
19 | module.exports = {
20 | entry: {
21 | main: [
22 | // Your app's code
23 | paths.appIndex
24 | ]
25 | },
26 | output: {
27 | // This is the productin JS bundle containing code from all our entry points.
28 | filename: 'bundle.js',
29 | // The output path where webpack will write the bundle
30 | path: paths.appBuild
31 | },
32 | resolve: {
33 | extensions: ['.js', '.ts', '.tsx', '.jsx', '.json']
34 | },
35 | module: {
36 | rules: [
37 | {
38 | // We use babel-loader to transipile every .js or .jsx file
39 | test: /\.jsx?$/,
40 | loader: 'babel-loader',
41 | // Including over excluding as a whitelist is easier to maintain than a blacklist.
42 | // as per http://stackoverflow.com/questions/31675025/how-to-exclude-nested-node-module-folders-from-a-loader-in-webpack
43 | include: paths.appSrc,
44 | options: {
45 | // This is a feature of `babel-loader` for webpack (not Babel itself).
46 | // It enables caching results in ./node_modules/.cache/babel-loader/
47 | // directory for faster rebuilds.
48 | cacheDirectory: true,
49 | // Instead of relying on a babelrc file to configure babel (or in package.json configs)
50 | // We speficy here which presets to use. In the future this could be moved to it's own
51 | // package as create-react-app does with their 'babel-preset-react-app module.
52 | // As uglify doesn't support es6 code yet, the uglify param will tell babel plugin to transpile to es5
53 | // in order for the output to be uglified.
54 | presets: [
55 | [ 'env', {
56 | 'targets': {
57 | 'browsers': ['last 2 versions'],
58 | uglify: true
59 | }
60 | }]
61 | ],
62 | plugins: [
63 | // https://cycle.js.org/getting-started.html#getting-started-coding-consider-jsx
64 | // This allow us to use JSX to create virtual dom elements instead of Snabbdom helpers like div(), input(), ..
65 | ['transform-react-jsx', { pragma: 'Snabbdom.createElement' }],
66 | // Allow Babel to transform rest properties for object destructuring assignment and spread properties for object literals.
67 | ['transform-object-rest-spread']
68 | ]
69 | }
70 | }
71 | ]
72 | },
73 | plugins: [
74 | // Generates an `index.html` file with the