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:
Tim Griesser
2021-09-22 09:18:44 -04:00
committed by GitHub
parent 3b8828907d
commit bad700b593
22 changed files with 346 additions and 1 deletions
+2 -1
View File
@@ -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",
+1
View File
@@ -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",
+3
View File
@@ -0,0 +1,3 @@
## @packages/data-context
Centralized data access for the Cypress application
+5
View File
@@ -0,0 +1,5 @@
if (process.env.CYPRESS_INTERNAL_ENV !== 'production') {
require('@packages/ts/register')
}
module.exports = require('./src')
+20
View File
@@ -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"
}
}
+5
View File
@@ -0,0 +1,5 @@
import type { DataContext } from '.'
export class DataActions {
constructor (private ctx: DataContext) {}
}
+31
View File
@@ -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'
+1
View File
@@ -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'
+43
View File
@@ -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
}
}
}
+4
View File
@@ -0,0 +1,4 @@
/* eslint-disable padding-line-between-statements */
// created by autobarrel, do not modify directly
export * from './cached'
+1
View File
@@ -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)
})
})
+20
View File
@@ -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": []
}
}
+2
View File
@@ -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)
+169
View File
@@ -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)
})
})
`,
),
] : []),
])
}
+1
View File
@@ -36,6 +36,7 @@ export async function nexusTypegen (cfg: NexusTypegenCfg) {
env: {
...process.env,
CYPRESS_INTERNAL_NEXUS_CODEGEN: 'true',
TS_NODE_CACHE: 'false',
},
})