mirror of
https://github.com/cypress-io/cypress.git
synced 2026-05-06 23:10:22 -05:00
feat: add gulp makePackage, begin to scaffold data-context (#18186)
* add gulp makePackage, begin to scaffold data-context * Don't type error on unused locals
This commit is contained in:
+2
-1
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"prefix": "/* eslint-disable padding-line-between-statements */",
|
||||
"paths": [
|
||||
"packages/graphql/src/**/*"
|
||||
"packages/graphql/src/**/*",
|
||||
"packages/data-context/src/**/*"
|
||||
],
|
||||
"ignore": [
|
||||
"packages/graphql/src/stitching",
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
"common-tags": "1.8.0",
|
||||
"conventional-recommended-bump": "6.1.0",
|
||||
"debug": "4.3.2",
|
||||
"dedent": "^0.7.0",
|
||||
"del": "3.0.0",
|
||||
"detect-port": "^1.3.0",
|
||||
"electron-builder": "22.9.1",
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## @packages/data-context
|
||||
|
||||
Centralized data access for the Cypress application
|
||||
@@ -0,0 +1,5 @@
|
||||
if (process.env.CYPRESS_INTERNAL_ENV !== 'production') {
|
||||
require('@packages/ts/register')
|
||||
}
|
||||
|
||||
module.exports = require('./src')
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "@packages/data-context",
|
||||
"version": "0.0.0-development",
|
||||
"description": "Centralized data access for the Cypress application",
|
||||
"main": "index.js",
|
||||
"browser": "src/index.ts",
|
||||
"scripts": {
|
||||
"build-prod": "tsc || echo 'built, with errors'",
|
||||
"check-ts": "tsc --noEmit",
|
||||
"clean-deps": "rm -rf node_modules",
|
||||
"clean": "rm -f ./src/*.js ./src/**/*.js ./src/**/**/*.js ./test/**/*.js || echo 'cleaned'",
|
||||
"test-unit": "mocha -r @packages/ts/register test/unit/**/*.spec.ts --config ./test/.mocharc.js --exit",
|
||||
"test-integration": "mocha -r @packages/ts/register test/integration/**/*.spec.ts --config ./test/.mocharc.js --exit"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@packages/ts": "0.0.0-development",
|
||||
"mocha": "7.0.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import type { DataContext } from '.'
|
||||
|
||||
export class DataActions {
|
||||
constructor (private ctx: DataContext) {}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { DataActions } from './DataActions'
|
||||
import { AppDataSource } from './sources/AppDataSource'
|
||||
import { ProjectDataSource } from './sources/ProjectDataSource'
|
||||
import { cached } from './util/cached'
|
||||
|
||||
interface DataContextConfig {
|
||||
cache: unknown
|
||||
}
|
||||
|
||||
export class DataContext {
|
||||
constructor (private config: DataContextConfig) {}
|
||||
|
||||
/**
|
||||
* All mutations (update / delete / create), fs writes, etc.
|
||||
* should run through this namespace. Everything else should be a "getter"
|
||||
*/
|
||||
@cached
|
||||
get actions () {
|
||||
return new DataActions(this)
|
||||
}
|
||||
|
||||
@cached
|
||||
get app () {
|
||||
return new AppDataSource(this)
|
||||
}
|
||||
|
||||
@cached
|
||||
get project () {
|
||||
return new ProjectDataSource(this)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import type { DataContext } from '..'
|
||||
|
||||
export class ProjectActions {
|
||||
constructor (private ctx: DataContext) {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/* eslint-disable padding-line-between-statements */
|
||||
// created by autobarrel, do not modify directly
|
||||
|
||||
export * from './ProjectActions'
|
||||
@@ -0,0 +1 @@
|
||||
export * from './DataContext'
|
||||
@@ -0,0 +1,5 @@
|
||||
import type { DataContext } from '..'
|
||||
|
||||
export class AppDataSource {
|
||||
constructor (private ctx: DataContext) {}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import type { DataContext } from '..'
|
||||
|
||||
export class ProjectDataSource {
|
||||
constructor (private ctx: DataContext) {}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/* eslint-disable padding-line-between-statements */
|
||||
// created by autobarrel, do not modify directly
|
||||
|
||||
export * from './AppDataSource'
|
||||
export * from './ProjectDataSource'
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* A cached decorator means the value is lazily evaluated once and
|
||||
* the result is cached on the class instance.
|
||||
*/
|
||||
export const cached = <T>(
|
||||
target: T,
|
||||
key: PropertyKey,
|
||||
descriptor: PropertyDescriptor,
|
||||
): void => {
|
||||
if (!descriptor) {
|
||||
descriptor = Object.getOwnPropertyDescriptor(
|
||||
target,
|
||||
key,
|
||||
) as PropertyDescriptor
|
||||
}
|
||||
|
||||
const originalMethod = descriptor.get
|
||||
const isStatic = Object.getPrototypeOf(target) === Function.prototype
|
||||
|
||||
if (isStatic) {
|
||||
throw new Error(`Don't use @cached decorator on static properties`)
|
||||
}
|
||||
|
||||
if (!originalMethod) {
|
||||
throw new Error('@cached can only decorate getters!')
|
||||
} else if (!descriptor.configurable) {
|
||||
throw new Error('@cached target must be configurable')
|
||||
} else {
|
||||
descriptor.get = function () {
|
||||
// eslint-disable-next-line
|
||||
const value = originalMethod.apply(this, arguments as any)
|
||||
const newDescriptor: PropertyDescriptor = {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
value,
|
||||
}
|
||||
|
||||
Object.defineProperty(this, key, newDescriptor)
|
||||
|
||||
return value
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/* eslint-disable padding-line-between-statements */
|
||||
// created by autobarrel, do not modify directly
|
||||
|
||||
export * from './cached'
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = {}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { expect } from 'chai'
|
||||
|
||||
describe('@packages/data-context unit', () => {
|
||||
it('has a sample test', () => {
|
||||
expect(1).to.eq(1)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,7 @@
|
||||
import { expect } from 'chai'
|
||||
|
||||
describe('@packages/data-context unit', () => {
|
||||
it('has a sample test', () => {
|
||||
expect(1).to.eq(1)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "../ts/tsconfig.json",
|
||||
"include": ["src"],
|
||||
"exclude": [
|
||||
"test",
|
||||
"script"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"importHelpers": true,
|
||||
"strict": true,
|
||||
"allowJs": false,
|
||||
"noImplicitAny": true,
|
||||
"resolveJsonModule": true,
|
||||
"experimentalDecorators": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"importsNotUsedAsValues": "error",
|
||||
"types": []
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import { checkTs } from './tasks/gulpTsc'
|
||||
import { viteApp, viteCleanApp, viteCleanLaunchpad, viteLaunchpad } from './tasks/gulpVite'
|
||||
import { makePathMap } from './utils/makePathMap'
|
||||
import { setGulpGlobal } from './gulpConstants'
|
||||
import { makePackage } from './tasks/gulpMakePackage'
|
||||
|
||||
gulp.task(
|
||||
'dev',
|
||||
@@ -94,6 +95,7 @@ gulp.task(
|
||||
// 'debug', // Tim: TODO
|
||||
// )
|
||||
|
||||
gulp.task(makePackage)
|
||||
gulp.task(checkTs)
|
||||
gulp.task(syncRemoteGraphQL)
|
||||
gulp.task(printUrqlSchema)
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
import inquirer from 'inquirer'
|
||||
import path from 'path'
|
||||
import fs from 'fs-extra'
|
||||
import dedent from 'dedent'
|
||||
|
||||
import { monorepoPaths } from '../monorepoPaths'
|
||||
|
||||
export async function makePackage () {
|
||||
const results = await inquirer.prompt<{
|
||||
packageName: string
|
||||
target: 'server'
|
||||
description: string
|
||||
scaffoldTests: boolean
|
||||
}>([
|
||||
{
|
||||
name: 'packageName',
|
||||
type: 'input',
|
||||
message: 'What is the package name?',
|
||||
validate: (val) => /[A-z\-]+/.test(val),
|
||||
},
|
||||
{
|
||||
name: 'target',
|
||||
type: 'list',
|
||||
choices: ['server'], // TODO: 'frontend'
|
||||
message: 'Where is the package targeting',
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
type: 'input',
|
||||
message: 'A brief description for the README.md',
|
||||
},
|
||||
{
|
||||
name: 'scaffoldTests',
|
||||
type: 'confirm',
|
||||
message: 'Should we scaffold tests?',
|
||||
},
|
||||
])
|
||||
|
||||
const newDir = path.join(monorepoPaths.pkgDir, results.packageName)
|
||||
|
||||
await fs.ensureDir(path.join(newDir, 'src'))
|
||||
|
||||
if (results.scaffoldTests) {
|
||||
await Promise.all([
|
||||
fs.ensureDir(path.join(newDir, 'test/unit')),
|
||||
fs.ensureDir(path.join(newDir, 'test/integration')),
|
||||
])
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
fs.writeFile(
|
||||
path.join(newDir, 'package.json'),
|
||||
JSON.stringify(
|
||||
{
|
||||
name: `@packages/${results.packageName}`,
|
||||
version: '0.0.0-development',
|
||||
description: results.description,
|
||||
'main': 'index.js',
|
||||
'browser': 'src/index.ts',
|
||||
scripts: {
|
||||
'build-prod': 'tsc || echo \'built, with errors\'',
|
||||
'check-ts': 'tsc --noEmit',
|
||||
'clean-deps': 'rm -rf node_modules',
|
||||
'clean': 'rm -f ./src/*.js ./src/**/*.js ./src/**/**/*.js ./test/**/*.js || echo \'cleaned\'',
|
||||
...(results.scaffoldTests ? {
|
||||
'test-unit': 'mocha -r @packages/ts/register test/unit/**/*.spec.ts --config ./test/.mocharc.js --exit',
|
||||
'test-integration': 'mocha -r @packages/ts/register test/integration/**/*.spec.ts --config ./test/.mocharc.js --exit',
|
||||
} : {}),
|
||||
},
|
||||
dependencies: {
|
||||
'tslib': '2.3.0',
|
||||
},
|
||||
devDependencies: results.scaffoldTests ? {
|
||||
'mocha': '7.0.1',
|
||||
'chai': '4.2.0',
|
||||
'@packages/ts': '0.0.0-development',
|
||||
} : {
|
||||
'@packages/ts': '0.0.0-development',
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
),
|
||||
fs.writeFile(
|
||||
path.join(newDir, 'tsconfig.json'),
|
||||
JSON.stringify(
|
||||
{
|
||||
'extends': '../ts/tsconfig.json',
|
||||
'include': ['src'],
|
||||
'exclude': [
|
||||
'test',
|
||||
'script',
|
||||
],
|
||||
'compilerOptions': {
|
||||
'importHelpers': true,
|
||||
'strict': true,
|
||||
'allowJs': false,
|
||||
'rootDir': 'src',
|
||||
'outDir': 'dist',
|
||||
'noImplicitAny': true,
|
||||
'resolveJsonModule': true,
|
||||
'experimentalDecorators': true,
|
||||
'noUncheckedIndexedAccess': true,
|
||||
'importsNotUsedAsValues': 'error',
|
||||
'types': [],
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
),
|
||||
fs.writeFile(
|
||||
path.join(newDir, 'README.md'),
|
||||
`## @packages/${results.packageName}\n\n${results.description}`,
|
||||
),
|
||||
])
|
||||
|
||||
await Promise.all([
|
||||
fs.writeFile(
|
||||
path.join(newDir, 'index.js'),
|
||||
dedent`
|
||||
if (process.env.CYPRESS_INTERNAL_ENV !== 'production') {
|
||||
require('@packages/ts/register')
|
||||
}
|
||||
|
||||
module.exports = require('./src')
|
||||
`,
|
||||
),
|
||||
fs.writeFile(
|
||||
path.join(newDir, 'src/index.ts'),
|
||||
`export * from './${results.packageName}'`,
|
||||
),
|
||||
fs.writeFile(
|
||||
path.join(newDir, `src/${results.packageName}.ts`),
|
||||
`export const stubPackage = {}`,
|
||||
),
|
||||
...(results.scaffoldTests ? [
|
||||
fs.writeFile(
|
||||
path.join(newDir, `test/.mocharc.js`),
|
||||
'module.exports = {}\n',
|
||||
),
|
||||
fs.writeFile(
|
||||
path.join(newDir, `test/unit/${results.packageName}.spec.ts`),
|
||||
dedent`
|
||||
import { expect } from 'chai'
|
||||
|
||||
describe('@packages/${results.packageName} unit', () => {
|
||||
it('has a sample test', () => {
|
||||
expect(1).to.eq(1)
|
||||
})
|
||||
})
|
||||
`,
|
||||
),
|
||||
fs.writeFile(
|
||||
path.join(newDir, `test/integration/${results.packageName}.spec.ts`),
|
||||
dedent`
|
||||
import { expect } from 'chai'
|
||||
|
||||
describe('@packages/${results.packageName} unit', () => {
|
||||
it('has a sample test', () => {
|
||||
expect(1).to.eq(1)
|
||||
})
|
||||
})
|
||||
`,
|
||||
),
|
||||
] : []),
|
||||
])
|
||||
}
|
||||
@@ -36,6 +36,7 @@ export async function nexusTypegen (cfg: NexusTypegenCfg) {
|
||||
env: {
|
||||
...process.env,
|
||||
CYPRESS_INTERNAL_NEXUS_CODEGEN: 'true',
|
||||
TS_NODE_CACHE: 'false',
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user