├── apps
├── .gitkeep
├── blog-api
│ ├── src
│ │ ├── app
│ │ │ └── .gitkeep
│ │ ├── assets
│ │ │ └── .gitkeep
│ │ ├── environments
│ │ │ ├── environment.ts
│ │ │ └── environment.prod.ts
│ │ └── main.ts
│ ├── .eslintrc
│ ├── tsconfig.app.json
│ ├── tsconfig.spec.json
│ ├── tsconfig.json
│ └── jest.config.js
├── blog
│ ├── src
│ │ ├── assets
│ │ │ └── .gitkeep
│ │ ├── favicon.ico
│ │ ├── styles.css
│ │ ├── environments
│ │ │ ├── environment.prod.ts
│ │ │ └── environment.ts
│ │ ├── polyfills.ts
│ │ ├── main.tsx
│ │ ├── index.html
│ │ └── app
│ │ │ ├── star.svg
│ │ │ ├── app.spec.tsx
│ │ │ ├── app.tsx
│ │ │ ├── app.css
│ │ │ └── logo.svg
│ ├── .babelrc
│ ├── proxy.conf.json
│ ├── babel-jest.config.json
│ ├── tsconfig.app.json
│ ├── tsconfig.json
│ ├── jest.config.js
│ ├── tsconfig.spec.json
│ ├── .browserslistrc
│ └── .eslintrc
├── todos-api
│ ├── src
│ │ ├── app
│ │ │ └── .gitkeep
│ │ ├── assets
│ │ │ └── .gitkeep
│ │ ├── environments
│ │ │ ├── environment.ts
│ │ │ └── environment.prod.ts
│ │ └── main.ts
│ ├── .eslintrc
│ ├── tsconfig.app.json
│ ├── tsconfig.spec.json
│ ├── tsconfig.json
│ └── jest.config.js
├── todos
│ ├── src
│ │ ├── assets
│ │ │ └── .gitkeep
│ │ ├── favicon.ico
│ │ ├── environments
│ │ │ ├── environment.prod.ts
│ │ │ └── environment.ts
│ │ ├── styles.css
│ │ ├── polyfills.ts
│ │ ├── main.tsx
│ │ ├── index.html
│ │ └── app
│ │ │ ├── star.svg
│ │ │ ├── app.spec.tsx
│ │ │ ├── app.tsx
│ │ │ ├── app.css
│ │ │ └── logo.svg
│ ├── .babelrc
│ ├── proxy.conf.json
│ ├── babel-jest.config.json
│ ├── tsconfig.json
│ ├── tsconfig.app.json
│ ├── jest.config.js
│ ├── tsconfig.spec.json
│ ├── .browserslistrc
│ └── .eslintrc
└── todos-e2e
│ ├── src
│ ├── support
│ │ ├── app.po.ts
│ │ ├── index.ts
│ │ └── commands.ts
│ ├── fixtures
│ │ └── example.json
│ ├── integration
│ │ └── app.spec.ts
│ └── plugins
│ │ └── index.js
│ ├── tsconfig.json
│ ├── tsconfig.e2e.json
│ ├── .eslintrc
│ └── cypress.json
├── libs
├── .gitkeep
└── api-interfaces
│ ├── src
│ ├── index.ts
│ └── lib
│ │ └── api-interfaces.ts
│ ├── .eslintrc
│ ├── README.md
│ ├── tsconfig.lib.json
│ ├── tsconfig.json
│ ├── tsconfig.spec.json
│ └── jest.config.js
├── tools
├── schematics
│ └── .gitkeep
├── tsconfig.tools.json
└── externals
│ └── prepare.js
├── .prettierrc
├── babel.config.json
├── .prettierignore
├── jest.config.js
├── .editorconfig
├── .gitignore
├── tsconfig.base.json
├── .github
└── workflows
│ ├── build-pr.yml
│ ├── build-main.yml
│ └── move-code.yml
├── externals
└── todos
│ ├── tsconfig.base.json
│ ├── nx.json
│ └── workspace.json
├── nx.json
├── .eslintrc
├── README.md
├── package.json
└── workspace.json
/apps/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/libs/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tools/schematics/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/blog-api/src/app/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/blog-api/src/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/blog/src/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/todos-api/src/app/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/todos/src/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/todos-api/src/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true
3 | }
4 |
--------------------------------------------------------------------------------
/libs/api-interfaces/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './lib/api-interfaces';
2 |
--------------------------------------------------------------------------------
/apps/todos-e2e/src/support/app.po.ts:
--------------------------------------------------------------------------------
1 | export const getGreeting = () => cy.get('h1');
2 |
--------------------------------------------------------------------------------
/apps/blog/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@nrwl/react/babel"],
3 | "plugins": []
4 | }
5 |
--------------------------------------------------------------------------------
/apps/todos/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@nrwl/react/babel"],
3 | "plugins": []
4 | }
5 |
--------------------------------------------------------------------------------
/babel.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@nrwl/web/babel"],
3 | "babelrcRoots": ["*"]
4 | }
5 |
--------------------------------------------------------------------------------
/apps/blog-api/.eslintrc:
--------------------------------------------------------------------------------
1 | { "extends": "../../.eslintrc", "rules": {}, "ignorePatterns": ["!**/*"] }
2 |
--------------------------------------------------------------------------------
/apps/blog/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Olivr/nx-copybara/HEAD/apps/blog/src/favicon.ico
--------------------------------------------------------------------------------
/apps/todos-api/.eslintrc:
--------------------------------------------------------------------------------
1 | { "extends": "../../.eslintrc", "rules": {}, "ignorePatterns": ["!**/*"] }
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Add files here to ignore them from prettier formatting
2 |
3 | /dist
4 | /coverage
5 |
--------------------------------------------------------------------------------
/apps/blog/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
--------------------------------------------------------------------------------
/apps/todos/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Olivr/nx-copybara/HEAD/apps/todos/src/favicon.ico
--------------------------------------------------------------------------------
/libs/api-interfaces/.eslintrc:
--------------------------------------------------------------------------------
1 | { "extends": "../../.eslintrc", "rules": {}, "ignorePatterns": ["!**/*"] }
2 |
--------------------------------------------------------------------------------
/libs/api-interfaces/src/lib/api-interfaces.ts:
--------------------------------------------------------------------------------
1 | export interface Message {
2 | message: string;
3 | }
4 |
--------------------------------------------------------------------------------
/apps/blog-api/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: false,
3 | };
4 |
--------------------------------------------------------------------------------
/apps/blog/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true,
3 | };
4 |
--------------------------------------------------------------------------------
/apps/todos-api/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: false,
3 | };
4 |
--------------------------------------------------------------------------------
/apps/todos/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true,
3 | };
4 |
--------------------------------------------------------------------------------
/apps/todos/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
--------------------------------------------------------------------------------
/apps/blog-api/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true,
3 | };
4 |
--------------------------------------------------------------------------------
/apps/todos-api/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true,
3 | };
4 |
--------------------------------------------------------------------------------
/apps/blog/proxy.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "/api": {
3 | "target": "http://localhost:3333",
4 | "secure": false
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/apps/todos/proxy.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "/api": {
3 | "target": "http://localhost:3333",
4 | "secure": false
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/apps/todos-e2e/src/fixtures/example.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Using fixtures to represent data",
3 | "email": "hello@cypress.io"
4 | }
5 |
--------------------------------------------------------------------------------
/apps/todos-e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.e2e.json"
8 | }
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/libs/api-interfaces/README.md:
--------------------------------------------------------------------------------
1 | # api-interfaces
2 |
3 | This library was generated with [Nx](https://nx.dev).
4 |
5 | ## Running unit tests
6 |
7 | Run `nx test api-interfaces` to execute the unit tests via [Jest](https://jestjs.io).
8 |
--------------------------------------------------------------------------------
/libs/api-interfaces/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "types": []
6 | },
7 | "exclude": ["**/*.spec.ts"],
8 | "include": ["**/*.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/apps/blog-api/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "types": ["node", "express"]
6 | },
7 | "exclude": ["**/*.spec.ts"],
8 | "include": ["**/*.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/apps/todos-api/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "types": ["node", "express"]
6 | },
7 | "exclude": ["**/*.spec.ts"],
8 | "include": ["**/*.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/apps/blog/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Polyfill stable language features. These imports will be optimized by `@babel/preset-env`.
3 | *
4 | * See: https://github.com/zloirock/core-js#babel
5 | */
6 | import 'core-js/stable';
7 | import 'regenerator-runtime/runtime';
8 |
--------------------------------------------------------------------------------
/apps/todos/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Polyfill stable language features. These imports will be optimized by `@babel/preset-env`.
3 | *
4 | * See: https://github.com/zloirock/core-js#babel
5 | */
6 | import 'core-js/stable';
7 | import 'regenerator-runtime/runtime';
8 |
--------------------------------------------------------------------------------
/apps/blog-api/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": ["**/*.spec.ts", "**/*.d.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/apps/todos-api/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": ["**/*.spec.ts", "**/*.d.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/apps/blog/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // When building for production, this file is replaced with `environment.prod.ts`.
3 |
4 | export const environment = {
5 | production: false,
6 | };
7 |
--------------------------------------------------------------------------------
/apps/blog/src/main.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | import App from './app/app';
5 |
6 | ReactDOM.render(
7 |
8 |
9 | ,
10 | document.getElementById('root')
11 | );
12 |
--------------------------------------------------------------------------------
/apps/todos/src/main.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | import App from './app/app';
5 |
6 | ReactDOM.render(
7 |
8 |
9 | ,
10 | document.getElementById('root')
11 | );
12 |
--------------------------------------------------------------------------------
/apps/todos/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // When building for production, this file is replaced with `environment.prod.ts`.
3 |
4 | export const environment = {
5 | production: false,
6 | };
7 |
--------------------------------------------------------------------------------
/apps/blog-api/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.app.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/apps/todos-api/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.app.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/libs/api-interfaces/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.lib.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/apps/blog/babel-jest.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "targets": {
7 | "node": "current"
8 | }
9 | }
10 | ],
11 | "@babel/preset-typescript",
12 | "@babel/preset-react"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/apps/todos/babel-jest.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "targets": {
7 | "node": "current"
8 | }
9 | }
10 | ],
11 | "@babel/preset-typescript",
12 | "@babel/preset-react"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/apps/todos-e2e/tsconfig.e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "sourceMap": false,
5 | "outDir": "../../dist/out-tsc",
6 | "allowJs": true,
7 | "types": ["cypress", "node"]
8 | },
9 | "include": ["src/**/*.ts", "src/**/*.js"]
10 | }
11 |
--------------------------------------------------------------------------------
/tools/tsconfig.tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.base.json",
3 | "compilerOptions": {
4 | "outDir": "../dist/out-tsc/tools",
5 | "rootDir": ".",
6 | "module": "commonjs",
7 | "target": "es5",
8 | "types": ["node"]
9 | },
10 | "include": ["**/*.ts"]
11 | }
12 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
3 | transform: {
4 | '^.+\\.(ts|js|html)$': 'ts-jest',
5 | },
6 | resolver: '@nrwl/jest/plugins/resolver',
7 | moduleFileExtensions: ['ts', 'js', 'html'],
8 | coverageReporters: ['html'],
9 | };
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = off
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/apps/todos-e2e/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {},
3 | "overrides": [
4 | {
5 | "files": ["src/plugins/index.js"],
6 | "rules": {
7 | "@typescript-eslint/no-var-requires": "off",
8 | "no-undef": "off"
9 | }
10 | }
11 | ],
12 | "extends": ["plugin:cypress/recommended", "../../.eslintrc"],
13 | "ignorePatterns": ["!**/*"]
14 | }
15 |
--------------------------------------------------------------------------------
/libs/api-interfaces/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": [
9 | "**/*.spec.ts",
10 | "**/*.spec.tsx",
11 | "**/*.spec.js",
12 | "**/*.spec.jsx",
13 | "**/*.d.ts"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/apps/blog-api/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: 'blog-api',
3 | preset: '../../jest.config.js',
4 | globals: {
5 | 'ts-jest': {
6 | tsConfig: '/tsconfig.spec.json',
7 | },
8 | },
9 | transform: {
10 | '^.+\\.[tj]s$': 'ts-jest',
11 | },
12 | moduleFileExtensions: ['ts', 'js', 'html'],
13 | coverageDirectory: '../../coverage/apps/blog-api',
14 | };
15 |
--------------------------------------------------------------------------------
/apps/blog/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | blog
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/apps/todos-api/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: 'todos-api',
3 | preset: '../../jest.config.js',
4 | globals: {
5 | 'ts-jest': {
6 | tsConfig: '/tsconfig.spec.json',
7 | },
8 | },
9 | transform: {
10 | '^.+\\.[tj]s$': 'ts-jest',
11 | },
12 | moduleFileExtensions: ['ts', 'js', 'html'],
13 | coverageDirectory: '../../coverage/apps/todos-api',
14 | };
15 |
--------------------------------------------------------------------------------
/apps/todos/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Todos
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/apps/blog/src/app/star.svg:
--------------------------------------------------------------------------------
1 |
2 |
12 |
--------------------------------------------------------------------------------
/apps/todos/src/app/star.svg:
--------------------------------------------------------------------------------
1 |
2 |
12 |
--------------------------------------------------------------------------------
/libs/api-interfaces/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: 'api-interfaces',
3 | preset: '../../jest.config.js',
4 | globals: {
5 | 'ts-jest': {
6 | tsConfig: '/tsconfig.spec.json',
7 | },
8 | },
9 | transform: {
10 | '^.+\\.[tj]sx?$': 'ts-jest',
11 | },
12 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
13 | coverageDirectory: '../../coverage/libs/api-interfaces',
14 | };
15 |
--------------------------------------------------------------------------------
/apps/blog/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "types": ["node"]
6 | },
7 | "files": [
8 | "../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
9 | "../../node_modules/@nrwl/react/typings/image.d.ts"
10 | ],
11 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
12 | "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
13 | }
14 |
--------------------------------------------------------------------------------
/apps/blog/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "jsx": "react",
5 | "allowJs": true,
6 | "esModuleInterop": true,
7 | "allowSyntheticDefaultImports": true
8 | },
9 | "files": [],
10 | "include": [],
11 | "references": [
12 | {
13 | "path": "./tsconfig.app.json"
14 | },
15 | {
16 | "path": "./tsconfig.spec.json"
17 | }
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/apps/todos/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "jsx": "react",
5 | "allowJs": true,
6 | "esModuleInterop": true,
7 | "allowSyntheticDefaultImports": true
8 | },
9 | "files": [],
10 | "include": [],
11 | "references": [
12 | {
13 | "path": "./tsconfig.app.json"
14 | },
15 | {
16 | "path": "./tsconfig.spec.json"
17 | }
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/apps/todos/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "types": ["node"]
6 | },
7 | "files": [
8 | "../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
9 | "../../node_modules/@nrwl/react/typings/image.d.ts"
10 | ],
11 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
12 | "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
13 | }
14 |
--------------------------------------------------------------------------------
/apps/blog/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: 'blog',
3 | preset: '../../jest.config.js',
4 | transform: {
5 | '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest',
6 | '^.+\\.[tj]sx?$': [
7 | 'babel-jest',
8 | { cwd: __dirname, configFile: './babel-jest.config.json' },
9 | ],
10 | },
11 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
12 | coverageDirectory: '../../coverage/apps/blog',
13 | };
14 |
--------------------------------------------------------------------------------
/apps/todos/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: 'todos',
3 | preset: '../../jest.config.js',
4 | transform: {
5 | '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest',
6 | '^.+\\.[tj]sx?$': [
7 | 'babel-jest',
8 | { cwd: __dirname, configFile: './babel-jest.config.json' },
9 | ],
10 | },
11 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
12 | coverageDirectory: '../../coverage/apps/todos',
13 | };
14 |
--------------------------------------------------------------------------------
/apps/todos-e2e/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "fileServerFolder": ".",
3 | "fixturesFolder": "./src/fixtures",
4 | "integrationFolder": "./src/integration",
5 | "modifyObstructiveCode": false,
6 | "pluginsFile": "./src/plugins/index",
7 | "supportFile": "./src/support/index.ts",
8 | "video": true,
9 | "videosFolder": "../../dist/cypress/apps/todos-e2e/videos",
10 | "screenshotsFolder": "../../dist/cypress/apps/todos-e2e/screenshots",
11 | "chromeWebSecurity": false
12 | }
13 |
--------------------------------------------------------------------------------
/apps/todos-e2e/src/integration/app.spec.ts:
--------------------------------------------------------------------------------
1 | import { getGreeting } from '../support/app.po';
2 |
3 | describe('todos', () => {
4 | beforeEach(() => cy.visit('/'));
5 |
6 | it('should display welcome message', () => {
7 | // Custom command example, see `../support/commands.ts` file
8 | cy.login('my-email@something.com', 'myPassword');
9 |
10 | // Function helper example, see `../support/app.po.ts` file
11 | getGreeting().contains('Welcome to todos!');
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/apps/blog-api/src/main.ts:
--------------------------------------------------------------------------------
1 | import * as express from 'express';
2 | import { Message } from '@myorg/api-interfaces';
3 |
4 | const app = express();
5 |
6 | const greeting: Message = { message: 'Welcome to api!' };
7 |
8 | app.get('/api', (req, res) => {
9 | res.send(greeting);
10 | });
11 |
12 | const port = process.env.port || 3333;
13 | const server = app.listen(port, () => {
14 | console.log('Listening at http://localhost:' + port + '/api');
15 | });
16 | server.on('error', console.error);
17 |
--------------------------------------------------------------------------------
/apps/todos-api/src/main.ts:
--------------------------------------------------------------------------------
1 | import * as express from 'express';
2 | import { Message } from '@myorg/api-interfaces';
3 |
4 | const app = express();
5 |
6 | const greeting: Message = { message: 'Welcome to api!' };
7 |
8 | app.get('/api', (req, res) => {
9 | res.send(greeting);
10 | });
11 |
12 | const port = process.env.port || 3333;
13 | const server = app.listen(port, () => {
14 | console.log('Listening at http://localhost:' + port + '/api');
15 | });
16 | server.on('error', console.error);
17 |
--------------------------------------------------------------------------------
/apps/blog/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": [
9 | "**/*.spec.ts",
10 | "**/*.spec.tsx",
11 | "**/*.spec.js",
12 | "**/*.spec.jsx",
13 | "**/*.d.ts"
14 | ],
15 | "files": [
16 | "../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
17 | "../../node_modules/@nrwl/react/typings/image.d.ts"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/apps/todos/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": [
9 | "**/*.spec.ts",
10 | "**/*.spec.tsx",
11 | "**/*.spec.js",
12 | "**/*.spec.jsx",
13 | "**/*.d.ts"
14 | ],
15 | "files": [
16 | "../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
17 | "../../node_modules/@nrwl/react/typings/image.d.ts"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/apps/blog/.browserslistrc:
--------------------------------------------------------------------------------
1 | # This file is used by:
2 | # 1. autoprefixer to adjust CSS to support the below specified browsers
3 | # 2. babel preset-env to adjust included polyfills
4 | #
5 | # For additional information regarding the format and rule options, please see:
6 | # https://github.com/browserslist/browserslist#queries
7 | #
8 | # If you need to support different browsers in production, you may tweak the list below.
9 |
10 | last 1 Chrome version
11 | last 1 Firefox version
12 | last 2 Edge major versions
13 | last 2 Safari major version
14 | last 2 iOS major versions
15 | Firefox ESR
16 | not IE 9-11 # For IE 9-11 support, remove 'not'.
--------------------------------------------------------------------------------
/apps/todos/.browserslistrc:
--------------------------------------------------------------------------------
1 | # This file is used by:
2 | # 1. autoprefixer to adjust CSS to support the below specified browsers
3 | # 2. babel preset-env to adjust included polyfills
4 | #
5 | # For additional information regarding the format and rule options, please see:
6 | # https://github.com/browserslist/browserslist#queries
7 | #
8 | # If you need to support different browsers in production, you may tweak the list below.
9 |
10 | last 1 Chrome version
11 | last 1 Firefox version
12 | last 2 Edge major versions
13 | last 2 Safari major version
14 | last 2 iOS major versions
15 | Firefox ESR
16 | not IE 9-11 # For IE 9-11 support, remove 'not'.
--------------------------------------------------------------------------------
/apps/blog/src/app/app.spec.tsx:
--------------------------------------------------------------------------------
1 | import App from "./app";
2 | import React from "react";
3 | import {
4 | cleanup,
5 | getByText,
6 | render,
7 | waitFor
8 | } from "@testing-library/react";
9 |
10 | describe('App', () => {
11 | afterEach(() => {
12 | delete global['fetch'];
13 | cleanup();
14 | });
15 |
16 | it('should render successfully', async () => {
17 | global['fetch'] = jest.fn().mockResolvedValueOnce({
18 | json: () => ({
19 | message: 'my message',
20 | }),
21 | });
22 |
23 | const { baseElement } = render();
24 | await waitFor(() => getByText(baseElement, 'my message'));
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/apps/todos/src/app/app.spec.tsx:
--------------------------------------------------------------------------------
1 | import App from "./app";
2 | import React from "react";
3 | import {
4 | cleanup,
5 | getByText,
6 | render,
7 | waitFor
8 | } from "@testing-library/react";
9 |
10 | describe('App', () => {
11 | afterEach(() => {
12 | delete global['fetch'];
13 | cleanup();
14 | });
15 |
16 | it('should render successfully', async () => {
17 | global['fetch'] = jest.fn().mockResolvedValueOnce({
18 | json: () => ({
19 | message: 'my message',
20 | }),
21 | });
22 |
23 | const { baseElement } = render();
24 | await waitFor(() => getByText(baseElement, 'my message'));
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 |
8 | # dependencies
9 | /node_modules
10 |
11 | # IDEs and editors
12 | /.idea
13 | .project
14 | .classpath
15 | .c9/
16 | *.launch
17 | .settings/
18 | *.sublime-workspace
19 |
20 | # IDE - VSCode
21 | .vscode/*
22 | !.vscode/settings.json
23 | !.vscode/tasks.json
24 | !.vscode/launch.json
25 | !.vscode/extensions.json
26 |
27 | # misc
28 | /.sass-cache
29 | /connect.lock
30 | /coverage
31 | /libpeerconnection.log
32 | npm-debug.log
33 | yarn-error.log
34 | testem.log
35 | /typings
36 |
37 | # System Files
38 | .DS_Store
39 | Thumbs.db
40 |
--------------------------------------------------------------------------------
/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "rootDir": ".",
5 | "sourceMap": true,
6 | "declaration": false,
7 | "moduleResolution": "node",
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "importHelpers": true,
11 | "target": "es2015",
12 | "module": "esnext",
13 | "typeRoots": ["node_modules/@types"],
14 | "lib": ["es2017", "dom"],
15 | "skipLibCheck": true,
16 | "skipDefaultLibCheck": true,
17 | "baseUrl": ".",
18 | "paths": {
19 | "@myorg/api-interfaces": ["libs/api-interfaces/src/index.ts"]
20 | }
21 | },
22 | "exclude": ["node_modules", "tmp"]
23 | }
24 |
--------------------------------------------------------------------------------
/apps/todos-e2e/src/support/index.ts:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/index.js is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | // Import commands.js using ES2015 syntax:
17 | import './commands';
18 |
--------------------------------------------------------------------------------
/.github/workflows/build-pr.yml:
--------------------------------------------------------------------------------
1 | on:
2 | pull_request:
3 | jobs:
4 | build:
5 | runs-on: ubuntu-latest
6 | steps:
7 | - uses: actions/checkout@v2
8 | with:
9 | fetch-depth: 0
10 |
11 | - uses: actions/setup-node@v2.1.0
12 | with:
13 | node-version: 12
14 |
15 | - run: yarn install --frozen-lockfile
16 |
17 | - run: yarn affected:lint --parallel --base=origin/${{ github.base_ref }}
18 | - run: yarn affected:test --parallel --base=origin/${{ github.base_ref }}
19 | - run: yarn affected:e2e --parallel --headless --base=origin/${{ github.base_ref }}
20 |
21 | - run: yarn affected:build --parallel --base=origin/${{ github.base_ref }}
22 |
--------------------------------------------------------------------------------
/apps/blog/src/app/app.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { Message } from "@myorg/api-interfaces";
3 |
4 | export const App = () => {
5 | const [m, setMessage] = useState({ message: '' });
6 |
7 | useEffect(() => {
8 | fetch('/api')
9 | .then((r) => r.json())
10 | .then(setMessage);
11 | }, []);
12 |
13 | return (
14 | <>
15 |
16 |
Welcome to blog!
17 |

21 |
22 | {m.message}
23 | >
24 | );
25 | };
26 |
27 | export default App;
28 |
--------------------------------------------------------------------------------
/apps/todos/src/app/app.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react';
2 | import { Message } from '@myorg/api-interfaces';
3 |
4 | export const App = () => {
5 | const [m, setMessage] = useState({ message: '' });
6 |
7 | useEffect(() => {
8 | fetch('/api')
9 | .then((r) => r.json())
10 | .then(setMessage);
11 | }, []);
12 |
13 | return (
14 | <>
15 |
16 |
Welcome to todos!
17 |

21 |
22 | {m.message}
23 | >
24 | );
25 | };
26 |
27 | export default App;
28 |
--------------------------------------------------------------------------------
/externals/todos/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "rootDir": ".",
5 | "sourceMap": true,
6 | "declaration": false,
7 | "moduleResolution": "node",
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "importHelpers": true,
11 | "target": "es2015",
12 | "module": "esnext",
13 | "typeRoots": [
14 | "node_modules/@types"
15 | ],
16 | "lib": [
17 | "es2017",
18 | "dom"
19 | ],
20 | "skipLibCheck": true,
21 | "skipDefaultLibCheck": true,
22 | "baseUrl": ".",
23 | "paths": {
24 | "@myorg/api-interfaces": [
25 | "libs/api-interfaces/src/index.ts"
26 | ]
27 | }
28 | },
29 | "exclude": [
30 | "node_modules",
31 | "tmp"
32 | ]
33 | }
--------------------------------------------------------------------------------
/.github/workflows/build-main.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches:
4 | - main
5 |
6 | jobs:
7 | build:
8 | name: Build & Release
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v2
12 | with:
13 | fetch-depth: 0
14 |
15 | - uses: actions/setup-node@v2.1.0
16 | with:
17 | node-version: 12
18 |
19 | - run: yarn install --frozen-lockfile
20 |
21 | - run: yarn nx run-many --parallel --all --target=lint
22 | - run: yarn nx run-many --parallel --all --target=test --configuration=production
23 | - run: yarn nx run-many --parallel --all --target=e2e --headless --configuration=production
24 |
25 | - run: yarn affected:build --base=main~1 --parallel --configuration=production
26 | - run: yarn affected:release --base=main~1 --parallel --configuration=production
27 |
--------------------------------------------------------------------------------
/apps/todos-e2e/src/plugins/index.js:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example plugins/index.js can be used to load plugins
3 | //
4 | // You can change the location of this file or turn off loading
5 | // the plugins file with the 'pluginsFile' configuration option.
6 | //
7 | // You can read more here:
8 | // https://on.cypress.io/plugins-guide
9 | // ***********************************************************
10 |
11 | // This function is called when a project is opened or re-opened (e.g. due to
12 | // the project's config changing)
13 |
14 | const { preprocessTypescript } = require('@nrwl/cypress/plugins/preprocessor');
15 |
16 | module.exports = (on, config) => {
17 | // `on` is used to hook into various events Cypress emits
18 | // `config` is the resolved Cypress config
19 |
20 | // Preprocess Typescript file using Nx helper
21 | on('file:preprocessor', preprocessTypescript(config));
22 | };
23 |
--------------------------------------------------------------------------------
/.github/workflows/move-code.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | pull_request_target:
4 | jobs:
5 | move-code:
6 | runs-on: ubuntu-latest
7 | steps:
8 | - uses: actions/checkout@v2
9 | with:
10 | fetch-depth: 0
11 |
12 | - uses: olivr/copybara-action@v1.2.2
13 | with:
14 | ssh_key: ${{ secrets.GH_SSH_BOT }}
15 | access_token: ${{ secrets.GH_TOKEN_BOT }}
16 | sot_repo: olivr/nx-copybara
17 | destination_repo: olivr/nx-copybara-todos
18 | push_include: '.github/workflows/build-pr.yml .github/workflows/move-code.yml apps/todos*/** libs/** externals/todos/** tools/** .*rc .*ignore *.json *.js *.lock'
19 | push_exclude: 'nx.json tsconfig.base.json workspace.json'
20 | pr_move: |
21 | nx.json||externals/todos/nx.json
22 | tsconfig.base.json||externals/todos/tsconfig.base.json
23 | workspace.json||externals/todos/workspace.json
24 |
--------------------------------------------------------------------------------
/nx.json:
--------------------------------------------------------------------------------
1 | {
2 | "npmScope": "myorg",
3 | "affected": {
4 | "defaultBase": "main"
5 | },
6 | "implicitDependencies": {
7 | "workspace.json": "*",
8 | "package.json": {
9 | "dependencies": "*",
10 | "devDependencies": "*"
11 | },
12 | "tsconfig.base.json": "*",
13 | "tslint.json": "*",
14 | "nx.json": "*"
15 | },
16 | "tasksRunnerOptions": {
17 | "default": {
18 | "runner": "@nrwl/workspace/tasks-runners/default",
19 | "options": {
20 | "cacheableOperations": ["build", "lint", "test", "e2e"]
21 | }
22 | }
23 | },
24 | "projects": {
25 | "todos": {
26 | "tags": ["todos"]
27 | },
28 | "todos-e2e": {
29 | "tags": ["todos"],
30 | "implicitDependencies": ["todos"]
31 | },
32 | "todos-api": {
33 | "tags": ["todos"]
34 | },
35 | "blog": {
36 | "tags": ["blog"]
37 | },
38 | "blog-api": {
39 | "tags": ["blog"]
40 | },
41 | "api-interfaces": {
42 | "tags": ["todos", "blog"]
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/externals/todos/nx.json:
--------------------------------------------------------------------------------
1 | {
2 | "npmScope": "myorg",
3 | "affected": {
4 | "defaultBase": "main"
5 | },
6 | "implicitDependencies": {
7 | "workspace.json": "*",
8 | "package.json": {
9 | "dependencies": "*",
10 | "devDependencies": "*"
11 | },
12 | "tsconfig.base.json": "*",
13 | "tslint.json": "*",
14 | "nx.json": "*"
15 | },
16 | "tasksRunnerOptions": {
17 | "default": {
18 | "runner": "@nrwl/workspace/tasks-runners/default",
19 | "options": {
20 | "cacheableOperations": [
21 | "build",
22 | "lint",
23 | "test",
24 | "e2e"
25 | ]
26 | }
27 | }
28 | },
29 | "projects": {
30 | "todos": {
31 | "tags": [
32 | "todos"
33 | ]
34 | },
35 | "todos-e2e": {
36 | "tags": [
37 | "todos"
38 | ],
39 | "implicitDependencies": [
40 | "todos"
41 | ]
42 | },
43 | "todos-api": {
44 | "tags": [
45 | "todos"
46 | ]
47 | },
48 | "api-interfaces": {
49 | "tags": [
50 | "todos",
51 | "blog"
52 | ]
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "parser": "@typescript-eslint/parser",
4 | "parserOptions": {
5 | "ecmaVersion": 2018,
6 | "sourceType": "module",
7 | "project": "./tsconfig.*?.json"
8 | },
9 | "ignorePatterns": ["**/*"],
10 | "plugins": ["@typescript-eslint", "@nrwl/nx"],
11 | "extends": [
12 | "eslint:recommended",
13 | "plugin:@typescript-eslint/eslint-recommended",
14 | "plugin:@typescript-eslint/recommended",
15 | "prettier",
16 | "prettier/@typescript-eslint"
17 | ],
18 | "rules": {
19 | "@typescript-eslint/explicit-member-accessibility": "off",
20 | "@typescript-eslint/explicit-function-return-type": "off",
21 | "@typescript-eslint/no-parameter-properties": "off",
22 | "@nrwl/nx/enforce-module-boundaries": [
23 | "error",
24 | {
25 | "enforceBuildableLibDependency": true,
26 | "allow": [],
27 | "depConstraints": [
28 | { "sourceTag": "*", "onlyDependOnLibsWithTags": ["*"] }
29 | ]
30 | }
31 | ]
32 | },
33 | "overrides": [
34 | {
35 | "files": ["*.tsx"],
36 | "rules": {
37 | "@typescript-eslint/no-unused-vars": "off"
38 | }
39 | }
40 | ]
41 | }
42 |
--------------------------------------------------------------------------------
/apps/todos-e2e/src/support/commands.ts:
--------------------------------------------------------------------------------
1 | // ***********************************************
2 | // This example commands.js shows you how to
3 | // create various custom commands and overwrite
4 | // existing commands.
5 | //
6 | // For more comprehensive examples of custom
7 | // commands please read more here:
8 | // https://on.cypress.io/custom-commands
9 | // ***********************************************
10 | // eslint-disable-next-line @typescript-eslint/no-namespace
11 | declare namespace Cypress {
12 | interface Chainable {
13 | login(email: string, password: string): void;
14 | }
15 | }
16 | //
17 | // -- This is a parent command --
18 | Cypress.Commands.add('login', (email, password) => {
19 | console.log('Custom command example: Login', email, password);
20 | });
21 | //
22 | // -- This is a child command --
23 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
24 | //
25 | //
26 | // -- This is a dual command --
27 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
28 | //
29 | //
30 | // -- This will overwrite an existing command --
31 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Open source NX sub-project as a new repo with Copybara and Github Actions
2 |
3 | This repo is an example [Nx](https://nx.dev) monorepo to demonstrate how to use [Copybara Action](https://github.com/olivr/copybara-action/) to open-source a part of the monorepo. Pull-Requests in the destination repo will be synced back to your main repo.
4 |
5 | ```text
6 | Source of Truth Destination
7 |
8 | +---------------+ Copybara +---------------+
9 | | Branch +------------> | Branch |
10 | +-------+-------+ +---------------+
11 | ^
12 | |
13 | |
14 | +-------+-------+ Copybara +---------------+
15 | | Pull Requests | <------------+ Pull Requests |
16 | +---------------+ +---------------+
17 | ```
18 |
19 | ## How it works
20 |
21 | 1. Apps and libs are tagged properly
22 | 2. Running `node tools/externals/prepare.js todos` will update `externals/todos`. (The output of this tool must be kept up to date and committed, you could set-up a pre-commit hook)
23 | 3. The Github workflow `.github/workflows/move-code.yml` will then take care of the rest.
24 |
25 | ## Try it!
26 |
27 | 1. Fork this repo
28 | 2. Create another empty repo to use as the destination
29 | 3. [Configure the secrets](https://github.com/olivr/copybara-action/blob/main/docs/basic-usage.md)
30 | 4. Run `node tools/externals/prepare.js blog` on your fork, you will see the new folder `externals/blog`
31 | 5. Change `.github/workflows/move-code.yml` accordingly (basically search/replace _todos_ by _blog_) and adjust the sot/destination repo values.
32 |
33 | ## Use in your own repo
34 |
35 | The two important bits that you need to copy in your own repo are [prepare.js](/tools/externals/prepare.js) and the Github [workflow](.github/workflows/move-code.yml). Check out [Copybara Action](https://github.com/olivr/copybara-action) for more customization.
36 |
--------------------------------------------------------------------------------
/tools/externals/prepare.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | const rootDir = process.env.PWD;
5 | const extDir = path.join(rootDir, 'externals');
6 |
7 | const nxSource = JSON.parse(
8 | fs.readFileSync(path.join(rootDir, 'nx.json'), 'utf-8')
9 | );
10 | const wsSource = JSON.parse(
11 | fs.readFileSync(path.join(rootDir, 'workspace.json'), 'utf-8')
12 | );
13 | const tsSource = JSON.parse(
14 | fs.readFileSync(path.join(rootDir, 'tsconfig.base.json'), 'utf-8')
15 | );
16 |
17 | const externals = process.argv.slice(2);
18 | //const externals = nxSource.externals
19 |
20 | if (externals.length && !fs.existsSync(extDir)) fs.mkdirSync(extDir);
21 |
22 | externals.forEach((tag) => {
23 | const nx = { ...nxSource };
24 | const ws = { ...wsSource };
25 | const ts = { ...tsSource };
26 | const projects = {};
27 |
28 | // Determine projects to include
29 | Object.entries(nx.projects).forEach(([k, v]) => {
30 | if (v.tags.includes(tag)) projects[k] = '';
31 | });
32 |
33 | // Prepare nx.json
34 | nx.projects = Object.keys(nx.projects)
35 | .filter((key) => Object.keys(projects).includes(key))
36 | .reduce((obj, key) => {
37 | obj[key] = nx.projects[key];
38 | return obj;
39 | }, {});
40 |
41 | // Prepare workspace.json
42 | ws.projects = Object.keys(ws.projects)
43 | .filter((key) => Object.keys(projects).includes(key))
44 | .reduce((obj, key) => {
45 | obj[key] = ws.projects[key];
46 | projects[key] = ws.projects[key].root.replace(/\/$/, '').concat('/');
47 | return obj;
48 | }, {});
49 |
50 | // Prepare tsconfig.base.json
51 | const paths = new RegExp(`^(${Object.values(projects).join('|')})`);
52 | ts.compilerOptions.paths = Object.entries(ts.compilerOptions.paths)
53 | .filter(([k, v]) => v.filter((path) => paths.test(path)).length == v.length)
54 | .reduce((obj, [k, v]) => {
55 | obj[k] = ts.compilerOptions.paths[k];
56 | return obj;
57 | }, {});
58 |
59 | // Save files
60 | const dir = path.join(extDir, tag);
61 | if (!fs.existsSync(dir)) fs.mkdirSync(dir);
62 | fs.writeFileSync(path.join(dir, 'nx.json'), JSON.stringify(nx, null, 2));
63 | fs.writeFileSync(
64 | path.join(dir, 'workspace.json'),
65 | JSON.stringify(ws, null, 2)
66 | );
67 | fs.writeFileSync(
68 | path.join(dir, 'tsconfig.base.json'),
69 | JSON.stringify(ts, null, 2)
70 | );
71 | });
72 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "myorg",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "scripts": {
6 | "nx": "nx",
7 | "start": "nx serve",
8 | "build": "nx build",
9 | "test": "nx test",
10 | "lint": "nx workspace-lint && nx lint",
11 | "e2e": "nx e2e",
12 | "affected:apps": "nx affected:apps",
13 | "affected:libs": "nx affected:libs",
14 | "affected:build": "nx affected:build",
15 | "affected:e2e": "nx affected:e2e",
16 | "affected:test": "nx affected:test",
17 | "affected:lint": "nx affected:lint",
18 | "affected:release": "nx affected --target=release",
19 | "affected:dep-graph": "nx affected:dep-graph",
20 | "affected": "nx affected",
21 | "format": "nx format:write",
22 | "format:write": "nx format:write",
23 | "format:check": "nx format:check",
24 | "update": "nx migrate latest",
25 | "workspace-schematic": "nx workspace-schematic",
26 | "dep-graph": "nx dep-graph",
27 | "help": "nx help"
28 | },
29 | "private": true,
30 | "dependencies": {
31 | "document-register-element": "1.13.1",
32 | "react": "16.13.1",
33 | "react-dom": "16.13.1",
34 | "express": "4.17.1"
35 | },
36 | "devDependencies": {
37 | "@nrwl/workspace": "10.2.1",
38 | "@types/node": "~8.9.4",
39 | "dotenv": "6.2.0",
40 | "ts-node": "~7.0.0",
41 | "tslint": "~6.0.0",
42 | "eslint": "6.8.0",
43 | "typescript": "~3.9.3",
44 | "prettier": "2.0.4",
45 | "@nrwl/react": "10.2.1",
46 | "@nrwl/express": "10.2.1",
47 | "@nrwl/jest": "10.2.1",
48 | "jest": "26.2.2",
49 | "@types/jest": "26.0.8",
50 | "ts-jest": "26.1.4",
51 | "cypress": "^4.1.0",
52 | "@nrwl/cypress": "10.2.1",
53 | "@nrwl/web": "10.2.1",
54 | "@types/react": "16.9.38",
55 | "@types/react-dom": "16.9.8",
56 | "@testing-library/react": "10.4.1",
57 | "@nrwl/eslint-plugin-nx": "10.2.1",
58 | "@typescript-eslint/parser": "2.19.2",
59 | "@typescript-eslint/eslint-plugin": "2.19.2",
60 | "eslint-config-prettier": "6.0.0",
61 | "eslint-plugin-import": "2.21.2",
62 | "eslint-plugin-jsx-a11y": "6.3.1",
63 | "eslint-plugin-react": "7.20.0",
64 | "eslint-plugin-react-hooks": "4.0.4",
65 | "eslint-plugin-cypress": "^2.10.3",
66 | "@babel/core": "7.9.6",
67 | "@babel/preset-env": "7.9.6",
68 | "@babel/preset-typescript": "7.9.0",
69 | "@babel/preset-react": "7.9.4",
70 | "babel-jest": "26.2.2",
71 | "@nrwl/node": "10.2.1",
72 | "@types/express": "4.17.0"
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/apps/blog/src/app/app.css:
--------------------------------------------------------------------------------
1 | .app {
2 | font-family: sans-serif;
3 | min-width: 300px;
4 | max-width: 600px;
5 | margin: 50px auto;
6 | }
7 |
8 | .app .gutter-left {
9 | margin-left: 9px;
10 | }
11 |
12 | .app .col-span-2 {
13 | grid-column: span 2;
14 | }
15 |
16 | .app .flex {
17 | display: flex;
18 | align-items: center;
19 | justify-content: center;
20 | }
21 |
22 | .app header {
23 | background-color: #143055;
24 | color: white;
25 | padding: 5px;
26 | border-radius: 3px;
27 | }
28 |
29 | .app main {
30 | padding: 0 36px;
31 | }
32 |
33 | .app p {
34 | text-align: center;
35 | }
36 |
37 | .app h1 {
38 | text-align: center;
39 | margin-left: 18px;
40 | font-size: 24px;
41 | }
42 |
43 | .app h2 {
44 | text-align: center;
45 | font-size: 20px;
46 | margin: 40px 0 10px 0;
47 | }
48 |
49 | .app .resources {
50 | text-align: center;
51 | list-style: none;
52 | padding: 0;
53 | display: grid;
54 | grid-gap: 9px;
55 | grid-template-columns: 1fr 1fr;
56 | }
57 |
58 | .app .resource {
59 | color: #0094ba;
60 | height: 36px;
61 | background-color: rgba(0, 0, 0, 0);
62 | border: 1px solid rgba(0, 0, 0, 0.12);
63 | border-radius: 4px;
64 | padding: 3px 9px;
65 | text-decoration: none;
66 | }
67 |
68 | .app .resource:hover {
69 | background-color: rgba(68, 138, 255, 0.04);
70 | }
71 |
72 | .app pre {
73 | padding: 9px;
74 | border-radius: 4px;
75 | background-color: black;
76 | color: #eee;
77 | }
78 |
79 | .app details {
80 | border-radius: 4px;
81 | color: #333;
82 | background-color: rgba(0, 0, 0, 0);
83 | border: 1px solid rgba(0, 0, 0, 0.12);
84 | padding: 3px 9px;
85 | margin-bottom: 9px;
86 | }
87 |
88 | .app summary {
89 | outline: none;
90 | height: 36px;
91 | line-height: 36px;
92 | }
93 |
94 | .app .github-star-container {
95 | margin-top: 12px;
96 | line-height: 20px;
97 | }
98 |
99 | .app .github-star-container a {
100 | display: flex;
101 | align-items: center;
102 | text-decoration: none;
103 | color: #333;
104 | }
105 |
106 | .app .github-star-badge {
107 | color: #24292e;
108 | display: flex;
109 | align-items: center;
110 | font-size: 12px;
111 | padding: 3px 10px;
112 | border: 1px solid rgba(27, 31, 35, 0.2);
113 | border-radius: 3px;
114 | background-image: linear-gradient(-180deg, #fafbfc, #eff3f6 90%);
115 | margin-left: 4px;
116 | font-weight: 600;
117 | }
118 |
119 | .app .github-star-badge:hover {
120 | background-image: linear-gradient(-180deg, #f0f3f6, #e6ebf1 90%);
121 | border-color: rgba(27, 31, 35, 0.35);
122 | background-position: -0.5em;
123 | }
124 | .app .github-star-badge .material-icons {
125 | height: 16px;
126 | width: 16px;
127 | margin-right: 4px;
128 | }
129 |
--------------------------------------------------------------------------------
/apps/todos/src/app/app.css:
--------------------------------------------------------------------------------
1 | .app {
2 | font-family: sans-serif;
3 | min-width: 300px;
4 | max-width: 600px;
5 | margin: 50px auto;
6 | }
7 |
8 | .app .gutter-left {
9 | margin-left: 9px;
10 | }
11 |
12 | .app .col-span-2 {
13 | grid-column: span 2;
14 | }
15 |
16 | .app .flex {
17 | display: flex;
18 | align-items: center;
19 | justify-content: center;
20 | }
21 |
22 | .app header {
23 | background-color: #143055;
24 | color: white;
25 | padding: 5px;
26 | border-radius: 3px;
27 | }
28 |
29 | .app main {
30 | padding: 0 36px;
31 | }
32 |
33 | .app p {
34 | text-align: center;
35 | }
36 |
37 | .app h1 {
38 | text-align: center;
39 | margin-left: 18px;
40 | font-size: 24px;
41 | }
42 |
43 | .app h2 {
44 | text-align: center;
45 | font-size: 20px;
46 | margin: 40px 0 10px 0;
47 | }
48 |
49 | .app .resources {
50 | text-align: center;
51 | list-style: none;
52 | padding: 0;
53 | display: grid;
54 | grid-gap: 9px;
55 | grid-template-columns: 1fr 1fr;
56 | }
57 |
58 | .app .resource {
59 | color: #0094ba;
60 | height: 36px;
61 | background-color: rgba(0, 0, 0, 0);
62 | border: 1px solid rgba(0, 0, 0, 0.12);
63 | border-radius: 4px;
64 | padding: 3px 9px;
65 | text-decoration: none;
66 | }
67 |
68 | .app .resource:hover {
69 | background-color: rgba(68, 138, 255, 0.04);
70 | }
71 |
72 | .app pre {
73 | padding: 9px;
74 | border-radius: 4px;
75 | background-color: black;
76 | color: #eee;
77 | }
78 |
79 | .app details {
80 | border-radius: 4px;
81 | color: #333;
82 | background-color: rgba(0, 0, 0, 0);
83 | border: 1px solid rgba(0, 0, 0, 0.12);
84 | padding: 3px 9px;
85 | margin-bottom: 9px;
86 | }
87 |
88 | .app summary {
89 | outline: none;
90 | height: 36px;
91 | line-height: 36px;
92 | }
93 |
94 | .app .github-star-container {
95 | margin-top: 12px;
96 | line-height: 20px;
97 | }
98 |
99 | .app .github-star-container a {
100 | display: flex;
101 | align-items: center;
102 | text-decoration: none;
103 | color: #333;
104 | }
105 |
106 | .app .github-star-badge {
107 | color: #24292e;
108 | display: flex;
109 | align-items: center;
110 | font-size: 12px;
111 | padding: 3px 10px;
112 | border: 1px solid rgba(27, 31, 35, 0.2);
113 | border-radius: 3px;
114 | background-image: linear-gradient(-180deg, #fafbfc, #eff3f6 90%);
115 | margin-left: 4px;
116 | font-weight: 600;
117 | }
118 |
119 | .app .github-star-badge:hover {
120 | background-image: linear-gradient(-180deg, #f0f3f6, #e6ebf1 90%);
121 | border-color: rgba(27, 31, 35, 0.35);
122 | background-position: -0.5em;
123 | }
124 | .app .github-star-badge .material-icons {
125 | height: 16px;
126 | width: 16px;
127 | margin-right: 4px;
128 | }
129 |
--------------------------------------------------------------------------------
/apps/blog/src/app/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
18 |
--------------------------------------------------------------------------------
/apps/todos/src/app/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
18 |
--------------------------------------------------------------------------------
/apps/blog/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "array-callback-return": "warn",
4 | "dot-location": ["warn", "property"],
5 | "eqeqeq": ["warn", "smart"],
6 | "new-parens": "warn",
7 | "no-caller": "warn",
8 | "no-cond-assign": ["warn", "except-parens"],
9 | "no-const-assign": "warn",
10 | "no-control-regex": "warn",
11 | "no-delete-var": "warn",
12 | "no-dupe-args": "warn",
13 | "no-dupe-keys": "warn",
14 | "no-duplicate-case": "warn",
15 | "no-empty-character-class": "warn",
16 | "no-empty-pattern": "warn",
17 | "no-eval": "warn",
18 | "no-ex-assign": "warn",
19 | "no-extend-native": "warn",
20 | "no-extra-bind": "warn",
21 | "no-extra-label": "warn",
22 | "no-fallthrough": "warn",
23 | "no-func-assign": "warn",
24 | "no-implied-eval": "warn",
25 | "no-invalid-regexp": "warn",
26 | "no-iterator": "warn",
27 | "no-label-var": "warn",
28 | "no-labels": ["warn", { "allowLoop": true, "allowSwitch": false }],
29 | "no-lone-blocks": "warn",
30 | "no-loop-func": "warn",
31 | "no-mixed-operators": [
32 | "warn",
33 | {
34 | "groups": [
35 | ["&", "|", "^", "~", "<<", ">>", ">>>"],
36 | ["==", "!=", "===", "!==", ">", ">=", "<", "<="],
37 | ["&&", "||"],
38 | ["in", "instanceof"]
39 | ],
40 | "allowSamePrecedence": false
41 | }
42 | ],
43 | "no-multi-str": "warn",
44 | "no-native-reassign": "warn",
45 | "no-negated-in-lhs": "warn",
46 | "no-new-func": "warn",
47 | "no-new-object": "warn",
48 | "no-new-symbol": "warn",
49 | "no-new-wrappers": "warn",
50 | "no-obj-calls": "warn",
51 | "no-octal": "warn",
52 | "no-octal-escape": "warn",
53 | "no-redeclare": "warn",
54 | "no-regex-spaces": "warn",
55 | "no-restricted-syntax": ["warn", "WithStatement"],
56 | "no-script-url": "warn",
57 | "no-self-assign": "warn",
58 | "no-self-compare": "warn",
59 | "no-sequences": "warn",
60 | "no-shadow-restricted-names": "warn",
61 | "no-sparse-arrays": "warn",
62 | "no-template-curly-in-string": "warn",
63 | "no-this-before-super": "warn",
64 | "no-throw-literal": "warn",
65 | "no-restricted-globals": [
66 | "error",
67 | "addEventListener",
68 | "blur",
69 | "close",
70 | "closed",
71 | "confirm",
72 | "defaultStatus",
73 | "defaultstatus",
74 | "event",
75 | "external",
76 | "find",
77 | "focus",
78 | "frameElement",
79 | "frames",
80 | "history",
81 | "innerHeight",
82 | "innerWidth",
83 | "length",
84 | "location",
85 | "locationbar",
86 | "menubar",
87 | "moveBy",
88 | "moveTo",
89 | "name",
90 | "onblur",
91 | "onerror",
92 | "onfocus",
93 | "onload",
94 | "onresize",
95 | "onunload",
96 | "open",
97 | "opener",
98 | "opera",
99 | "outerHeight",
100 | "outerWidth",
101 | "pageXOffset",
102 | "pageYOffset",
103 | "parent",
104 | "print",
105 | "removeEventListener",
106 | "resizeBy",
107 | "resizeTo",
108 | "screen",
109 | "screenLeft",
110 | "screenTop",
111 | "screenX",
112 | "screenY",
113 | "scroll",
114 | "scrollbars",
115 | "scrollBy",
116 | "scrollTo",
117 | "scrollX",
118 | "scrollY",
119 | "self",
120 | "status",
121 | "statusbar",
122 | "stop",
123 | "toolbar",
124 | "top"
125 | ],
126 | "no-unexpected-multiline": "warn",
127 | "no-unreachable": "warn",
128 | "no-unused-expressions": "off",
129 | "no-unused-labels": "warn",
130 | "no-useless-computed-key": "warn",
131 | "no-useless-concat": "warn",
132 | "no-useless-escape": "warn",
133 | "no-useless-rename": [
134 | "warn",
135 | {
136 | "ignoreDestructuring": false,
137 | "ignoreImport": false,
138 | "ignoreExport": false
139 | }
140 | ],
141 | "no-with": "warn",
142 | "no-whitespace-before-property": "warn",
143 | "react-hooks/exhaustive-deps": "warn",
144 | "require-yield": "warn",
145 | "rest-spread-spacing": ["warn", "never"],
146 | "strict": ["warn", "never"],
147 | "unicode-bom": ["warn", "never"],
148 | "use-isnan": "warn",
149 | "valid-typeof": "warn",
150 | "no-restricted-properties": [
151 | "error",
152 | {
153 | "object": "require",
154 | "property": "ensure",
155 | "message": "Please use import() instead. More info: https://facebook.github.io/create-react-app/docs/code-splitting"
156 | },
157 | {
158 | "object": "System",
159 | "property": "import",
160 | "message": "Please use import() instead. More info: https://facebook.github.io/create-react-app/docs/code-splitting"
161 | }
162 | ],
163 | "getter-return": "warn",
164 | "import/first": "error",
165 | "import/no-amd": "error",
166 | "import/no-webpack-loader-syntax": "error",
167 | "react/forbid-foreign-prop-types": ["warn", { "allowInPropTypes": true }],
168 | "react/jsx-no-comment-textnodes": "warn",
169 | "react/jsx-no-duplicate-props": "warn",
170 | "react/jsx-no-target-blank": "warn",
171 | "react/jsx-no-undef": "error",
172 | "react/jsx-pascal-case": ["warn", { "allowAllCaps": true, "ignore": [] }],
173 | "react/jsx-uses-react": "warn",
174 | "react/jsx-uses-vars": "warn",
175 | "react/no-danger-with-children": "warn",
176 | "react/no-direct-mutation-state": "warn",
177 | "react/no-is-mounted": "warn",
178 | "react/no-typos": "error",
179 | "react/react-in-jsx-scope": "error",
180 | "react/require-render-return": "error",
181 | "react/style-prop-object": "warn",
182 | "react/jsx-no-useless-fragment": "warn",
183 | "jsx-a11y/accessible-emoji": "warn",
184 | "jsx-a11y/alt-text": "warn",
185 | "jsx-a11y/anchor-has-content": "warn",
186 | "jsx-a11y/anchor-is-valid": [
187 | "warn",
188 | { "aspects": ["noHref", "invalidHref"] }
189 | ],
190 | "jsx-a11y/aria-activedescendant-has-tabindex": "warn",
191 | "jsx-a11y/aria-props": "warn",
192 | "jsx-a11y/aria-proptypes": "warn",
193 | "jsx-a11y/aria-role": "warn",
194 | "jsx-a11y/aria-unsupported-elements": "warn",
195 | "jsx-a11y/heading-has-content": "warn",
196 | "jsx-a11y/iframe-has-title": "warn",
197 | "jsx-a11y/img-redundant-alt": "warn",
198 | "jsx-a11y/no-access-key": "warn",
199 | "jsx-a11y/no-distracting-elements": "warn",
200 | "jsx-a11y/no-redundant-roles": "warn",
201 | "jsx-a11y/role-has-required-aria-props": "warn",
202 | "jsx-a11y/role-supports-aria-props": "warn",
203 | "jsx-a11y/scope": "warn",
204 | "react-hooks/rules-of-hooks": "error",
205 | "default-case": "off",
206 | "no-dupe-class-members": "off",
207 | "no-undef": "off",
208 | "@typescript-eslint/consistent-type-assertions": "warn",
209 | "no-array-constructor": "off",
210 | "@typescript-eslint/no-array-constructor": "warn",
211 | "@typescript-eslint/no-namespace": "error",
212 | "no-use-before-define": "off",
213 | "@typescript-eslint/no-use-before-define": [
214 | "warn",
215 | {
216 | "functions": false,
217 | "classes": false,
218 | "variables": false,
219 | "typedefs": false
220 | }
221 | ],
222 | "no-unused-vars": "off",
223 | "@typescript-eslint/no-unused-vars": [
224 | "warn",
225 | { "args": "none", "ignoreRestSiblings": true }
226 | ],
227 | "no-useless-constructor": "off",
228 | "@typescript-eslint/no-useless-constructor": "warn",
229 | "@typescript-eslint/no-unused-expressions": [
230 | "error",
231 | {
232 | "allowShortCircuit": true,
233 | "allowTernary": true,
234 | "allowTaggedTemplates": true
235 | }
236 | ]
237 | },
238 | "env": {
239 | "browser": true,
240 | "commonjs": true,
241 | "es6": true,
242 | "jest": true,
243 | "node": true
244 | },
245 | "settings": { "react": { "version": "detect" } },
246 | "plugins": ["import", "jsx-a11y", "react", "react-hooks"],
247 | "extends": ["../../.eslintrc"],
248 | "ignorePatterns": ["!**/*"]
249 | }
250 |
--------------------------------------------------------------------------------
/apps/todos/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "array-callback-return": "warn",
4 | "dot-location": ["warn", "property"],
5 | "eqeqeq": ["warn", "smart"],
6 | "new-parens": "warn",
7 | "no-caller": "warn",
8 | "no-cond-assign": ["warn", "except-parens"],
9 | "no-const-assign": "warn",
10 | "no-control-regex": "warn",
11 | "no-delete-var": "warn",
12 | "no-dupe-args": "warn",
13 | "no-dupe-keys": "warn",
14 | "no-duplicate-case": "warn",
15 | "no-empty-character-class": "warn",
16 | "no-empty-pattern": "warn",
17 | "no-eval": "warn",
18 | "no-ex-assign": "warn",
19 | "no-extend-native": "warn",
20 | "no-extra-bind": "warn",
21 | "no-extra-label": "warn",
22 | "no-fallthrough": "warn",
23 | "no-func-assign": "warn",
24 | "no-implied-eval": "warn",
25 | "no-invalid-regexp": "warn",
26 | "no-iterator": "warn",
27 | "no-label-var": "warn",
28 | "no-labels": ["warn", { "allowLoop": true, "allowSwitch": false }],
29 | "no-lone-blocks": "warn",
30 | "no-loop-func": "warn",
31 | "no-mixed-operators": [
32 | "warn",
33 | {
34 | "groups": [
35 | ["&", "|", "^", "~", "<<", ">>", ">>>"],
36 | ["==", "!=", "===", "!==", ">", ">=", "<", "<="],
37 | ["&&", "||"],
38 | ["in", "instanceof"]
39 | ],
40 | "allowSamePrecedence": false
41 | }
42 | ],
43 | "no-multi-str": "warn",
44 | "no-native-reassign": "warn",
45 | "no-negated-in-lhs": "warn",
46 | "no-new-func": "warn",
47 | "no-new-object": "warn",
48 | "no-new-symbol": "warn",
49 | "no-new-wrappers": "warn",
50 | "no-obj-calls": "warn",
51 | "no-octal": "warn",
52 | "no-octal-escape": "warn",
53 | "no-redeclare": "warn",
54 | "no-regex-spaces": "warn",
55 | "no-restricted-syntax": ["warn", "WithStatement"],
56 | "no-script-url": "warn",
57 | "no-self-assign": "warn",
58 | "no-self-compare": "warn",
59 | "no-sequences": "warn",
60 | "no-shadow-restricted-names": "warn",
61 | "no-sparse-arrays": "warn",
62 | "no-template-curly-in-string": "warn",
63 | "no-this-before-super": "warn",
64 | "no-throw-literal": "warn",
65 | "no-restricted-globals": [
66 | "error",
67 | "addEventListener",
68 | "blur",
69 | "close",
70 | "closed",
71 | "confirm",
72 | "defaultStatus",
73 | "defaultstatus",
74 | "event",
75 | "external",
76 | "find",
77 | "focus",
78 | "frameElement",
79 | "frames",
80 | "history",
81 | "innerHeight",
82 | "innerWidth",
83 | "length",
84 | "location",
85 | "locationbar",
86 | "menubar",
87 | "moveBy",
88 | "moveTo",
89 | "name",
90 | "onblur",
91 | "onerror",
92 | "onfocus",
93 | "onload",
94 | "onresize",
95 | "onunload",
96 | "open",
97 | "opener",
98 | "opera",
99 | "outerHeight",
100 | "outerWidth",
101 | "pageXOffset",
102 | "pageYOffset",
103 | "parent",
104 | "print",
105 | "removeEventListener",
106 | "resizeBy",
107 | "resizeTo",
108 | "screen",
109 | "screenLeft",
110 | "screenTop",
111 | "screenX",
112 | "screenY",
113 | "scroll",
114 | "scrollbars",
115 | "scrollBy",
116 | "scrollTo",
117 | "scrollX",
118 | "scrollY",
119 | "self",
120 | "status",
121 | "statusbar",
122 | "stop",
123 | "toolbar",
124 | "top"
125 | ],
126 | "no-unexpected-multiline": "warn",
127 | "no-unreachable": "warn",
128 | "no-unused-expressions": "off",
129 | "no-unused-labels": "warn",
130 | "no-useless-computed-key": "warn",
131 | "no-useless-concat": "warn",
132 | "no-useless-escape": "warn",
133 | "no-useless-rename": [
134 | "warn",
135 | {
136 | "ignoreDestructuring": false,
137 | "ignoreImport": false,
138 | "ignoreExport": false
139 | }
140 | ],
141 | "no-with": "warn",
142 | "no-whitespace-before-property": "warn",
143 | "react-hooks/exhaustive-deps": "warn",
144 | "require-yield": "warn",
145 | "rest-spread-spacing": ["warn", "never"],
146 | "strict": ["warn", "never"],
147 | "unicode-bom": ["warn", "never"],
148 | "use-isnan": "warn",
149 | "valid-typeof": "warn",
150 | "no-restricted-properties": [
151 | "error",
152 | {
153 | "object": "require",
154 | "property": "ensure",
155 | "message": "Please use import() instead. More info: https://facebook.github.io/create-react-app/docs/code-splitting"
156 | },
157 | {
158 | "object": "System",
159 | "property": "import",
160 | "message": "Please use import() instead. More info: https://facebook.github.io/create-react-app/docs/code-splitting"
161 | }
162 | ],
163 | "getter-return": "warn",
164 | "import/first": "error",
165 | "import/no-amd": "error",
166 | "import/no-webpack-loader-syntax": "error",
167 | "react/forbid-foreign-prop-types": ["warn", { "allowInPropTypes": true }],
168 | "react/jsx-no-comment-textnodes": "warn",
169 | "react/jsx-no-duplicate-props": "warn",
170 | "react/jsx-no-target-blank": "warn",
171 | "react/jsx-no-undef": "error",
172 | "react/jsx-pascal-case": ["warn", { "allowAllCaps": true, "ignore": [] }],
173 | "react/jsx-uses-react": "warn",
174 | "react/jsx-uses-vars": "warn",
175 | "react/no-danger-with-children": "warn",
176 | "react/no-direct-mutation-state": "warn",
177 | "react/no-is-mounted": "warn",
178 | "react/no-typos": "error",
179 | "react/react-in-jsx-scope": "error",
180 | "react/require-render-return": "error",
181 | "react/style-prop-object": "warn",
182 | "react/jsx-no-useless-fragment": "warn",
183 | "jsx-a11y/accessible-emoji": "warn",
184 | "jsx-a11y/alt-text": "warn",
185 | "jsx-a11y/anchor-has-content": "warn",
186 | "jsx-a11y/anchor-is-valid": [
187 | "warn",
188 | { "aspects": ["noHref", "invalidHref"] }
189 | ],
190 | "jsx-a11y/aria-activedescendant-has-tabindex": "warn",
191 | "jsx-a11y/aria-props": "warn",
192 | "jsx-a11y/aria-proptypes": "warn",
193 | "jsx-a11y/aria-role": "warn",
194 | "jsx-a11y/aria-unsupported-elements": "warn",
195 | "jsx-a11y/heading-has-content": "warn",
196 | "jsx-a11y/iframe-has-title": "warn",
197 | "jsx-a11y/img-redundant-alt": "warn",
198 | "jsx-a11y/no-access-key": "warn",
199 | "jsx-a11y/no-distracting-elements": "warn",
200 | "jsx-a11y/no-redundant-roles": "warn",
201 | "jsx-a11y/role-has-required-aria-props": "warn",
202 | "jsx-a11y/role-supports-aria-props": "warn",
203 | "jsx-a11y/scope": "warn",
204 | "react-hooks/rules-of-hooks": "error",
205 | "default-case": "off",
206 | "no-dupe-class-members": "off",
207 | "no-undef": "off",
208 | "@typescript-eslint/consistent-type-assertions": "warn",
209 | "no-array-constructor": "off",
210 | "@typescript-eslint/no-array-constructor": "warn",
211 | "@typescript-eslint/no-namespace": "error",
212 | "no-use-before-define": "off",
213 | "@typescript-eslint/no-use-before-define": [
214 | "warn",
215 | {
216 | "functions": false,
217 | "classes": false,
218 | "variables": false,
219 | "typedefs": false
220 | }
221 | ],
222 | "no-unused-vars": "off",
223 | "@typescript-eslint/no-unused-vars": [
224 | "warn",
225 | { "args": "none", "ignoreRestSiblings": true }
226 | ],
227 | "no-useless-constructor": "off",
228 | "@typescript-eslint/no-useless-constructor": "warn",
229 | "@typescript-eslint/no-unused-expressions": [
230 | "error",
231 | {
232 | "allowShortCircuit": true,
233 | "allowTernary": true,
234 | "allowTaggedTemplates": true
235 | }
236 | ]
237 | },
238 | "env": {
239 | "browser": true,
240 | "commonjs": true,
241 | "es6": true,
242 | "jest": true,
243 | "node": true
244 | },
245 | "settings": { "react": { "version": "detect" } },
246 | "plugins": ["import", "jsx-a11y", "react", "react-hooks"],
247 | "extends": ["../../.eslintrc"],
248 | "ignorePatterns": ["!**/*"]
249 | }
250 |
--------------------------------------------------------------------------------
/externals/todos/workspace.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "projects": {
4 | "todos": {
5 | "root": "apps/todos",
6 | "sourceRoot": "apps/todos/src",
7 | "projectType": "application",
8 | "schematics": {},
9 | "architect": {
10 | "build": {
11 | "builder": "@nrwl/web:build",
12 | "options": {
13 | "outputPath": "dist/apps/todos",
14 | "index": "apps/todos/src/index.html",
15 | "main": "apps/todos/src/main.tsx",
16 | "polyfills": "apps/todos/src/polyfills.ts",
17 | "tsConfig": "apps/todos/tsconfig.app.json",
18 | "assets": [
19 | "apps/todos/src/favicon.ico",
20 | "apps/todos/src/assets"
21 | ],
22 | "styles": [
23 | "apps/todos/src/styles.css"
24 | ],
25 | "scripts": [],
26 | "webpackConfig": "@nrwl/react/plugins/webpack"
27 | },
28 | "configurations": {
29 | "production": {
30 | "fileReplacements": [
31 | {
32 | "replace": "apps/todos/src/environments/environment.ts",
33 | "with": "apps/todos/src/environments/environment.prod.ts"
34 | }
35 | ],
36 | "optimization": true,
37 | "outputHashing": "all",
38 | "sourceMap": false,
39 | "extractCss": true,
40 | "namedChunks": false,
41 | "extractLicenses": true,
42 | "vendorChunk": false,
43 | "budgets": [
44 | {
45 | "type": "initial",
46 | "maximumWarning": "2mb",
47 | "maximumError": "5mb"
48 | }
49 | ]
50 | }
51 | }
52 | },
53 | "serve": {
54 | "builder": "@nrwl/web:dev-server",
55 | "options": {
56 | "buildTarget": "todos:build",
57 | "proxyConfig": "apps/todos/proxy.conf.json"
58 | },
59 | "configurations": {
60 | "production": {
61 | "buildTarget": "todos:build:production"
62 | }
63 | }
64 | },
65 | "lint": {
66 | "builder": "@nrwl/linter:lint",
67 | "options": {
68 | "linter": "eslint",
69 | "tsConfig": [
70 | "apps/todos/tsconfig.app.json",
71 | "apps/todos/tsconfig.spec.json"
72 | ],
73 | "exclude": [
74 | "**/node_modules/**",
75 | "!apps/todos/**/*"
76 | ]
77 | }
78 | },
79 | "test": {
80 | "builder": "@nrwl/jest:jest",
81 | "options": {
82 | "jestConfig": "apps/todos/jest.config.js",
83 | "passWithNoTests": true
84 | }
85 | },
86 | "release": {
87 | "builder": "@nrwl/workspace:run-commands",
88 | "options": {
89 | "commands": [
90 | {
91 | "command": "echo released!"
92 | }
93 | ]
94 | }
95 | }
96 | }
97 | },
98 | "todos-e2e": {
99 | "root": "apps/todos-e2e",
100 | "sourceRoot": "apps/todos-e2e/src",
101 | "projectType": "application",
102 | "architect": {
103 | "e2e": {
104 | "builder": "@nrwl/cypress:cypress",
105 | "options": {
106 | "cypressConfig": "apps/todos-e2e/cypress.json",
107 | "tsConfig": "apps/todos-e2e/tsconfig.e2e.json",
108 | "devServerTarget": "todos:serve"
109 | },
110 | "configurations": {
111 | "production": {
112 | "devServerTarget": "todos:serve:production"
113 | }
114 | }
115 | },
116 | "lint": {
117 | "builder": "@nrwl/linter:lint",
118 | "options": {
119 | "linter": "eslint",
120 | "tsConfig": [
121 | "apps/todos-e2e/tsconfig.e2e.json"
122 | ],
123 | "exclude": [
124 | "**/node_modules/**",
125 | "!apps/todos-e2e/**/*"
126 | ]
127 | }
128 | }
129 | }
130 | },
131 | "todos-api": {
132 | "root": "apps/todos-api",
133 | "sourceRoot": "apps/todos-api/src",
134 | "projectType": "application",
135 | "prefix": "api",
136 | "schematics": {},
137 | "architect": {
138 | "build": {
139 | "builder": "@nrwl/node:build",
140 | "options": {
141 | "outputPath": "dist/apps/todos-api",
142 | "main": "apps/todos-api/src/main.ts",
143 | "tsConfig": "apps/todos-api/tsconfig.app.json",
144 | "assets": [
145 | "apps/todos-api/src/assets"
146 | ]
147 | },
148 | "configurations": {
149 | "production": {
150 | "optimization": true,
151 | "extractLicenses": true,
152 | "inspect": false,
153 | "fileReplacements": [
154 | {
155 | "replace": "apps/todos-api/src/environments/environment.ts",
156 | "with": "apps/todos-api/src/environments/environment.prod.ts"
157 | }
158 | ]
159 | }
160 | }
161 | },
162 | "serve": {
163 | "builder": "@nrwl/node:execute",
164 | "options": {
165 | "buildTarget": "api:build"
166 | }
167 | },
168 | "lint": {
169 | "builder": "@nrwl/linter:lint",
170 | "options": {
171 | "linter": "eslint",
172 | "tsConfig": [
173 | "apps/todos-api/tsconfig.app.json",
174 | "apps/todos-api/tsconfig.spec.json"
175 | ],
176 | "exclude": [
177 | "**/node_modules/**",
178 | "!apps/todos-api/**/*"
179 | ]
180 | }
181 | },
182 | "test": {
183 | "builder": "@nrwl/jest:jest",
184 | "options": {
185 | "jestConfig": "apps/todos-api/jest.config.js",
186 | "passWithNoTests": true
187 | }
188 | },
189 | "release": {
190 | "builder": "@nrwl/workspace:run-commands",
191 | "options": {
192 | "commands": [
193 | {
194 | "command": "echo released!"
195 | }
196 | ]
197 | }
198 | }
199 | }
200 | },
201 | "api-interfaces": {
202 | "root": "libs/api-interfaces",
203 | "sourceRoot": "libs/api-interfaces/src",
204 | "projectType": "library",
205 | "schematics": {},
206 | "architect": {
207 | "lint": {
208 | "builder": "@nrwl/linter:lint",
209 | "options": {
210 | "linter": "eslint",
211 | "tsConfig": [
212 | "libs/api-interfaces/tsconfig.lib.json",
213 | "libs/api-interfaces/tsconfig.spec.json"
214 | ],
215 | "exclude": [
216 | "**/node_modules/**",
217 | "!libs/api-interfaces/**/*"
218 | ]
219 | }
220 | },
221 | "test": {
222 | "builder": "@nrwl/jest:jest",
223 | "options": {
224 | "jestConfig": "libs/api-interfaces/jest.config.js",
225 | "passWithNoTests": true
226 | }
227 | },
228 | "release": {
229 | "builder": "@nrwl/workspace:run-commands",
230 | "options": {
231 | "commands": [
232 | {
233 | "command": "echo released!"
234 | }
235 | ]
236 | }
237 | }
238 | }
239 | }
240 | },
241 | "cli": {
242 | "defaultCollection": "@nrwl/react"
243 | },
244 | "schematics": {
245 | "@nrwl/react": {
246 | "application": {
247 | "style": "css",
248 | "linter": "eslint",
249 | "babel": true
250 | },
251 | "component": {
252 | "style": "css"
253 | },
254 | "library": {
255 | "style": "css",
256 | "linter": "eslint"
257 | }
258 | }
259 | },
260 | "defaultProject": "todos"
261 | }
--------------------------------------------------------------------------------
/workspace.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "projects": {
4 | "todos": {
5 | "root": "apps/todos",
6 | "sourceRoot": "apps/todos/src",
7 | "projectType": "application",
8 | "schematics": {},
9 | "architect": {
10 | "build": {
11 | "builder": "@nrwl/web:build",
12 | "options": {
13 | "outputPath": "dist/apps/todos",
14 | "index": "apps/todos/src/index.html",
15 | "main": "apps/todos/src/main.tsx",
16 | "polyfills": "apps/todos/src/polyfills.ts",
17 | "tsConfig": "apps/todos/tsconfig.app.json",
18 | "assets": ["apps/todos/src/favicon.ico", "apps/todos/src/assets"],
19 | "styles": ["apps/todos/src/styles.css"],
20 | "scripts": [],
21 | "webpackConfig": "@nrwl/react/plugins/webpack"
22 | },
23 | "configurations": {
24 | "production": {
25 | "fileReplacements": [
26 | {
27 | "replace": "apps/todos/src/environments/environment.ts",
28 | "with": "apps/todos/src/environments/environment.prod.ts"
29 | }
30 | ],
31 | "optimization": true,
32 | "outputHashing": "all",
33 | "sourceMap": false,
34 | "extractCss": true,
35 | "namedChunks": false,
36 | "extractLicenses": true,
37 | "vendorChunk": false,
38 | "budgets": [
39 | {
40 | "type": "initial",
41 | "maximumWarning": "2mb",
42 | "maximumError": "5mb"
43 | }
44 | ]
45 | }
46 | }
47 | },
48 | "serve": {
49 | "builder": "@nrwl/web:dev-server",
50 | "options": {
51 | "buildTarget": "todos:build",
52 | "proxyConfig": "apps/todos/proxy.conf.json"
53 | },
54 | "configurations": {
55 | "production": {
56 | "buildTarget": "todos:build:production"
57 | }
58 | }
59 | },
60 | "lint": {
61 | "builder": "@nrwl/linter:lint",
62 | "options": {
63 | "linter": "eslint",
64 | "tsConfig": [
65 | "apps/todos/tsconfig.app.json",
66 | "apps/todos/tsconfig.spec.json"
67 | ],
68 | "exclude": ["**/node_modules/**", "!apps/todos/**/*"]
69 | }
70 | },
71 | "test": {
72 | "builder": "@nrwl/jest:jest",
73 | "options": {
74 | "jestConfig": "apps/todos/jest.config.js",
75 | "passWithNoTests": true
76 | }
77 | },
78 | "release": {
79 | "builder": "@nrwl/workspace:run-commands",
80 | "options": {
81 | "commands": [
82 | {
83 | "command": "echo released!"
84 | }
85 | ]
86 | }
87 | }
88 | }
89 | },
90 | "todos-e2e": {
91 | "root": "apps/todos-e2e",
92 | "sourceRoot": "apps/todos-e2e/src",
93 | "projectType": "application",
94 | "architect": {
95 | "e2e": {
96 | "builder": "@nrwl/cypress:cypress",
97 | "options": {
98 | "cypressConfig": "apps/todos-e2e/cypress.json",
99 | "tsConfig": "apps/todos-e2e/tsconfig.e2e.json",
100 | "devServerTarget": "todos:serve"
101 | },
102 | "configurations": {
103 | "production": {
104 | "devServerTarget": "todos:serve:production"
105 | }
106 | }
107 | },
108 | "lint": {
109 | "builder": "@nrwl/linter:lint",
110 | "options": {
111 | "linter": "eslint",
112 | "tsConfig": ["apps/todos-e2e/tsconfig.e2e.json"],
113 | "exclude": ["**/node_modules/**", "!apps/todos-e2e/**/*"]
114 | }
115 | }
116 | }
117 | },
118 | "todos-api": {
119 | "root": "apps/todos-api",
120 | "sourceRoot": "apps/todos-api/src",
121 | "projectType": "application",
122 | "prefix": "api",
123 | "schematics": {},
124 | "architect": {
125 | "build": {
126 | "builder": "@nrwl/node:build",
127 | "options": {
128 | "outputPath": "dist/apps/todos-api",
129 | "main": "apps/todos-api/src/main.ts",
130 | "tsConfig": "apps/todos-api/tsconfig.app.json",
131 | "assets": ["apps/todos-api/src/assets"]
132 | },
133 | "configurations": {
134 | "production": {
135 | "optimization": true,
136 | "extractLicenses": true,
137 | "inspect": false,
138 | "fileReplacements": [
139 | {
140 | "replace": "apps/todos-api/src/environments/environment.ts",
141 | "with": "apps/todos-api/src/environments/environment.prod.ts"
142 | }
143 | ]
144 | }
145 | }
146 | },
147 | "serve": {
148 | "builder": "@nrwl/node:execute",
149 | "options": {
150 | "buildTarget": "api:build"
151 | }
152 | },
153 | "lint": {
154 | "builder": "@nrwl/linter:lint",
155 | "options": {
156 | "linter": "eslint",
157 | "tsConfig": [
158 | "apps/todos-api/tsconfig.app.json",
159 | "apps/todos-api/tsconfig.spec.json"
160 | ],
161 | "exclude": ["**/node_modules/**", "!apps/todos-api/**/*"]
162 | }
163 | },
164 | "test": {
165 | "builder": "@nrwl/jest:jest",
166 | "options": {
167 | "jestConfig": "apps/todos-api/jest.config.js",
168 | "passWithNoTests": true
169 | }
170 | },
171 | "release": {
172 | "builder": "@nrwl/workspace:run-commands",
173 | "options": {
174 | "commands": [
175 | {
176 | "command": "echo released!"
177 | }
178 | ]
179 | }
180 | }
181 | }
182 | },
183 | "blog": {
184 | "root": "apps/blog",
185 | "sourceRoot": "apps/blog/src",
186 | "projectType": "application",
187 | "schematics": {},
188 | "architect": {
189 | "build": {
190 | "builder": "@nrwl/web:build",
191 | "options": {
192 | "outputPath": "dist/apps/blog",
193 | "index": "apps/blog/src/index.html",
194 | "main": "apps/blog/src/main.tsx",
195 | "polyfills": "apps/blog/src/polyfills.ts",
196 | "tsConfig": "apps/blog/tsconfig.app.json",
197 | "assets": ["apps/blog/src/favicon.ico", "apps/blog/src/assets"],
198 | "styles": ["apps/blog/src/styles.css"],
199 | "scripts": [],
200 | "webpackConfig": "@nrwl/react/plugins/webpack"
201 | },
202 | "configurations": {
203 | "production": {
204 | "fileReplacements": [
205 | {
206 | "replace": "apps/blog/src/environments/environment.ts",
207 | "with": "apps/blog/src/environments/environment.prod.ts"
208 | }
209 | ],
210 | "optimization": true,
211 | "outputHashing": "all",
212 | "sourceMap": false,
213 | "extractCss": true,
214 | "namedChunks": false,
215 | "extractLicenses": true,
216 | "vendorChunk": false,
217 | "budgets": [
218 | {
219 | "type": "initial",
220 | "maximumWarning": "2mb",
221 | "maximumError": "5mb"
222 | }
223 | ]
224 | }
225 | }
226 | },
227 | "serve": {
228 | "builder": "@nrwl/web:dev-server",
229 | "options": {
230 | "buildTarget": "blog:build",
231 | "proxyConfig": "apps/blog/proxy.conf.json"
232 | },
233 | "configurations": {
234 | "production": {
235 | "buildTarget": "blog:build:production"
236 | }
237 | }
238 | },
239 | "lint": {
240 | "builder": "@nrwl/linter:lint",
241 | "options": {
242 | "linter": "eslint",
243 | "tsConfig": [
244 | "apps/blog/tsconfig.app.json",
245 | "apps/blog/tsconfig.spec.json"
246 | ],
247 | "exclude": ["**/node_modules/**", "!apps/blog/**/*"]
248 | }
249 | },
250 | "test": {
251 | "builder": "@nrwl/jest:jest",
252 | "options": {
253 | "jestConfig": "apps/blog/jest.config.js",
254 | "passWithNoTests": true
255 | }
256 | },
257 | "release": {
258 | "builder": "@nrwl/workspace:run-commands",
259 | "options": {
260 | "commands": [
261 | {
262 | "command": "echo released!"
263 | }
264 | ]
265 | }
266 | }
267 | }
268 | },
269 | "blog-api": {
270 | "root": "apps/blog-api",
271 | "sourceRoot": "apps/blog-api/src",
272 | "projectType": "application",
273 | "prefix": "api",
274 | "schematics": {},
275 | "architect": {
276 | "build": {
277 | "builder": "@nrwl/node:build",
278 | "options": {
279 | "outputPath": "dist/apps/blog-api",
280 | "main": "apps/blog-api/src/main.ts",
281 | "tsConfig": "apps/blog-api/tsconfig.app.json",
282 | "assets": ["apps/blog-api/src/assets"]
283 | },
284 | "configurations": {
285 | "production": {
286 | "optimization": true,
287 | "extractLicenses": true,
288 | "inspect": false,
289 | "fileReplacements": [
290 | {
291 | "replace": "apps/blog-api/src/environments/environment.ts",
292 | "with": "apps/blog-api/src/environments/environment.prod.ts"
293 | }
294 | ]
295 | }
296 | }
297 | },
298 | "serve": {
299 | "builder": "@nrwl/node:execute",
300 | "options": {
301 | "buildTarget": "api:build"
302 | }
303 | },
304 | "lint": {
305 | "builder": "@nrwl/linter:lint",
306 | "options": {
307 | "linter": "eslint",
308 | "tsConfig": [
309 | "apps/blog-api/tsconfig.app.json",
310 | "apps/blog-api/tsconfig.spec.json"
311 | ],
312 | "exclude": ["**/node_modules/**", "!apps/blog-api/**/*"]
313 | }
314 | },
315 | "test": {
316 | "builder": "@nrwl/jest:jest",
317 | "options": {
318 | "jestConfig": "apps/blog-api/jest.config.js",
319 | "passWithNoTests": true
320 | }
321 | },
322 | "release": {
323 | "builder": "@nrwl/workspace:run-commands",
324 | "options": {
325 | "commands": [
326 | {
327 | "command": "echo released!"
328 | }
329 | ]
330 | }
331 | }
332 | }
333 | },
334 | "api-interfaces": {
335 | "root": "libs/api-interfaces",
336 | "sourceRoot": "libs/api-interfaces/src",
337 | "projectType": "library",
338 | "schematics": {},
339 | "architect": {
340 | "lint": {
341 | "builder": "@nrwl/linter:lint",
342 | "options": {
343 | "linter": "eslint",
344 | "tsConfig": [
345 | "libs/api-interfaces/tsconfig.lib.json",
346 | "libs/api-interfaces/tsconfig.spec.json"
347 | ],
348 | "exclude": ["**/node_modules/**", "!libs/api-interfaces/**/*"]
349 | }
350 | },
351 | "test": {
352 | "builder": "@nrwl/jest:jest",
353 | "options": {
354 | "jestConfig": "libs/api-interfaces/jest.config.js",
355 | "passWithNoTests": true
356 | }
357 | },
358 | "release": {
359 | "builder": "@nrwl/workspace:run-commands",
360 | "options": {
361 | "commands": [
362 | {
363 | "command": "echo released!"
364 | }
365 | ]
366 | }
367 | }
368 | }
369 | }
370 | },
371 | "cli": {
372 | "defaultCollection": "@nrwl/react"
373 | },
374 | "schematics": {
375 | "@nrwl/react": {
376 | "application": {
377 | "style": "css",
378 | "linter": "eslint",
379 | "babel": true
380 | },
381 | "component": {
382 | "style": "css"
383 | },
384 | "library": {
385 | "style": "css",
386 | "linter": "eslint"
387 | }
388 | }
389 | },
390 | "defaultProject": "todos"
391 | }
392 |
--------------------------------------------------------------------------------