mirror of
https://github.com/LukeHagar/form.git
synced 2025-12-06 04:19:43 +00:00
Update build tooling (#401)
* chore: inital work to migrate to Query's alpha package setup * chore: update deps * chore: fix build issues * chore: disable no-children-prop rule
This commit is contained in:
56
.eslintrc
56
.eslintrc
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"root": true,
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint", "import"],
|
||||
"extends": [
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:import/typescript",
|
||||
"react-app",
|
||||
"prettier"
|
||||
],
|
||||
"env": {
|
||||
"es6": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"project": "./tsconfig.base.json",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"settings": {
|
||||
"import/parsers": {
|
||||
"@typescript-eslint/parser": [".ts", ".tsx"]
|
||||
},
|
||||
"import/resolver": {
|
||||
"node": true,
|
||||
"typescript": {
|
||||
"project": "packages/*/tsconfig.json"
|
||||
}
|
||||
},
|
||||
"react": {
|
||||
"version": "detect"
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"react/jsx-key": ["error", { "checkFragmentShorthand": true }],
|
||||
"@typescript-eslint/ban-types": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/consistent-type-imports": "error",
|
||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||
"@typescript-eslint/no-empty-interface": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"@typescript-eslint/no-unnecessary-condition": "error",
|
||||
"@typescript-eslint/no-inferrable-types": [
|
||||
"error",
|
||||
{
|
||||
"ignoreParameters": true
|
||||
}
|
||||
],
|
||||
"no-shadow": "error",
|
||||
"import/no-cycle": "error",
|
||||
"import/no-unresolved": ["error", { "ignore": ["^@tanstack\/"] }],
|
||||
"import/no-unused-modules": ["off", { "unusedExports": true }],
|
||||
"no-redeclare": "off",
|
||||
"react-hooks/exhaustive-deps": "error"
|
||||
}
|
||||
}
|
||||
68
.eslintrc.cjs
Normal file
68
.eslintrc.cjs
Normal file
@@ -0,0 +1,68 @@
|
||||
// @ts-check
|
||||
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
const config = {
|
||||
root: true,
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint', 'compat', 'import'],
|
||||
extends: [
|
||||
'plugin:@typescript-eslint/eslint-recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:compat/recommended',
|
||||
'plugin:import/recommended',
|
||||
'plugin:import/typescript',
|
||||
'prettier',
|
||||
],
|
||||
env: {
|
||||
browser: true,
|
||||
es2020: true,
|
||||
},
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json',
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 2020,
|
||||
},
|
||||
settings: {
|
||||
'import/parsers': {
|
||||
'@typescript-eslint/parser': ['.ts', '.tsx'],
|
||||
},
|
||||
'import/resolver': {
|
||||
typescript: true,
|
||||
},
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/ban-types': 'off',
|
||||
'@typescript-eslint/ban-ts-comment': 'off',
|
||||
'@typescript-eslint/consistent-type-imports': 'error',
|
||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||
'@typescript-eslint/no-empty-interface': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/no-unnecessary-condition': 'error',
|
||||
'@typescript-eslint/no-inferrable-types': [
|
||||
'error',
|
||||
{
|
||||
ignoreParameters: true,
|
||||
},
|
||||
],
|
||||
'no-shadow': 'error',
|
||||
'import/no-cycle': 'error',
|
||||
'import/no-unresolved': ['error', { ignore: ['^@tanstack/'] }],
|
||||
'import/no-unused-modules': ['off', { unusedExports: true }],
|
||||
'no-redeclare': 'off',
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['**/*.test.{ts,tsx}'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-unnecessary-condition': 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
module.exports = config
|
||||
@@ -1,2 +1,6 @@
|
||||
/packages/svelte-form/.svelte-kit
|
||||
/packages/*/build
|
||||
**/.next
|
||||
**/.svelte-kit
|
||||
**/build
|
||||
**/coverage
|
||||
**/dist
|
||||
**/codemods/**/__testfixtures__
|
||||
|
||||
67
nx.json
67
nx.json
@@ -1,16 +1,20 @@
|
||||
{
|
||||
"$schema": "./node_modules/nx/schemas/nx-schema.json",
|
||||
"affected": {
|
||||
"defaultBase": "main"
|
||||
},
|
||||
"tasksRunnerOptions": {
|
||||
"default": {
|
||||
"runner": "@nrwl/nx-cloud",
|
||||
"runner": "nx-cloud",
|
||||
"options": {
|
||||
"cacheableOperations": [
|
||||
"test:lib",
|
||||
"test:eslint",
|
||||
"test:types",
|
||||
"build:types",
|
||||
"build",
|
||||
"rollup"
|
||||
"test:build",
|
||||
"build"
|
||||
],
|
||||
"parallel": 5,
|
||||
"accessToken": "OTI3Y2U3NGQtYzQ3ZC00ZmE3LWJjZWQtYTYxOTEyNmNiN2IyfHJlYWQtb25seQ=="
|
||||
}
|
||||
}
|
||||
@@ -22,56 +26,45 @@
|
||||
}
|
||||
},
|
||||
"namedInputs": {
|
||||
"globalBuildAffectingConfig": [
|
||||
"{workspaceRoot}/babel.config.js",
|
||||
"{workspaceRoot}/rollup.config.js",
|
||||
"{workspaceRoot}/rollup.config.ts",
|
||||
"{workspaceRoot}/tsconfig.json",
|
||||
"{workspaceRoot}/tsconfig.base.json"
|
||||
],
|
||||
"globalNonBuildAffectingConfig": [
|
||||
"{workspaceRoot}/.eslintrc",
|
||||
"{workspaceRoot}/jest-preset.js"
|
||||
"sharedGlobals": [
|
||||
"{workspaceRoot}/.browserslistrc",
|
||||
"{workspaceRoot}/.eslintrc.cjs",
|
||||
"{workspaceRoot}/babel.config.cjs",
|
||||
"{workspaceRoot}/package.json",
|
||||
"{workspaceRoot}/scripts/getRollupConfig.js",
|
||||
"{workspaceRoot}/tsconfig.json"
|
||||
],
|
||||
"default": [
|
||||
"sharedGlobals",
|
||||
"{projectRoot}/**/*",
|
||||
"globalBuildAffectingConfig",
|
||||
"globalNonBuildAffectingConfig",
|
||||
"!{projectRoot}/**/*.md",
|
||||
"!{projectRoot}/**/build/**/*"
|
||||
"!{projectRoot}/**/*.md"
|
||||
],
|
||||
"public": [
|
||||
"default",
|
||||
"!{workspaceRoot}/.eslintrc",
|
||||
"!{workspaceRoot}/jest-preset.js",
|
||||
"!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
|
||||
"!{projectRoot}/.eslintrc",
|
||||
"!{projectRoot}/jest.config.js"
|
||||
"{projectRoot}/build",
|
||||
"{projectRoot}/dist",
|
||||
"!{projectRoot}/.eslintrc.cjs",
|
||||
"!{projectRoot}/tsconfig.eslint.json"
|
||||
]
|
||||
},
|
||||
"targetDefaults": {
|
||||
"test:lib": {
|
||||
"outputs": ["{projectRoot}/coverage"],
|
||||
"inputs": ["default", "^public"]
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": ["default", "^public"],
|
||||
"outputs": ["{projectRoot}/coverage"]
|
||||
},
|
||||
"test:eslint": {
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": ["default", "^public"]
|
||||
},
|
||||
"test:types": {
|
||||
"outputs": [
|
||||
"{projectRoot}/build/**/*.d.ts",
|
||||
"{projectRoot}/build/.tsbuildinfo"
|
||||
],
|
||||
"inputs": ["default", "^public"],
|
||||
"dependsOn": ["^test:types"]
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": ["default", "^public"]
|
||||
},
|
||||
"build:types": {
|
||||
"outputs": [
|
||||
"{projectRoot}/build/**/*.d.ts",
|
||||
"{projectRoot}/build/.tsbuildinfo"
|
||||
],
|
||||
"build": {
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": ["default", "^public"],
|
||||
"dependsOn": ["^build:types"]
|
||||
"outputs": ["{projectRoot}/build", "{projectRoot}/dist"]
|
||||
},
|
||||
"test:build": {
|
||||
"dependsOn": ["build"],
|
||||
|
||||
129
package.json
129
package.json
@@ -2,52 +2,48 @@
|
||||
"name": "form",
|
||||
"private": true,
|
||||
"repository": "https://github.com/tanstack/form.git",
|
||||
"packageManager": "pnpm@8.5.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"nx-reset": "nx reset",
|
||||
"clean": "pnpm --filter \"./packages/**\" run clean",
|
||||
"preinstall": "node -e \"if(process.env.CI == 'true') {console.log('Skipping preinstall...'); process.exit(1)}\" || npx -y only-allow pnpm",
|
||||
"install:csb": "pnpm --filter \"./packages/**\" --prefer-offline install --no-frozen-lockfile",
|
||||
"install:csb": "corepack enable && pnpm install --frozen-lockfile",
|
||||
"test": "pnpm run test:ci",
|
||||
"test:ci": "nx affected --targets=test:lib,test:types,test:eslint,test:format --parallel=5",
|
||||
"test:react:17": "nx affected --target=test:lib --parallel=5",
|
||||
"test:eslint": "nx affected --target=test:eslint --parallel=5",
|
||||
"test:ci": "nx run-many --exclude=examples/** --targets=test:format,test:eslint,test:lib,test:types,build,test:build",
|
||||
"test:eslint": "nx affected --target=test:eslint",
|
||||
"test:format": "pnpm run prettier --check",
|
||||
"test:lib": "nx affected --target=test:lib --parallel=5",
|
||||
"test:lib": "nx affected --target=test:lib",
|
||||
"test:lib:dev": "pnpm --filter \"./packages/**\" run test:lib:dev",
|
||||
"test:build": "nx run-many --target=test:build --projects=root",
|
||||
"test:types": "nx affected --target=test:types --parallel=5",
|
||||
"build": "nx run-many --target=build --projects=root",
|
||||
"build:types": "nx affected --target=build:types --parallel=5",
|
||||
"watch": "concurrently --kill-others \"rollup --config rollup.config.js -w\" \"pnpm run build:types --watch\"",
|
||||
"test:build": "nx affected --target=test:build",
|
||||
"test:types": "nx affected --target=test:types",
|
||||
"build": "nx affected --target=build",
|
||||
"build:all": "nx run-many --exclude=examples/** --target=build",
|
||||
"watch": "pnpm run build:all && nx watch --all -- pnpm run build:all",
|
||||
"dev": "pnpm run watch",
|
||||
"prettier": "prettier --plugin-search-dir . \"{packages,examples}/**/src/**/*.{md,js,jsx,ts,tsx,json,vue,svelte}\"",
|
||||
"prettier": "prettier --plugin-search-dir . \"{packages,examples,scripts}/**/*.{md,js,jsx,cjs,ts,tsx,json,vue,svelte}\"",
|
||||
"prettier:write": "pnpm run prettier --write",
|
||||
"cipublish": "ts-node scripts/publish.ts"
|
||||
"cipublish": "node scripts/publish.js"
|
||||
},
|
||||
"nx": {
|
||||
"includedScripts": [
|
||||
"test:format",
|
||||
"test:build"
|
||||
"test:format"
|
||||
]
|
||||
},
|
||||
"namespace": "@tanstack",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.17.9",
|
||||
"@babel/preset-env": "^7.16.11",
|
||||
"@babel/preset-react": "^7.16.7",
|
||||
"@babel/preset-typescript": "^7.16.7",
|
||||
"@commitlint/parse": "^16.2.1",
|
||||
"@faker-js/faker": "^6.3.1",
|
||||
"@nrwl/nx-cloud": "latest",
|
||||
"@rollup/plugin-babel": "^5.3.1",
|
||||
"@rollup/plugin-commonjs": "22.0.1",
|
||||
"@rollup/plugin-node-resolve": "^13.2.1",
|
||||
"@rollup/plugin-replace": "^4.0.0",
|
||||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@testing-library/react": "^13.0.0",
|
||||
"@testing-library/react-17": "npm:@testing-library/react@12.1.4",
|
||||
"@testing-library/react-hooks": "^7.0.2",
|
||||
"@testing-library/user-event": "14.4.3",
|
||||
"@babel/core": "^7.21.8",
|
||||
"@babel/preset-env": "^7.21.5",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@babel/preset-typescript": "^7.21.5",
|
||||
"@commitlint/parse": "^17.6.5",
|
||||
"@rollup/plugin-babel": "^6.0.3",
|
||||
"@rollup/plugin-commonjs": "^25.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.2",
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@testing-library/user-event": "^14.4.3",
|
||||
"@types/jest": "^26.0.4",
|
||||
"@types/luxon": "^2.3.1",
|
||||
"@types/node": "^17.0.25",
|
||||
@@ -57,67 +53,56 @@
|
||||
"@types/testing-library__jest-dom": "^5.14.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.41.0",
|
||||
"@typescript-eslint/parser": "^5.41.0",
|
||||
"@vitest/coverage-istanbul": "^0.27.1",
|
||||
"axios": "^0.26.1",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-jest": "^27.5.1",
|
||||
"babel-plugin-transform-async-to-promises": "^0.8.18",
|
||||
"babel-preset-solid": "^1.5.4",
|
||||
"bundlewatch": "^0.3.2",
|
||||
"chalk": "^4.1.2",
|
||||
"concurrently": "^7.1.0",
|
||||
"concurrently": "^8.2.0",
|
||||
"cpy-cli": "^5.0.0",
|
||||
"current-git-branch": "^1.1.0",
|
||||
"eslint": "8.34.0",
|
||||
"eslint-config-prettier": "^8.6.0",
|
||||
"eslint-config-react-app": "^7.0.1",
|
||||
"eslint-config-standard": "^17.0.0",
|
||||
"eslint-config-standard-react": "^13.0.0",
|
||||
"eslint-import-resolver-typescript": "^3.5.3",
|
||||
"eslint-plugin-flowtype": "8.0.3",
|
||||
"eslint": "^8.34.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-import-resolver-typescript": "^3.5.5",
|
||||
"eslint-plugin-compat": "^4.1.4",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-react": "7.32.2",
|
||||
"eslint-plugin-react": "^7.32.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-standard": "^5.0.0",
|
||||
"git-log-parser": "^1.2.0",
|
||||
"jest": "^27.5.1",
|
||||
"jsdom": "^22.0.0",
|
||||
"jsonfile": "^6.1.0",
|
||||
"luxon": "^2.3.2",
|
||||
"nx": "15.9.2",
|
||||
"nx-cloud": "^16.0.2",
|
||||
"prettier": "^2.6.2",
|
||||
"prettier-plugin-svelte": "^2.9.0",
|
||||
"luxon": "^3.3.0",
|
||||
"nx": "^16.4.2",
|
||||
"nx-cloud": "^16.0.5",
|
||||
"prettier": "^2.8.8",
|
||||
"prettier-plugin-svelte": "^2.10.0",
|
||||
"publint": "^0.1.15",
|
||||
"react": "^18.2.0",
|
||||
"react-17": "npm:react@^17.0.2",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-dom-17": "npm:react-dom@^17.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.70.2",
|
||||
"rollup-plugin-preserve-directives": "0.1.0",
|
||||
"rimraf": "^5.0.1",
|
||||
"rollup": "^3.23.0",
|
||||
"rollup-plugin-node-externals": "^6.1.0",
|
||||
"rollup-plugin-preserve-directives": "^0.2.0",
|
||||
"rollup-plugin-size": "^0.2.2",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"rollup-plugin-visualizer": "^5.6.0",
|
||||
"rollup-plugin-visualizer": "^5.9.0",
|
||||
"rollup-preset-solid": "^2.0.1",
|
||||
"semver": "^7.3.8",
|
||||
"solid-js": "^1.5.7",
|
||||
"solid-testing-library": "^0.3.0",
|
||||
"solid-js": "^1.6.13",
|
||||
"stream-to-array": "^2.3.0",
|
||||
"ts-jest": "^27.1.1",
|
||||
"ts-node": "^10.7.0",
|
||||
"tsup": "^7.0.0",
|
||||
"type-fest": "^3.11.0",
|
||||
"typescript": "^5.0.4",
|
||||
"vue": "^3.2.33"
|
||||
"vitest": "^0.27.1",
|
||||
"vue": "^3.2.47"
|
||||
},
|
||||
"bundlewatch": {
|
||||
"files": [
|
||||
{
|
||||
"path": "packages/*/build/umd/*.production.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@tanstack/store": "^0.0.1-beta.84",
|
||||
"fs-extra": "^11.1.1",
|
||||
"rollup-plugin-dts": "^5.3.0"
|
||||
"pnpm": {
|
||||
"patchedDependencies": {
|
||||
"@types/testing-library__jest-dom@5.14.5": "patches/@types__testing-library__jest-dom@5.14.5.patch"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"parserOptions": {
|
||||
"project": "./tsconfig.json",
|
||||
"sourceType": "module"
|
||||
}
|
||||
}
|
||||
11
packages/form-core/.eslintrc.cjs
Normal file
11
packages/form-core/.eslintrc.cjs
Normal file
@@ -0,0 +1,11 @@
|
||||
// @ts-check
|
||||
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
const config = {
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.eslint.json',
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = config
|
||||
@@ -1,4 +0,0 @@
|
||||
export default {
|
||||
displayName: 'form-core',
|
||||
preset: '../../jest-preset.js',
|
||||
}
|
||||
@@ -10,21 +10,34 @@
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
},
|
||||
"types": "build/types/index.d.ts",
|
||||
"main": "build/cjs/index.js",
|
||||
"module": "build/esm/index.js",
|
||||
"type": "module",
|
||||
"types": "build/lib/index.d.ts",
|
||||
"main": "build/lib/index.legacy.cjs",
|
||||
"module": "build/lib/index.legacy.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./build/lib/index.d.ts",
|
||||
"import": "./build/lib/index.js",
|
||||
"require": "./build/lib/index.cjs",
|
||||
"default": "./build/lib/index.cjs"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"files": [
|
||||
"build/**",
|
||||
"build/lib/*",
|
||||
"src"
|
||||
],
|
||||
"scripts": {
|
||||
"clean": "rimraf ./build",
|
||||
"clean": "rimraf ./build && rimraf ./coverage",
|
||||
"test:eslint": "eslint --ext .ts,.tsx ./src",
|
||||
"test:types": "tsc",
|
||||
"test:lib": "jest --config ./jest.config.ts",
|
||||
"test:types": "tsc --noEmit",
|
||||
"test:lib": "vitest run --coverage",
|
||||
"test:lib:dev": "pnpm run test:lib --watch",
|
||||
"build:types": "tsc --build"
|
||||
"test:build": "publint --strict",
|
||||
"build": "pnpm build:rollup && pnpm build:types",
|
||||
"build:rollup": "rollup --config rollup.config.js",
|
||||
"build:types": "tsc --emitDeclarationOnly"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tanstack/store": "0.0.1-beta.89"
|
||||
|
||||
12
packages/form-core/rollup.config.js
Normal file
12
packages/form-core/rollup.config.js
Normal file
@@ -0,0 +1,12 @@
|
||||
// @ts-check
|
||||
|
||||
import { defineConfig } from 'rollup'
|
||||
import { buildConfigs } from '../../scripts/getRollupConfig.js'
|
||||
|
||||
export default defineConfig(
|
||||
buildConfigs({
|
||||
name: 'form-core',
|
||||
outputFile: 'index',
|
||||
entryFile: './src/index.ts',
|
||||
}),
|
||||
)
|
||||
7
packages/form-core/tsconfig.eslint.json
Normal file
7
packages/form-core/tsconfig.eslint.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": true
|
||||
},
|
||||
"include": ["**/*.ts", "**/*.tsx", ".eslintrc.cjs", "rollup.config.js"]
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
// "composite": true,
|
||||
// "rootDir": "./src",
|
||||
"outDir": "./build/types"
|
||||
"outDir": "./build/lib",
|
||||
"types": ["vitest/globals"]
|
||||
},
|
||||
"include": ["./src/**/*"]
|
||||
"include": ["src"]
|
||||
}
|
||||
|
||||
12
packages/form-core/vitest.config.ts
Normal file
12
packages/form-core/vitest.config.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { defineConfig } from 'vitest/config'
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
name: 'form-core',
|
||||
dir: './src',
|
||||
watch: false,
|
||||
environment: 'jsdom',
|
||||
globals: true,
|
||||
coverage: { provider: 'istanbul' },
|
||||
},
|
||||
})
|
||||
@@ -2,11 +2,15 @@
|
||||
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
const config = {
|
||||
parser: '@typescript-eslint/parser',
|
||||
extends: ['plugin:react/recommended', 'plugin:react-hooks/recommended'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.eslint.json',
|
||||
sourceType: 'module',
|
||||
},
|
||||
rules: {
|
||||
'react/jsx-key': ['error', { checkFragmentShorthand: true }],
|
||||
'react-hooks/exhaustive-deps': 'error',
|
||||
'react/no-children-prop': 'off',
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
export default {
|
||||
displayName: 'react-form',
|
||||
preset: '../../jest-preset.js',
|
||||
testMatch: ['<rootDir>/src/**/*.test.tsx', '<rootDir>/codemods/**/*.test.js'],
|
||||
}
|
||||
@@ -10,21 +10,39 @@
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
},
|
||||
"types": "build/types/index.d.ts",
|
||||
"main": "build/cjs/index.js",
|
||||
"module": "build/esm/index.js",
|
||||
"type": "module",
|
||||
"types": "build/lib/index.d.ts",
|
||||
"main": "build/lib/index.legacy.cjs",
|
||||
"module": "build/lib/index.legacy.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./build/lib/index.d.ts",
|
||||
"import": "./build/lib/index.js",
|
||||
"require": "./build/lib/index.cjs",
|
||||
"default": "./build/lib/index.cjs"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"clean": "rimraf ./build",
|
||||
"clean": "rimraf ./build && rimraf ./coverage",
|
||||
"test:eslint": "eslint --ext .ts,.tsx ./src",
|
||||
"test:types": "tsc",
|
||||
"test:lib": "jest --config ./jest.config.ts",
|
||||
"test:types": "tsc --noEmit",
|
||||
"test:lib": "vitest run --coverage",
|
||||
"test:lib:dev": "pnpm run test:lib --watch",
|
||||
"build:types": "tsc --build"
|
||||
"test:build": "publint --strict",
|
||||
"build": "pnpm build:rollup && pnpm build:codemods && pnpm build:types",
|
||||
"build:rollup": "rollup --config rollup.config.js",
|
||||
"build:codemods": "cpy ../codemods/src/**/* ./build/codemods",
|
||||
"build:types": "tsc --emitDeclarationOnly"
|
||||
},
|
||||
"files": [
|
||||
"build/**",
|
||||
"src"
|
||||
"build/lib/*",
|
||||
"src",
|
||||
"build/codemods",
|
||||
"!build/codemods/jest.config.js",
|
||||
"!build/codemods/**/__testfixtures__",
|
||||
"!build/codemods/**/__tests__"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/jscodeshift": "^0.11.3",
|
||||
|
||||
12
packages/react-form/rollup.config.js
Normal file
12
packages/react-form/rollup.config.js
Normal file
@@ -0,0 +1,12 @@
|
||||
// @ts-check
|
||||
|
||||
import { defineConfig } from 'rollup'
|
||||
import { buildConfigs } from '../../scripts/getRollupConfig.js'
|
||||
|
||||
export default defineConfig(
|
||||
buildConfigs({
|
||||
name: 'react-form',
|
||||
outputFile: 'index',
|
||||
entryFile: './src/index.ts',
|
||||
}),
|
||||
)
|
||||
@@ -41,6 +41,7 @@ export function useForm<TData>(opts?: FormOptions<TData>): FormApi<TData> {
|
||||
// @ts-ignore
|
||||
const api = new FormApi<TData>(opts)
|
||||
|
||||
// eslint-disable-next-line react/display-name
|
||||
api.Provider = (props) => (
|
||||
<formContext.Provider {...props} value={{ formApi: api }} />
|
||||
)
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
"compilerOptions": {
|
||||
"noEmit": true
|
||||
},
|
||||
"include": ["**/*.ts", "**/*.tsx", "./.eslintrc.cjs"]
|
||||
"include": ["**/*.ts", "**/*.tsx", ".eslintrc.cjs", "rollup.config.js"]
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
// "composite": true,
|
||||
// "rootDir": "./src",
|
||||
"outDir": "./build/types"
|
||||
"jsx": "react",
|
||||
"outDir": "./build/lib",
|
||||
"types": ["vitest/globals"]
|
||||
},
|
||||
"include": ["./src/**/*"]
|
||||
"include": ["src"]
|
||||
}
|
||||
|
||||
12
packages/react-form/vitest.config.ts
Normal file
12
packages/react-form/vitest.config.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { defineConfig } from 'vitest/config'
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
name: 'react-form',
|
||||
dir: './src',
|
||||
watch: false,
|
||||
environment: 'jsdom',
|
||||
globals: true,
|
||||
coverage: { provider: 'istanbul' },
|
||||
},
|
||||
})
|
||||
22
patches/@types__testing-library__jest-dom@5.14.5.patch
Normal file
22
patches/@types__testing-library__jest-dom@5.14.5.patch
Normal file
@@ -0,0 +1,22 @@
|
||||
diff --git a/index.d.ts b/index.d.ts
|
||||
index 43ba6b7fe458e77d152fe0b2f7afeac05d8fc563..979c61d461cc22711033ec43b9d7b749fa4a4396 100755
|
||||
--- a/index.d.ts
|
||||
+++ b/index.d.ts
|
||||
@@ -7,12 +7,11 @@
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// Minimum TypeScript Version: 4.3
|
||||
|
||||
-/// <reference types="jest" />
|
||||
-
|
||||
-import { TestingLibraryMatchers } from './matchers';
|
||||
+import { TestingLibraryMatchers } from "./matchers";
|
||||
|
||||
declare global {
|
||||
- namespace jest {
|
||||
- interface Matchers<R = void, T = {}> extends TestingLibraryMatchers<typeof expect.stringContaining, R> {}
|
||||
- }
|
||||
+ namespace jest {
|
||||
+ interface Matchers<R = void, T = {}>
|
||||
+ extends TestingLibraryMatchers<typeof expect.stringContaining, R> {}
|
||||
+ }
|
||||
}
|
||||
9202
pnpm-lock.yaml
generated
9202
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
24
project.json
24
project.json
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"name": "root",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "./",
|
||||
"targets": {
|
||||
"rollup": {
|
||||
"command": "rollup --config rollup.config.js",
|
||||
"outputs": [
|
||||
"{workspaceRoot}/packages/*/build/**/*(.cjs|.mjs|.js)*",
|
||||
"{workspaceRoot}/packages/*/build/stats*",
|
||||
"{workspaceRoot}/packages/*/build/**/*.svelte"
|
||||
],
|
||||
"inputs": ["default"]
|
||||
},
|
||||
"build": {
|
||||
"command": "echo \" @tanstack/form > All packages built! 📦\"",
|
||||
"dependsOn": ["rollup", "^build:types", "^build"]
|
||||
},
|
||||
"test:build": {
|
||||
"command": "bundlewatch"
|
||||
}
|
||||
},
|
||||
"implicitDependencies": ["@tanstack/form-core", "@tanstack/react-form"]
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
require("ts-node").register({
|
||||
compilerOptions: {
|
||||
esModuleInterop: true,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = require("./rollup.config.ts");
|
||||
253
rollup.config.ts
253
rollup.config.ts
@@ -1,253 +0,0 @@
|
||||
import type { RollupOptions } from 'rollup'
|
||||
import babel from '@rollup/plugin-babel'
|
||||
import { terser } from 'rollup-plugin-terser'
|
||||
// @ts-ignore
|
||||
import size from 'rollup-plugin-size'
|
||||
import visualizer from 'rollup-plugin-visualizer'
|
||||
import replace from '@rollup/plugin-replace'
|
||||
import nodeResolve from '@rollup/plugin-node-resolve'
|
||||
import commonjs from '@rollup/plugin-commonjs'
|
||||
import path from 'path'
|
||||
// import svelte from 'rollup-plugin-svelte'
|
||||
import dts from 'rollup-plugin-dts'
|
||||
//
|
||||
import { packages } from './scripts/config'
|
||||
import { readJsonSync } from 'fs-extra'
|
||||
|
||||
type Options = {
|
||||
input: string
|
||||
packageDir: string
|
||||
umdExternal: RollupOptions['external']
|
||||
external: RollupOptions['external']
|
||||
banner: string
|
||||
jsName: string
|
||||
globals: Record<string, string>
|
||||
}
|
||||
|
||||
const umdDevPlugin = (type: 'development' | 'production') =>
|
||||
replace({
|
||||
'process.env.NODE_ENV': `"${type}"`,
|
||||
delimiters: ['', ''],
|
||||
preventAssignment: true,
|
||||
})
|
||||
|
||||
const babelPlugin = babel({
|
||||
babelHelpers: 'bundled',
|
||||
exclude: /node_modules/,
|
||||
extensions: ['.ts', '.tsx'],
|
||||
})
|
||||
|
||||
export default function rollup(options: RollupOptions): RollupOptions[] {
|
||||
return packages.flatMap((pkg) => {
|
||||
return buildConfigs({
|
||||
name: pkg.packageDir,
|
||||
packageDir: `packages/${pkg.packageDir}`,
|
||||
jsName: pkg.jsName,
|
||||
outputFile: pkg.packageDir,
|
||||
entryFile: pkg.entryFile,
|
||||
globals: pkg.globals ?? {},
|
||||
esm: pkg.esm ?? true,
|
||||
cjs: pkg.cjs ?? true,
|
||||
umd: pkg.umd ?? true,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function buildConfigs(opts: {
|
||||
esm: boolean
|
||||
cjs: boolean
|
||||
umd: boolean
|
||||
packageDir: string
|
||||
name: string
|
||||
jsName: string
|
||||
outputFile: string
|
||||
entryFile: string
|
||||
globals: Record<string, string>
|
||||
}): RollupOptions[] {
|
||||
const input = path.resolve(opts.packageDir, opts.entryFile)
|
||||
|
||||
const packageJson =
|
||||
readJsonSync(
|
||||
path.resolve(process.cwd(), opts.packageDir, 'package.json'),
|
||||
) ?? {}
|
||||
|
||||
const banner = createBanner(opts.name)
|
||||
|
||||
const options: Options = {
|
||||
input,
|
||||
jsName: opts.jsName,
|
||||
packageDir: opts.packageDir,
|
||||
external: [
|
||||
...Object.keys(packageJson.dependencies ?? {}),
|
||||
...Object.keys(packageJson.peerDependencies ?? {}),
|
||||
],
|
||||
umdExternal: Object.keys(packageJson.peerDependencies ?? {}),
|
||||
banner,
|
||||
globals: opts.globals,
|
||||
}
|
||||
|
||||
return [
|
||||
opts.esm ? esm(options) : null,
|
||||
opts.cjs ? cjs(options) : null,
|
||||
opts.umd ? umdDev(options) : null,
|
||||
opts.umd ? umdProd(options) : null,
|
||||
types(options),
|
||||
].filter(Boolean) as any
|
||||
}
|
||||
|
||||
function esm({ input, packageDir, external, banner }: Options): RollupOptions {
|
||||
return {
|
||||
// ESM
|
||||
external,
|
||||
input,
|
||||
output: {
|
||||
format: 'esm',
|
||||
sourcemap: true,
|
||||
dir: `${packageDir}/build/esm`,
|
||||
banner,
|
||||
},
|
||||
plugins: [
|
||||
// svelte({
|
||||
// compilerOptions: {
|
||||
// hydratable: true,
|
||||
// },
|
||||
// }),
|
||||
babelPlugin,
|
||||
nodeResolve({ extensions: ['.ts', '.tsx'] }),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
function cjs({ input, external, packageDir, banner }: Options): RollupOptions {
|
||||
return {
|
||||
// CJS
|
||||
external,
|
||||
input,
|
||||
output: {
|
||||
format: 'cjs',
|
||||
sourcemap: true,
|
||||
dir: `${packageDir}/build/cjs`,
|
||||
preserveModules: true,
|
||||
exports: 'named',
|
||||
banner,
|
||||
},
|
||||
plugins: [
|
||||
// svelte(),
|
||||
babelPlugin,
|
||||
commonjs(),
|
||||
nodeResolve({ extensions: ['.ts', '.tsx'] }),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
function umdDev({
|
||||
input,
|
||||
umdExternal,
|
||||
packageDir,
|
||||
globals,
|
||||
banner,
|
||||
jsName,
|
||||
}: Options): RollupOptions {
|
||||
return {
|
||||
// UMD (Dev)
|
||||
external: umdExternal,
|
||||
input,
|
||||
output: {
|
||||
format: 'umd',
|
||||
sourcemap: true,
|
||||
file: `${packageDir}/build/umd/index.development.js`,
|
||||
name: jsName,
|
||||
globals,
|
||||
banner,
|
||||
},
|
||||
plugins: [
|
||||
// svelte(),
|
||||
babelPlugin,
|
||||
commonjs(),
|
||||
nodeResolve({ extensions: ['.ts', '.tsx'] }),
|
||||
umdDevPlugin('development'),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
function umdProd({
|
||||
input,
|
||||
umdExternal,
|
||||
packageDir,
|
||||
globals,
|
||||
banner,
|
||||
jsName,
|
||||
}: Options): RollupOptions {
|
||||
return {
|
||||
// UMD (Prod)
|
||||
external: umdExternal,
|
||||
input,
|
||||
output: {
|
||||
format: 'umd',
|
||||
sourcemap: true,
|
||||
file: `${packageDir}/build/umd/index.production.js`,
|
||||
name: jsName,
|
||||
globals,
|
||||
banner,
|
||||
},
|
||||
plugins: [
|
||||
// svelte(),
|
||||
babelPlugin,
|
||||
commonjs(),
|
||||
nodeResolve({ extensions: ['.ts', '.tsx'] }),
|
||||
umdDevPlugin('production'),
|
||||
terser({
|
||||
mangle: true,
|
||||
compress: true,
|
||||
}),
|
||||
size({}),
|
||||
visualizer({
|
||||
filename: `${packageDir}/build/stats-html.html`,
|
||||
gzipSize: true,
|
||||
}),
|
||||
visualizer({
|
||||
filename: `${packageDir}/build/stats-react.json`,
|
||||
// template: 'treemap',
|
||||
gzipSize: true,
|
||||
json: true,
|
||||
}),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
function types({
|
||||
input,
|
||||
packageDir,
|
||||
external,
|
||||
banner,
|
||||
}: Options): RollupOptions {
|
||||
return {
|
||||
// TYPES
|
||||
external,
|
||||
input,
|
||||
output: {
|
||||
format: 'es',
|
||||
file: `${packageDir}/build/types/index.d.ts`,
|
||||
banner,
|
||||
},
|
||||
plugins: [
|
||||
dts({
|
||||
// tsconfig: path.resolve(process.cwd(), 'tsconfig.json'),
|
||||
// tsconfig: path.resolve(packageDir, 'tsconfig.json'),
|
||||
}),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
function createBanner(libraryName: string) {
|
||||
return `/**
|
||||
* ${libraryName}
|
||||
*
|
||||
* Copyright (c) TanStack
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE.md file in the root directory of this source tree.
|
||||
*
|
||||
* @license MIT
|
||||
*/`
|
||||
}
|
||||
68
scripts/config.js
Normal file
68
scripts/config.js
Normal file
@@ -0,0 +1,68 @@
|
||||
// @ts-check
|
||||
|
||||
import { resolve } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
/**
|
||||
* List your npm packages here. The first package will be used as the versioner.
|
||||
* @type {import('./types').Package[]}
|
||||
*/
|
||||
export const packages = [
|
||||
{
|
||||
name: '@tanstack/form-core',
|
||||
packageDir: 'packages/form-core',
|
||||
entries: ['main', 'module', 'types'],
|
||||
},
|
||||
{
|
||||
name: '@tanstack/react-form',
|
||||
packageDir: 'packages/react-form',
|
||||
entries: ['main', 'module', 'types'],
|
||||
},
|
||||
// {
|
||||
// name: '@tanstack/react-form-devtools',
|
||||
// packageDir: 'packages/react-form-devtools',
|
||||
// entries: ['main', 'module', 'types'],
|
||||
// },
|
||||
// {
|
||||
// name: '@tanstack/react-form-persist-client',
|
||||
// packageDir: 'packages/react-form-persist-client',
|
||||
// entries: ['main', 'module', 'types'],
|
||||
// },
|
||||
// {
|
||||
// name: '@tanstack/solid-form',
|
||||
// packageDir: 'packages/solid-form',
|
||||
// entries: ['main', 'module', 'types'],
|
||||
// },
|
||||
// {
|
||||
// name: '@tanstack/svelte-form',
|
||||
// packageDir: 'packages/svelte-form',
|
||||
// entries: ['main', 'module', 'types'],
|
||||
// },
|
||||
// {
|
||||
// name: '@tanstack/vue-form',
|
||||
// packageDir: 'packages/vue-form',
|
||||
// entries: ['main', 'module', 'types'],
|
||||
// },
|
||||
]
|
||||
|
||||
/**
|
||||
* Contains config for publishable branches.
|
||||
* @type {Record<string, import('./types').BranchConfig>}
|
||||
*/
|
||||
export const branchConfigs = {
|
||||
main: {
|
||||
prerelease: false,
|
||||
},
|
||||
next: {
|
||||
prerelease: true,
|
||||
},
|
||||
beta: {
|
||||
prerelease: true,
|
||||
},
|
||||
alpha: {
|
||||
prerelease: true,
|
||||
},
|
||||
}
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url))
|
||||
export const rootDir = resolve(__dirname, '..')
|
||||
@@ -1,78 +0,0 @@
|
||||
import path from 'path'
|
||||
import type { BranchConfig, Package } from './types'
|
||||
|
||||
// TODO: List your npm packages here. The first package will be used as the versioner.
|
||||
export const packages: Package[] = [
|
||||
{
|
||||
name: '@tanstack/form-core',
|
||||
packageDir: 'form-core',
|
||||
srcDir: 'src',
|
||||
jsName: 'FormCore',
|
||||
entryFile: 'src/index.ts',
|
||||
globals: {},
|
||||
},
|
||||
{
|
||||
name: '@tanstack/react-form',
|
||||
packageDir: 'react-form',
|
||||
srcDir: 'src',
|
||||
jsName: 'ReactForm',
|
||||
entryFile: 'src/index.ts',
|
||||
globals: {
|
||||
react: 'React',
|
||||
},
|
||||
},
|
||||
// {
|
||||
// name: '@tanstack/react-form-devtools',
|
||||
// packageDir: 'react-form-devtools',
|
||||
// srcDir: 'src',
|
||||
// },
|
||||
// {
|
||||
// name: '@tanstack/react-form-persist-client',
|
||||
// packageDir: 'react-form-persist-client',
|
||||
// srcDir: 'src',
|
||||
// },
|
||||
// {
|
||||
// name: '@tanstack/solid-form',
|
||||
// packageDir: 'solid-form',
|
||||
// srcDir: 'src',
|
||||
// },
|
||||
// {
|
||||
// name: '@tanstack/svelte-form',
|
||||
// packageDir: 'svelte-form',
|
||||
// srcDir: 'src',
|
||||
// },
|
||||
// {
|
||||
// name: '@tanstack/vue-form',
|
||||
// packageDir: 'vue-form',
|
||||
// srcDir: 'src',
|
||||
// },
|
||||
]
|
||||
|
||||
export const latestBranch = 'main'
|
||||
|
||||
export const branchConfigs: Record<string, BranchConfig> = {
|
||||
main: {
|
||||
prerelease: false,
|
||||
ghRelease: true,
|
||||
},
|
||||
next: {
|
||||
prerelease: true,
|
||||
ghRelease: true,
|
||||
},
|
||||
beta: {
|
||||
prerelease: true,
|
||||
ghRelease: true,
|
||||
},
|
||||
alpha: {
|
||||
prerelease: true,
|
||||
ghRelease: true,
|
||||
},
|
||||
}
|
||||
|
||||
export const rootDir = path.resolve(__dirname, '..')
|
||||
export const examplesDirs = [
|
||||
'examples/react',
|
||||
// 'examples/solid',
|
||||
// 'examples/svelte',
|
||||
// 'examples/vue',
|
||||
]
|
||||
199
scripts/getRollupConfig.js
Normal file
199
scripts/getRollupConfig.js
Normal file
@@ -0,0 +1,199 @@
|
||||
// @ts-check
|
||||
|
||||
import { resolve } from 'node:path'
|
||||
import { babel } from '@rollup/plugin-babel'
|
||||
import { visualizer } from 'rollup-plugin-visualizer'
|
||||
import replace from '@rollup/plugin-replace'
|
||||
import { nodeResolve } from '@rollup/plugin-node-resolve'
|
||||
import commonJS from '@rollup/plugin-commonjs'
|
||||
import externals from 'rollup-plugin-node-externals'
|
||||
import preserveDirectives from 'rollup-plugin-preserve-directives'
|
||||
import { rootDir } from './config.js'
|
||||
|
||||
/** @param {'development' | 'production'} type */
|
||||
const forceEnvPlugin = (type) =>
|
||||
replace({
|
||||
'process.env.NODE_ENV': `"${type}"`,
|
||||
delimiters: ['', ''],
|
||||
preventAssignment: true,
|
||||
})
|
||||
|
||||
/** @param {'legacy' | 'modern'} type */
|
||||
const babelPlugin = (type) =>
|
||||
babel({
|
||||
configFile: resolve(rootDir, 'babel.config.cjs'),
|
||||
browserslistConfigFile: type === 'modern' ? true : false,
|
||||
targets:
|
||||
type === 'modern'
|
||||
? ''
|
||||
: {
|
||||
chrome: '73',
|
||||
firefox: '78',
|
||||
edge: '79',
|
||||
safari: '12',
|
||||
ios: '12',
|
||||
opera: '53',
|
||||
},
|
||||
babelHelpers: 'bundled',
|
||||
exclude: /node_modules/,
|
||||
extensions: ['.ts', '.tsx'],
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {Object} opts - Options for building configurations.
|
||||
* @param {string} opts.name - The name.
|
||||
* @param {string} opts.outputFile - The output file.
|
||||
* @param {string} opts.entryFile - The entry file.
|
||||
* @param {boolean} [opts.bundleDeps] - Flag indicating whether to make all deps external.
|
||||
* @param {boolean} [opts.forceDevEnv] - Flag indicating whether to force development environment.
|
||||
* @param {boolean} [opts.forceBundle] - Flag indicating whether to force bundling.
|
||||
* @returns {import('rollup').RollupOptions[]}
|
||||
*/
|
||||
export function buildConfigs(opts) {
|
||||
return [modernConfig(opts), legacyConfig(opts)]
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} opts - Options for building configurations.
|
||||
* @param {string} opts.name - The name.
|
||||
* @param {string} opts.outputFile - The output file.
|
||||
* @param {string} opts.entryFile - The entry file.
|
||||
* @param {boolean} [opts.bundleDeps] - Flag indicating whether to make all deps external.
|
||||
* @param {boolean} [opts.forceDevEnv] - Flag indicating whether to force development environment.
|
||||
* @param {boolean} [opts.forceBundle] - Flag indicating whether to force bundling.
|
||||
* @returns {import('rollup').RollupOptions}
|
||||
*/
|
||||
function modernConfig(opts) {
|
||||
const forceDevEnv = opts.forceDevEnv || false
|
||||
const forceBundle = opts.forceBundle || false
|
||||
const bundleDeps = opts.bundleDeps || false
|
||||
|
||||
/** @type {import('rollup').OutputOptions[]} */
|
||||
const bundleOutput = [
|
||||
{
|
||||
format: 'esm',
|
||||
file: `./build/lib/${opts.outputFile}.js`,
|
||||
sourcemap: true,
|
||||
},
|
||||
{
|
||||
format: 'cjs',
|
||||
file: `./build/lib/${opts.outputFile}.cjs`,
|
||||
sourcemap: true,
|
||||
exports: 'named',
|
||||
},
|
||||
]
|
||||
|
||||
/** @type {import('rollup').OutputOptions[]} */
|
||||
const normalOutput = [
|
||||
{
|
||||
format: 'esm',
|
||||
dir: `./build/lib`,
|
||||
sourcemap: true,
|
||||
preserveModules: true,
|
||||
entryFileNames: '[name].js',
|
||||
},
|
||||
{
|
||||
format: 'cjs',
|
||||
dir: `./build/lib`,
|
||||
sourcemap: true,
|
||||
exports: 'named',
|
||||
preserveModules: true,
|
||||
entryFileNames: '[name].cjs',
|
||||
},
|
||||
]
|
||||
|
||||
return {
|
||||
input: [opts.entryFile],
|
||||
output: forceBundle ? bundleOutput : normalOutput,
|
||||
plugins: [
|
||||
commonJS(),
|
||||
babelPlugin('modern'),
|
||||
nodeResolve({ extensions: ['.ts', '.tsx'] }),
|
||||
forceDevEnv ? forceEnvPlugin('development') : undefined,
|
||||
bundleDeps
|
||||
? undefined
|
||||
: externals({
|
||||
packagePath: './package.json',
|
||||
deps: true,
|
||||
devDeps: true,
|
||||
peerDeps: true,
|
||||
}),
|
||||
preserveDirectives(),
|
||||
visualizer({
|
||||
filename: `./build/stats.html`,
|
||||
template: 'treemap',
|
||||
gzipSize: true,
|
||||
}),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} opts - Options for building configurations.
|
||||
* @param {string} opts.name - The name.
|
||||
* @param {string} opts.outputFile - The output file.
|
||||
* @param {string} opts.entryFile - The entry file.
|
||||
* @param {boolean} [opts.bundleDeps] - Flag indicating whether to make all deps external.
|
||||
* @param {boolean} [opts.forceDevEnv] - Flag indicating whether to force development environment.
|
||||
* @param {boolean} [opts.forceBundle] - Flag indicating whether to force bundling.
|
||||
* @returns {import('rollup').RollupOptions}
|
||||
*/
|
||||
function legacyConfig(opts) {
|
||||
const forceDevEnv = opts.forceDevEnv || false
|
||||
const forceBundle = opts.forceBundle || false
|
||||
const bundleDeps = opts.bundleDeps || false
|
||||
|
||||
/** @type {import('rollup').OutputOptions[]} */
|
||||
const bundleOutput = [
|
||||
{
|
||||
format: 'esm',
|
||||
file: `./build/lib/${opts.outputFile}.legacy.js`,
|
||||
sourcemap: true,
|
||||
},
|
||||
{
|
||||
format: 'cjs',
|
||||
file: `./build/lib/${opts.outputFile}.legacy.cjs`,
|
||||
sourcemap: true,
|
||||
exports: 'named',
|
||||
},
|
||||
]
|
||||
|
||||
/** @type {import('rollup').OutputOptions[]} */
|
||||
const normalOutput = [
|
||||
{
|
||||
format: 'esm',
|
||||
dir: `./build/lib`,
|
||||
sourcemap: true,
|
||||
preserveModules: true,
|
||||
entryFileNames: '[name].legacy.js',
|
||||
},
|
||||
{
|
||||
format: 'cjs',
|
||||
dir: `./build/lib`,
|
||||
sourcemap: true,
|
||||
exports: 'named',
|
||||
preserveModules: true,
|
||||
entryFileNames: '[name].legacy.cjs',
|
||||
},
|
||||
]
|
||||
|
||||
return {
|
||||
input: [opts.entryFile],
|
||||
output: forceBundle ? bundleOutput : normalOutput,
|
||||
plugins: [
|
||||
commonJS(),
|
||||
babelPlugin('legacy'),
|
||||
nodeResolve({ extensions: ['.ts', '.tsx'] }),
|
||||
forceDevEnv ? forceEnvPlugin('development') : undefined,
|
||||
bundleDeps
|
||||
? undefined
|
||||
: externals({
|
||||
packagePath: './package.json',
|
||||
deps: true,
|
||||
devDeps: true,
|
||||
peerDeps: true,
|
||||
}),
|
||||
preserveDirectives(),
|
||||
],
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"name": "scripts",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "scripts",
|
||||
"targets": {
|
||||
"test:eslint": { "command": "eslint ./scripts" }
|
||||
|
||||
479
scripts/publish.js
Normal file
479
scripts/publish.js
Normal file
@@ -0,0 +1,479 @@
|
||||
// @ts-check
|
||||
// Originally ported to TS from https://github.com/remix-run/react-router/tree/main/scripts/{version,publish}.js
|
||||
|
||||
import path from 'node:path'
|
||||
import { execSync } from 'node:child_process'
|
||||
import chalk from 'chalk'
|
||||
import jsonfile from 'jsonfile'
|
||||
import * as semver from 'semver'
|
||||
import currentGitBranch from 'current-git-branch'
|
||||
import { parse as parseCommit } from '@commitlint/parse'
|
||||
import log from 'git-log-parser'
|
||||
import streamToArray from 'stream-to-array'
|
||||
import axios from 'axios'
|
||||
import { DateTime } from 'luxon'
|
||||
import { branchConfigs, packages, rootDir } from './config.js'
|
||||
|
||||
/** @param {string} version */
|
||||
const releaseCommitMsg = (version) => `release: v${version}`
|
||||
|
||||
async function run() {
|
||||
const branchName =
|
||||
/** @type {string} */ process.env.BRANCH ?? currentGitBranch()
|
||||
|
||||
const isMainBranch = branchName === 'main'
|
||||
const npmTag = isMainBranch ? 'latest' : branchName
|
||||
|
||||
// Get tags
|
||||
/** @type {string[]} */
|
||||
let tags = execSync('git tag').toString().split('\n')
|
||||
|
||||
// Filter tags to our branch/pre-release combo
|
||||
tags = tags
|
||||
.filter((tag) => semver.valid(tag))
|
||||
.filter((tag) => {
|
||||
if (semver.prerelease(tag) === null) {
|
||||
return isMainBranch
|
||||
} else {
|
||||
return !isMainBranch
|
||||
}
|
||||
})
|
||||
// sort by latest
|
||||
.sort(semver.compare)
|
||||
|
||||
// Get the latest tag
|
||||
let latestTag = /** @type {string} */ [...tags].pop()
|
||||
|
||||
let range = `${latestTag}..HEAD`
|
||||
// let range = ``;
|
||||
|
||||
// If RELEASE_ALL is set via a commit subject or body, all packages will be
|
||||
// released regardless if they have changed files matching the package srcDir.
|
||||
let RELEASE_ALL = false
|
||||
|
||||
if (!latestTag || process.env.TAG) {
|
||||
if (process.env.TAG) {
|
||||
if (!process.env.TAG.startsWith('v')) {
|
||||
throw new Error(
|
||||
`process.env.TAG must start with "v", eg. v0.0.0. You supplied ${process.env.TAG}`,
|
||||
)
|
||||
}
|
||||
console.info(
|
||||
chalk.yellow(
|
||||
`Tag is set to ${process.env.TAG}. This will force release all packages. Publishing...`,
|
||||
),
|
||||
)
|
||||
RELEASE_ALL = true
|
||||
|
||||
// Is it a major version?
|
||||
if (!semver.patch(process.env.TAG) && !semver.minor(process.env.TAG)) {
|
||||
range = `origin/main..HEAD`
|
||||
latestTag = process.env.TAG
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
'Could not find latest tag! To make a release tag of v0.0.1, run with TAG=v0.0.1',
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
console.info(`Git Range: ${range}`)
|
||||
|
||||
/**
|
||||
* Get the commits since the latest tag
|
||||
* @type {import('./types.js').Commit[]}
|
||||
*/
|
||||
const commitsSinceLatestTag = (
|
||||
await new Promise((resolve, reject) => {
|
||||
/** @type {NodeJS.ReadableStream} */
|
||||
const strm = log.parse({
|
||||
_: range,
|
||||
})
|
||||
|
||||
streamToArray(strm, function (err, arr) {
|
||||
if (err) return reject(err)
|
||||
|
||||
Promise.all(
|
||||
arr.map(async (d) => {
|
||||
const parsed = await parseCommit(d.subject)
|
||||
|
||||
return { ...d, parsed }
|
||||
}),
|
||||
).then((res) => resolve(res.filter(Boolean)))
|
||||
})
|
||||
})
|
||||
).filter((/** @type {import('./types.js').Commit} */ commit) => {
|
||||
const exclude = [
|
||||
commit.subject.startsWith('Merge branch '), // No merge commits
|
||||
commit.subject.startsWith(releaseCommitMsg('')), // No example update commits
|
||||
].some(Boolean)
|
||||
|
||||
return !exclude
|
||||
})
|
||||
|
||||
console.info(
|
||||
`Parsing ${commitsSinceLatestTag.length} commits since ${latestTag}...`,
|
||||
)
|
||||
|
||||
/**
|
||||
* Parses the commit messsages, log them, and determine the type of release needed
|
||||
* -1 means no release is necessary
|
||||
* 0 means patch release is necessary
|
||||
* 1 means minor release is necessary
|
||||
* 2 means major release is necessary
|
||||
* @type {number}
|
||||
*/
|
||||
let recommendedReleaseLevel = commitsSinceLatestTag.reduce(
|
||||
(releaseLevel, commit) => {
|
||||
if (commit.parsed.type) {
|
||||
if (['fix', 'refactor', 'perf'].includes(commit.parsed.type)) {
|
||||
releaseLevel = Math.max(releaseLevel, 0)
|
||||
}
|
||||
if (['feat'].includes(commit.parsed.type)) {
|
||||
releaseLevel = Math.max(releaseLevel, 1)
|
||||
}
|
||||
if (commit.body.includes('BREAKING CHANGE')) {
|
||||
releaseLevel = Math.max(releaseLevel, 2)
|
||||
}
|
||||
if (
|
||||
commit.subject.includes('RELEASE_ALL') ||
|
||||
commit.body.includes('RELEASE_ALL')
|
||||
) {
|
||||
RELEASE_ALL = true
|
||||
}
|
||||
}
|
||||
|
||||
return releaseLevel
|
||||
},
|
||||
-1,
|
||||
)
|
||||
|
||||
/**
|
||||
* Uses git diff to determine which files have changed since the latest tag
|
||||
* @type {string[]}
|
||||
*/
|
||||
const changedFiles = process.env.TAG
|
||||
? []
|
||||
: execSync(`git diff ${latestTag} --name-only`)
|
||||
.toString()
|
||||
.split('\n')
|
||||
.filter(Boolean)
|
||||
|
||||
/** Uses packages and changedFiles to determine which packages have changed */
|
||||
const changedPackages = RELEASE_ALL
|
||||
? packages
|
||||
: packages.filter((pkg) => {
|
||||
const changed = changedFiles.some(
|
||||
(file) =>
|
||||
file.startsWith(path.join(pkg.packageDir, 'src')) ||
|
||||
file.startsWith(path.join(pkg.packageDir, 'package.json')),
|
||||
)
|
||||
return changed
|
||||
})
|
||||
|
||||
// If a package has a dependency that has been updated, we need to update the
|
||||
// package that depends on it as well.
|
||||
// run this multiple times so that dependencies of dependencies are also included
|
||||
for (let runs = 0; runs < 3; runs++) {
|
||||
for (const pkg of packages) {
|
||||
const packageJson = await readPackageJson(
|
||||
path.resolve(rootDir, pkg.packageDir, 'package.json'),
|
||||
)
|
||||
const allDependencies = Object.keys(
|
||||
Object.assign(
|
||||
{},
|
||||
packageJson.dependencies ?? {},
|
||||
packageJson.peerDependencies ?? {},
|
||||
),
|
||||
)
|
||||
|
||||
if (
|
||||
allDependencies.find((dep) =>
|
||||
changedPackages.find((d) => d.name === dep),
|
||||
) &&
|
||||
!changedPackages.find((d) => d.name === pkg.name)
|
||||
) {
|
||||
console.info(
|
||||
'adding package dependency',
|
||||
pkg.name,
|
||||
'to changed packages',
|
||||
)
|
||||
changedPackages.push(pkg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!process.env.TAG) {
|
||||
if (recommendedReleaseLevel === 2) {
|
||||
console.info(
|
||||
`Major versions releases must be tagged and released manually.`,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if (recommendedReleaseLevel === -1) {
|
||||
console.info(
|
||||
`There have been no changes since the release of ${latestTag} that require a new version. You're good!`,
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const changelogCommitsMd = process.env.TAG
|
||||
? `Manual Release: ${process.env.TAG}`
|
||||
: await Promise.all(
|
||||
Object.entries(
|
||||
commitsSinceLatestTag.reduce(
|
||||
(acc, next) => {
|
||||
const type = next.parsed.type?.toLowerCase() ?? 'other'
|
||||
|
||||
return {
|
||||
...acc,
|
||||
[type]: [...(acc[type] || []), next],
|
||||
}
|
||||
},
|
||||
/** @type {Record<string, import('./types.js').Commit[]>} */ {},
|
||||
),
|
||||
)
|
||||
.sort(
|
||||
getSorterFn([
|
||||
([d]) =>
|
||||
[
|
||||
'other',
|
||||
'examples',
|
||||
'docs',
|
||||
'chore',
|
||||
'refactor',
|
||||
'perf',
|
||||
'fix',
|
||||
'feat',
|
||||
].indexOf(d),
|
||||
]),
|
||||
)
|
||||
.reverse()
|
||||
.map(async ([type, commits]) => {
|
||||
return Promise.all(
|
||||
commits.map(async (commit) => {
|
||||
let username = ''
|
||||
|
||||
if (process.env.GH_TOKEN) {
|
||||
const query = `${
|
||||
commit.author.email || commit.committer.email
|
||||
}`
|
||||
|
||||
const res = await axios.get(
|
||||
'https://api.github.com/search/users',
|
||||
{
|
||||
params: {
|
||||
q: query,
|
||||
},
|
||||
headers: {
|
||||
Authorization: `token ${process.env.GH_TOKEN}`,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
username = res.data.items[0]?.login
|
||||
}
|
||||
|
||||
const scope = commit.parsed.scope
|
||||
? `${commit.parsed.scope}: `
|
||||
: ''
|
||||
const subject = commit.parsed.subject || commit.subject
|
||||
|
||||
return `- ${scope}${subject} (${commit.commit.short}) ${
|
||||
username
|
||||
? `by @${username}`
|
||||
: `by ${commit.author.name || commit.author.email}`
|
||||
}`
|
||||
}),
|
||||
).then((c) => /** @type {const} */ [type, c])
|
||||
}),
|
||||
).then((groups) => {
|
||||
return groups
|
||||
.map(([type, commits]) => {
|
||||
return [`### ${capitalize(type)}`, commits.join('\n')].join('\n\n')
|
||||
})
|
||||
.join('\n\n')
|
||||
})
|
||||
|
||||
if (process.env.TAG && recommendedReleaseLevel === -1) {
|
||||
recommendedReleaseLevel = 0
|
||||
}
|
||||
|
||||
/** @type {import('./types.js').BranchConfig | undefined} */
|
||||
const branchConfig = branchConfigs[branchName]
|
||||
|
||||
if (!branchConfig) {
|
||||
console.log(`No publish config found for branch: ${branchName}`)
|
||||
console.log('Exiting...')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const releaseType = branchConfig.prerelease
|
||||
? 'prerelease'
|
||||
: /** @type {const} */ { 0: 'patch', 1: 'minor', 2: 'major' }[
|
||||
recommendedReleaseLevel
|
||||
]
|
||||
|
||||
if (!releaseType) {
|
||||
throw new Error(`Invalid release level: ${recommendedReleaseLevel}`)
|
||||
}
|
||||
|
||||
const version = process.env.TAG
|
||||
? semver.parse(process.env.TAG)?.version
|
||||
: semver.inc(latestTag, releaseType, npmTag)
|
||||
|
||||
if (!version) {
|
||||
throw new Error(
|
||||
`Invalid version increment from semver.inc(${[
|
||||
latestTag,
|
||||
recommendedReleaseLevel,
|
||||
branchConfig.prerelease,
|
||||
].join(', ')}`,
|
||||
)
|
||||
}
|
||||
|
||||
const changelogMd = [
|
||||
`Version ${version} - ${DateTime.now().toLocaleString(
|
||||
DateTime.DATETIME_SHORT,
|
||||
)}`,
|
||||
`## Changes`,
|
||||
changelogCommitsMd,
|
||||
`## Packages`,
|
||||
changedPackages.map((d) => `- ${d.name}@${version}`).join('\n'),
|
||||
].join('\n\n')
|
||||
|
||||
console.info('Generating changelog...')
|
||||
console.info()
|
||||
console.info(changelogMd)
|
||||
console.info()
|
||||
|
||||
if (changedPackages.length === 0) {
|
||||
console.info('No packages have been affected.')
|
||||
return
|
||||
}
|
||||
|
||||
console.info(`Updating all changed packages to version ${version}...`)
|
||||
// Update each package to the new version
|
||||
for (const pkg of changedPackages) {
|
||||
console.info(` Updating ${pkg.name} version to ${version}...`)
|
||||
|
||||
await updatePackageJson(
|
||||
path.resolve(rootDir, pkg.packageDir, 'package.json'),
|
||||
(config) => {
|
||||
config.version = version
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
if (!process.env.CI) {
|
||||
console.warn(
|
||||
`This is a dry run for version ${version}. Push to CI to publish for real or set CI=true to override!`,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
console.info()
|
||||
console.info(`Publishing all packages to npm with tag "${npmTag}"`)
|
||||
|
||||
// Publish each package
|
||||
changedPackages.forEach((pkg) => {
|
||||
const packageDir = path.join(rootDir, pkg.packageDir)
|
||||
const cmd = `cd ${packageDir} && pnpm publish --tag ${npmTag} --access=public --no-git-checks`
|
||||
console.info(
|
||||
` Publishing ${pkg.name}@${version} to npm with tag "${npmTag}"...`,
|
||||
)
|
||||
execSync(cmd, {
|
||||
stdio: [process.stdin, process.stdout, process.stderr],
|
||||
})
|
||||
})
|
||||
|
||||
console.info()
|
||||
|
||||
console.info(`Committing changes...`)
|
||||
execSync(`git add -A && git commit -m "${releaseCommitMsg(version)}"`)
|
||||
console.info()
|
||||
console.info(` Committed Changes.`)
|
||||
|
||||
console.info(`Pushing changes...`)
|
||||
execSync(`git push`)
|
||||
console.info()
|
||||
console.info(` Changes pushed.`)
|
||||
|
||||
console.info(`Creating new git tag v${version}`)
|
||||
execSync(`git tag -a -m "v${version}" v${version}`)
|
||||
|
||||
console.info(`Pushing tags...`)
|
||||
execSync(`git push --tags`)
|
||||
console.info()
|
||||
console.info(` Tags pushed.`)
|
||||
|
||||
console.info(`Creating github release...`)
|
||||
// Stringify the markdown to excape any quotes
|
||||
execSync(
|
||||
`gh release create v${version} ${
|
||||
!isMainBranch ? '--prerelease' : ''
|
||||
} --notes '${changelogMd.replace(/'/g, '"')}'`,
|
||||
)
|
||||
console.info(` Github release created.`)
|
||||
|
||||
console.info(`All done!`)
|
||||
}
|
||||
|
||||
run().catch((err) => {
|
||||
console.info(err)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
/** @param {string} str */
|
||||
function capitalize(str) {
|
||||
return str.slice(0, 1).toUpperCase() + str.slice(1)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} pathName
|
||||
* @returns {Promise<import('type-fest').PackageJson>}
|
||||
*/
|
||||
async function readPackageJson(pathName) {
|
||||
return await jsonfile.readFile(pathName)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} pathName
|
||||
* @param {(json: import('type-fest').PackageJson) => Promise<void> | void} transform
|
||||
*/
|
||||
async function updatePackageJson(pathName, transform) {
|
||||
const json = await readPackageJson(pathName)
|
||||
await transform(json)
|
||||
await jsonfile.writeFile(pathName, json, {
|
||||
spaces: 2,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @template TItem
|
||||
* @param {((d: TItem) => any)[]} sorters
|
||||
* @returns {(a: TItem, b: TItem) => number}
|
||||
*/
|
||||
function getSorterFn(sorters) {
|
||||
return (a, b) => {
|
||||
let i = 0
|
||||
|
||||
sorters.some((sorter) => {
|
||||
const sortedA = sorter(a)
|
||||
const sortedB = sorter(b)
|
||||
if (sortedA > sortedB) {
|
||||
i = 1
|
||||
return true
|
||||
}
|
||||
if (sortedA < sortedB) {
|
||||
i = -1
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
return i
|
||||
}
|
||||
}
|
||||
@@ -1,671 +0,0 @@
|
||||
import {
|
||||
branchConfigs,
|
||||
examplesDirs,
|
||||
latestBranch,
|
||||
packages,
|
||||
rootDir,
|
||||
} from './config'
|
||||
import type { BranchConfig, Commit, Package } from './types'
|
||||
|
||||
// Originally ported to TS from https://github.com/remix-run/router/tree/main/scripts/{version,publish}.js
|
||||
import path from 'path'
|
||||
import { exec, execSync } from 'child_process'
|
||||
import fsp from 'fs/promises'
|
||||
import chalk from 'chalk'
|
||||
import jsonfile from 'jsonfile'
|
||||
import semver from 'semver'
|
||||
import currentGitBranch from 'current-git-branch'
|
||||
import parseCommit from '@commitlint/parse'
|
||||
import log from 'git-log-parser'
|
||||
import streamToArray from 'stream-to-array'
|
||||
import axios from 'axios'
|
||||
import { DateTime } from 'luxon'
|
||||
|
||||
import type { PackageJson } from 'type-fest'
|
||||
|
||||
const releaseCommitMsg = (version: string) => `release: v${version}`
|
||||
|
||||
async function run() {
|
||||
const branchName: string =
|
||||
process.env.BRANCH ??
|
||||
// (process.env.PR_NUMBER ? `pr-${process.env.PR_NUMBER}` : currentGitBranch())
|
||||
currentGitBranch()
|
||||
|
||||
const branchConfig = branchConfigs[branchName]
|
||||
|
||||
if (!branchConfig) {
|
||||
console.log(`No publish config found for branch: ${branchName}`)
|
||||
console.log('Exiting...')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const isLatestBranch = branchName === latestBranch
|
||||
const npmTag = isLatestBranch ? 'latest' : branchName
|
||||
|
||||
let remoteURL = execSync('git config --get remote.origin.url').toString()
|
||||
|
||||
remoteURL = remoteURL.substring(0, remoteURL.indexOf('.git'))
|
||||
|
||||
// Get tags
|
||||
let tags: string[] = execSync('git tag').toString().split('\n')
|
||||
|
||||
// Filter tags to our branch/pre-release combo
|
||||
tags = tags
|
||||
.filter((tag) => semver.valid(tag))
|
||||
.filter((tag) => {
|
||||
if (isLatestBranch) {
|
||||
return semver.prerelease(tag) == null
|
||||
}
|
||||
|
||||
return tag.includes(`-${branchName}`)
|
||||
})
|
||||
// sort by latest
|
||||
.sort(semver.compare)
|
||||
|
||||
// Get the latest tag
|
||||
let latestTag = [...tags].pop()
|
||||
|
||||
let range = `${latestTag}..HEAD`
|
||||
// let range = ``;
|
||||
|
||||
// If RELEASE_ALL is set via a commit subject or body, all packages will be
|
||||
// released regardless if they have changed files matching the package srcDir.
|
||||
let RELEASE_ALL = false
|
||||
let SKIP_TESTS = false
|
||||
|
||||
if (!latestTag || process.env.TAG) {
|
||||
if (process.env.TAG) {
|
||||
if (!process.env.TAG.startsWith('v')) {
|
||||
throw new Error(
|
||||
`process.env.TAG must start with "v", eg. v0.0.0. You supplied ${process.env.TAG}`,
|
||||
)
|
||||
}
|
||||
console.info(
|
||||
chalk.yellow(
|
||||
`Tag is set to ${process.env.TAG}. This will force release all packages. Publishing...`,
|
||||
),
|
||||
)
|
||||
RELEASE_ALL = true
|
||||
|
||||
// Is it a major version?
|
||||
if (!semver.patch(process.env.TAG) && !semver.minor(process.env.TAG)) {
|
||||
range = `beta..HEAD`
|
||||
latestTag = process.env.TAG
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
'Could not find latest tag! To make a release tag of v0.0.1, run with TAG=v0.0.1',
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
console.info(`Git Range: ${range}`)
|
||||
|
||||
// Get the commits since the latest tag
|
||||
const commitsSinceLatestTag = (
|
||||
await new Promise<Commit[]>((resolve, reject) => {
|
||||
const strm = log.parse({
|
||||
_: range,
|
||||
})
|
||||
|
||||
streamToArray(strm, function (err: any, arr: any[]) {
|
||||
if (err) return reject(err)
|
||||
|
||||
Promise.all(
|
||||
arr.map(async (d) => {
|
||||
const parsed = await parseCommit(d.subject)
|
||||
|
||||
return { ...d, parsed }
|
||||
}),
|
||||
).then((res) => resolve(res.filter(Boolean)))
|
||||
})
|
||||
})
|
||||
).filter((commit: Commit) => {
|
||||
const exclude = [
|
||||
commit.subject.startsWith('Merge branch '), // No merge commits
|
||||
commit.subject.startsWith(releaseCommitMsg('')), // No example update commits
|
||||
].some(Boolean)
|
||||
|
||||
return !exclude
|
||||
})
|
||||
|
||||
console.info(
|
||||
`Parsing ${commitsSinceLatestTag.length} commits since ${latestTag}...`,
|
||||
)
|
||||
|
||||
// Pares the commit messsages, log them, and determine the type of release needed
|
||||
let recommendedReleaseLevel: number = commitsSinceLatestTag.reduce(
|
||||
(releaseLevel, commit) => {
|
||||
if (commit.parsed) {
|
||||
if (['fix', 'refactor', 'perf'].includes(commit.parsed.type || '')) {
|
||||
releaseLevel = Math.max(releaseLevel, 0)
|
||||
}
|
||||
if (['feat'].includes(commit.parsed.type || '')) {
|
||||
releaseLevel = Math.max(releaseLevel, 1)
|
||||
}
|
||||
}
|
||||
if (commit.body.includes('BREAKING CHANGE')) {
|
||||
releaseLevel = Math.max(releaseLevel, 2)
|
||||
}
|
||||
if (
|
||||
commit.subject.includes('RELEASE_ALL') ||
|
||||
commit.body.includes('RELEASE_ALL')
|
||||
) {
|
||||
RELEASE_ALL = true
|
||||
}
|
||||
|
||||
if (
|
||||
commit.subject.includes('SKIP_TESTS') ||
|
||||
commit.body.includes('SKIP_TESTS')
|
||||
) {
|
||||
SKIP_TESTS = true
|
||||
}
|
||||
|
||||
return releaseLevel
|
||||
},
|
||||
-1,
|
||||
)
|
||||
|
||||
const changedFiles: string[] = process.env.TAG
|
||||
? []
|
||||
: execSync(`git diff ${latestTag} --name-only`)
|
||||
.toString()
|
||||
.split('\n')
|
||||
.filter(Boolean)
|
||||
|
||||
const changedPackages = RELEASE_ALL
|
||||
? packages
|
||||
: changedFiles.reduce((changedPackagesAcc: Package[], file) => {
|
||||
const pkg = packages.find((p) =>
|
||||
file.startsWith(path.join('packages', p.packageDir, p.srcDir)),
|
||||
)
|
||||
if (pkg && !changedPackagesAcc.find((d) => d.name === pkg.name)) {
|
||||
changedPackagesAcc.push(pkg)
|
||||
}
|
||||
return changedPackagesAcc
|
||||
}, [] as Package[])
|
||||
|
||||
// If a package has a dependency that has been updated, we need to update the
|
||||
// package that depends on it as well.
|
||||
await Promise.all(
|
||||
packages.map(async (pkg) => {
|
||||
const pkgJson = await readPackageJson(
|
||||
path.resolve(rootDir, 'packages', pkg.packageDir, 'package.json'),
|
||||
)
|
||||
if (
|
||||
Object.keys(pkgJson.dependencies ?? {}).find((dep) =>
|
||||
changedPackages.find((d) => d.name === dep),
|
||||
) &&
|
||||
!changedPackages.find((d) => d.name === pkg.name)
|
||||
) {
|
||||
changedPackages.push(pkg)
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
if (!process.env.TAG) {
|
||||
if (recommendedReleaseLevel === 2) {
|
||||
console.info(
|
||||
`Major versions releases must be tagged and released manually.`,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if (recommendedReleaseLevel === -1) {
|
||||
console.info(
|
||||
`There have been no changes since the release of ${latestTag} that require a new version. You're good!`,
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function getSorterFn<TItem>(sorters: ((d: TItem) => any)[]) {
|
||||
return (a: TItem, b: TItem) => {
|
||||
let i = 0
|
||||
|
||||
sorters.some((sorter) => {
|
||||
const sortedA = sorter(a)
|
||||
const sortedB = sorter(b)
|
||||
if (sortedA > sortedB) {
|
||||
i = 1
|
||||
return true
|
||||
}
|
||||
if (sortedA < sortedB) {
|
||||
i = -1
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
const changelogCommitsMd = process.env.TAG
|
||||
? `Manual Release: ${process.env.TAG}`
|
||||
: await Promise.all(
|
||||
Object.entries(
|
||||
commitsSinceLatestTag.reduce((acc, next) => {
|
||||
const type = next.parsed?.type?.toLowerCase() ?? 'other'
|
||||
|
||||
return {
|
||||
...acc,
|
||||
[type]: [...(acc[type] || []), next],
|
||||
}
|
||||
}, {} as Record<string, Commit[]>),
|
||||
)
|
||||
.sort(
|
||||
getSorterFn([
|
||||
([d]) =>
|
||||
[
|
||||
'other',
|
||||
'examples',
|
||||
'docs',
|
||||
'chore',
|
||||
'refactor',
|
||||
'perf',
|
||||
'fix',
|
||||
'feat',
|
||||
].indexOf(d),
|
||||
]),
|
||||
)
|
||||
.reverse()
|
||||
.map(async ([type, commits]) => {
|
||||
return Promise.all(
|
||||
commits.map(async (commit) => {
|
||||
let username = ''
|
||||
|
||||
if (process.env.GH_TOKEN) {
|
||||
const query = `${
|
||||
commit.author?.email ?? commit.committer.email
|
||||
}`
|
||||
|
||||
const res = await axios.get(
|
||||
'https://api.github.com/search/users',
|
||||
{
|
||||
params: {
|
||||
q: query,
|
||||
},
|
||||
headers: {
|
||||
Authorization: `token ${process.env.GH_TOKEN}`,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
username = res.data.items[0]?.login
|
||||
}
|
||||
|
||||
const scope = commit.parsed?.scope
|
||||
? `${commit.parsed.scope}: `
|
||||
: ''
|
||||
const subject = commit.parsed?.subject ?? commit.subject
|
||||
// const commitUrl = `${remoteURL}/commit/${commit.commit.long}`;
|
||||
|
||||
return `- ${scope}${subject} (${commit.commit.short}) ${
|
||||
username
|
||||
? `by @${username}`
|
||||
: `by ${commit.author?.name ?? commit.author?.email}`
|
||||
}`
|
||||
}),
|
||||
).then((commitDescriptions) => [type, commitDescriptions] as const)
|
||||
}),
|
||||
).then((groups) => {
|
||||
return groups
|
||||
.map(([type, commits]) => {
|
||||
return [`### ${capitalize(type)}`, commits.join('\n')].join('\n\n')
|
||||
})
|
||||
.join('\n\n')
|
||||
})
|
||||
|
||||
if (process.env.TAG && recommendedReleaseLevel === -1) {
|
||||
recommendedReleaseLevel = 0
|
||||
}
|
||||
|
||||
const releaseType = branchConfig.prerelease
|
||||
? 'prerelease'
|
||||
: ({ 0: 'patch', 1: 'minor', 2: 'major' } as const)[recommendedReleaseLevel]
|
||||
|
||||
if (!releaseType) {
|
||||
throw new Error(`Invalid release level: ${recommendedReleaseLevel}`)
|
||||
}
|
||||
|
||||
const version = process.env.TAG
|
||||
? semver.parse(process.env.TAG)?.version
|
||||
: semver.inc(latestTag!, releaseType, npmTag)
|
||||
|
||||
if (!version) {
|
||||
throw new Error(
|
||||
`Invalid version increment from semver.inc(${[
|
||||
latestTag,
|
||||
recommendedReleaseLevel,
|
||||
branchConfig.prerelease,
|
||||
].join(', ')}`,
|
||||
)
|
||||
}
|
||||
|
||||
const changelogMd = [
|
||||
`Version ${version} - ${DateTime.now().toLocaleString(
|
||||
DateTime.DATETIME_SHORT,
|
||||
)}`,
|
||||
`## Changes`,
|
||||
changelogCommitsMd,
|
||||
`## Packages`,
|
||||
changedPackages.map((d) => `- ${d.name}@${version}`).join('\n'),
|
||||
].join('\n\n')
|
||||
|
||||
console.info('Generating changelog...')
|
||||
console.info()
|
||||
console.info(changelogMd)
|
||||
console.info()
|
||||
|
||||
console.info('Building packages...')
|
||||
execSync(`pnpm build`, { encoding: 'utf8', stdio: 'inherit' })
|
||||
console.info('')
|
||||
|
||||
// console.info('Building types...')
|
||||
// execSync(`yarn types`, { encoding: 'utf8', stdio: 'inherit' })
|
||||
// console.info('')
|
||||
|
||||
// console.info('Validating packages...')
|
||||
// const failedValidations: string[] = []
|
||||
|
||||
// await Promise.all(
|
||||
// packages.map(async (pkg) => {
|
||||
// const pkgJson = await readPackageJson(
|
||||
// path.resolve(rootDir, 'packages', pkg.packageDir, 'package.json'),
|
||||
// )
|
||||
|
||||
// await Promise.all(
|
||||
// (['module', 'main', 'browser', 'types'] as const).map(
|
||||
// async (entryKey) => {
|
||||
// const entry = pkgJson[entryKey] as string
|
||||
|
||||
// if (!entry) {
|
||||
// throw new Error(
|
||||
// `Missing entry for "${entryKey}" in ${pkg.packageDir}/package.json!`,
|
||||
// )
|
||||
// }
|
||||
|
||||
// const filePath = path.resolve(
|
||||
// rootDir,
|
||||
// 'packages',
|
||||
// pkg.packageDir,
|
||||
// entry,
|
||||
// )
|
||||
|
||||
// try {
|
||||
// await fsp.access(filePath)
|
||||
// } catch (err) {
|
||||
// failedValidations.push(`Missing build file: ${filePath}`)
|
||||
// }
|
||||
// },
|
||||
// ),
|
||||
// )
|
||||
// }),
|
||||
// )
|
||||
// console.info('')
|
||||
// if (failedValidations.length > 0) {
|
||||
// throw new Error(
|
||||
// 'Some packages failed validation:\n\n' + failedValidations.join('\n'),
|
||||
// )
|
||||
// }
|
||||
|
||||
console.info('Testing packages...')
|
||||
execSync(`pnpm test:ci ${(SKIP_TESTS as boolean) ? '|| exit 0' : ''}`, {
|
||||
encoding: 'utf8',
|
||||
})
|
||||
console.info('')
|
||||
|
||||
console.info(`Updating all changed packages to version ${version}...`)
|
||||
// Update each package to the new version
|
||||
for (const pkg of changedPackages) {
|
||||
console.info(` Updating ${pkg.name} version to ${version}...`)
|
||||
|
||||
await updatePackageJson(
|
||||
path.resolve(rootDir, 'packages', pkg.packageDir, 'package.json'),
|
||||
(config) => {
|
||||
config.version = version
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// console.info(`Updating all package dependencies to latest versions...`)
|
||||
// // Update all changed package dependencies to their correct versions
|
||||
// for (const pkg of packages) {
|
||||
// await updatePackageJson(
|
||||
// path.resolve(rootDir, 'packages', pkg.packageDir, 'package.json'),
|
||||
// async (config) => {
|
||||
// await Promise.all(
|
||||
// (pkg.dependencies ?? []).map(async (dep) => {
|
||||
// const depPackage = packages.find((d) => d.name === dep)
|
||||
|
||||
// if (!depPackage) {
|
||||
// throw new Error(`Could not find package ${dep}`)
|
||||
// }
|
||||
|
||||
// const depVersion = await getPackageVersion(
|
||||
// path.resolve(
|
||||
// rootDir,
|
||||
// 'packages',
|
||||
// depPackage.packageDir,
|
||||
// 'package.json',
|
||||
// ),
|
||||
// )
|
||||
|
||||
// if (
|
||||
// config.dependencies?.[dep] &&
|
||||
// config.dependencies[dep] !== depVersion
|
||||
// ) {
|
||||
// console.info(
|
||||
// ` Updating ${pkg.name}'s dependency on ${dep} to version ${depVersion}.`,
|
||||
// )
|
||||
// config.dependencies[dep] = depVersion
|
||||
// }
|
||||
// }),
|
||||
// )
|
||||
|
||||
// await Promise.all(
|
||||
// (pkg.peerDependencies ?? []).map(async (peerDep) => {
|
||||
// const peerDepPackage = packages.find((d) => d.name === peerDep)
|
||||
|
||||
// if (!peerDepPackage) {
|
||||
// throw new Error(`Could not find package ${peerDep}`)
|
||||
// }
|
||||
|
||||
// const depVersion = await getPackageVersion(
|
||||
// path.resolve(
|
||||
// rootDir,
|
||||
// 'packages',
|
||||
// peerDepPackage.packageDir,
|
||||
// 'package.json',
|
||||
// ),
|
||||
// )
|
||||
|
||||
// if (
|
||||
// config.peerDependencies?.[peerDep] &&
|
||||
// config.peerDependencies[peerDep] !== depVersion
|
||||
// ) {
|
||||
// console.info(
|
||||
// ` Updating ${pkg.name}'s peerDependency on ${peerDep} to version ${depVersion}.`,
|
||||
// )
|
||||
// config.peerDependencies[peerDep] = depVersion
|
||||
// }
|
||||
// }),
|
||||
// )
|
||||
// },
|
||||
// )
|
||||
// }
|
||||
|
||||
console.info(`Updating all example dependencies...`)
|
||||
await Promise.all(
|
||||
examplesDirs.map(async (examplesDir) => {
|
||||
examplesDir = path.resolve(rootDir, examplesDir)
|
||||
const exampleDirs = await fsp.readdir(examplesDir)
|
||||
for (const exampleName of exampleDirs) {
|
||||
const exampleDir = path.resolve(examplesDir, exampleName)
|
||||
const stat = await fsp.stat(exampleDir)
|
||||
if (!stat.isDirectory()) continue
|
||||
|
||||
await Promise.all([
|
||||
fsp.rm(path.resolve(exampleDir, 'package-lock.json'), {
|
||||
force: true,
|
||||
}),
|
||||
fsp.rm(path.resolve(exampleDir, 'yarn.lock'), {
|
||||
force: true,
|
||||
}),
|
||||
updatePackageJson(
|
||||
path.resolve(exampleDir, 'package.json'),
|
||||
async (config) => {
|
||||
await Promise.all(
|
||||
changedPackages.map(async (pkg) => {
|
||||
const depVersion = await getPackageVersion(
|
||||
path.resolve(
|
||||
rootDir,
|
||||
'packages',
|
||||
pkg.packageDir,
|
||||
'package.json',
|
||||
),
|
||||
)
|
||||
|
||||
if (
|
||||
config.dependencies?.[pkg.name] &&
|
||||
config.dependencies[pkg.name] !== depVersion
|
||||
) {
|
||||
console.info(
|
||||
` Updating ${exampleName}'s dependency on ${pkg.name} to version ${depVersion}.`,
|
||||
)
|
||||
config.dependencies[pkg.name] = depVersion
|
||||
}
|
||||
}),
|
||||
)
|
||||
},
|
||||
),
|
||||
])
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
if (!process.env.CI) {
|
||||
console.warn(
|
||||
`This is a dry run for version ${version}. Push to CI to publish for real or set CI=true to override!`,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Tag and commit
|
||||
console.info(`Creating new git tag v${version}`)
|
||||
execSync(`git tag -a -m "v${version}" v${version}`)
|
||||
|
||||
const taggedVersion = getTaggedVersion()
|
||||
if (!taggedVersion) {
|
||||
throw new Error(
|
||||
'Missing the tagged release version. Something weird is afoot!',
|
||||
)
|
||||
}
|
||||
|
||||
console.info()
|
||||
console.info(`Publishing all packages to npm with tag "${npmTag}"`)
|
||||
|
||||
// Publish each package
|
||||
changedPackages.map((pkg) => {
|
||||
const packageDir = path.join(rootDir, 'packages', pkg.packageDir)
|
||||
const cmd = `cd ${packageDir} && pnpm publish --tag ${npmTag} --access=public --no-git-checks`
|
||||
console.info(
|
||||
` Publishing ${pkg.name}@${version} to npm with tag "${npmTag}"...`,
|
||||
)
|
||||
// execSync(`${cmd} --token ${process.env.NPM_TOKEN}`)
|
||||
execSync(cmd)
|
||||
})
|
||||
|
||||
console.info()
|
||||
|
||||
console.info(`Pushing new tags to branch.`)
|
||||
execSync(`git push --tags`)
|
||||
console.info(` Pushed tags to branch.`)
|
||||
|
||||
if (branchConfig.ghRelease) {
|
||||
console.info(`Creating github release...`)
|
||||
// Stringify the markdown to excape any quotes
|
||||
execSync(
|
||||
`gh release create v${version} ${
|
||||
!isLatestBranch ? '--prerelease' : ''
|
||||
} --notes '${changelogMd}'`,
|
||||
)
|
||||
console.info(` Github release created.`)
|
||||
|
||||
console.info(`Committing changes...`)
|
||||
execSync(`git add -A && git commit -m "${releaseCommitMsg(version)}"`)
|
||||
console.info()
|
||||
console.info(` Committed Changes.`)
|
||||
console.info(`Pushing changes...`)
|
||||
execSync(`git push`)
|
||||
console.info()
|
||||
console.info(` Changes pushed.`)
|
||||
} else {
|
||||
console.info(`Skipping github release and change commit.`)
|
||||
}
|
||||
|
||||
console.info(`Pushing tags...`)
|
||||
execSync(`git push --tags`)
|
||||
console.info()
|
||||
console.info(` Tags pushed.`)
|
||||
console.info(`All done!`)
|
||||
}
|
||||
|
||||
run().catch((err) => {
|
||||
console.info(err)
|
||||
if (err.stdout) {
|
||||
console.log(err.stdout.toString())
|
||||
}
|
||||
if (err.stderr) {
|
||||
console.log(err.stderr.toString())
|
||||
}
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
function capitalize(str: string) {
|
||||
return str.slice(0, 1).toUpperCase() + str.slice(1)
|
||||
}
|
||||
|
||||
async function readPackageJson(pathName: string) {
|
||||
return (await jsonfile.readFile(pathName)) as PackageJson
|
||||
}
|
||||
|
||||
async function updatePackageJson(
|
||||
pathName: string,
|
||||
transform: (json: PackageJson) => Promise<void> | void,
|
||||
) {
|
||||
const json = await readPackageJson(pathName)
|
||||
await transform(json)
|
||||
await jsonfile.writeFile(pathName, json, {
|
||||
spaces: 2,
|
||||
})
|
||||
}
|
||||
|
||||
async function getPackageVersion(pathName: string) {
|
||||
const json = await readPackageJson(pathName)
|
||||
|
||||
if (!json.version) {
|
||||
throw new Error(`No version found for package: ${pathName}`)
|
||||
}
|
||||
|
||||
return json.version
|
||||
}
|
||||
|
||||
function updateExampleLockfile(example: string) {
|
||||
// execute npm to update lockfile, ignoring any stdout or stderr
|
||||
const exampleDir = path.join(rootDir, 'examples', example)
|
||||
execSync(`cd ${exampleDir} && pnpm install`, { stdio: 'ignore' })
|
||||
}
|
||||
|
||||
function getPackageNameDirectory(pathName: string) {
|
||||
return pathName
|
||||
.split('/')
|
||||
.filter((d) => !d.startsWith('@'))
|
||||
.join('/')
|
||||
}
|
||||
|
||||
function getTaggedVersion() {
|
||||
const output = execSync('git tag --list --points-at HEAD').toString()
|
||||
return output.replace(/^v|\n+$/g, '')
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES5",
|
||||
"module": "commonjs",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"skipLibCheck": true,
|
||||
"checkJs": true
|
||||
},
|
||||
"ts-node": {
|
||||
"transpileOnly": true,
|
||||
"files": true,
|
||||
"compilerOptions": {
|
||||
"sourceMap": true,
|
||||
"inlineSources": true
|
||||
}
|
||||
}
|
||||
}
|
||||
20
scripts/types.ts → scripts/types.d.ts
vendored
20
scripts/types.ts → scripts/types.d.ts
vendored
@@ -1,11 +1,13 @@
|
||||
import type { RollupOptions } from 'rollup'
|
||||
|
||||
export type Commit = {
|
||||
commit: CommitOrTree
|
||||
tree: CommitOrTree
|
||||
author?: AuthorOrCommitter
|
||||
author: AuthorOrCommitter
|
||||
committer: AuthorOrCommitter
|
||||
subject: string
|
||||
body: string
|
||||
parsed?: Parsed
|
||||
parsed: Parsed
|
||||
}
|
||||
|
||||
export type CommitOrTree = {
|
||||
@@ -14,13 +16,13 @@ export type CommitOrTree = {
|
||||
}
|
||||
|
||||
export type AuthorOrCommitter = {
|
||||
name?: string
|
||||
name: string
|
||||
email: string
|
||||
date: string
|
||||
}
|
||||
|
||||
export type Parsed = {
|
||||
type?: string
|
||||
type: string | null
|
||||
scope?: string | null
|
||||
subject: string
|
||||
merge?: null
|
||||
@@ -37,17 +39,9 @@ export type Parsed = {
|
||||
export type Package = {
|
||||
name: string
|
||||
packageDir: string
|
||||
srcDir: string
|
||||
jsName: string
|
||||
entryFile: string
|
||||
external?: (d: string) => any
|
||||
globals?: Record<string, string>
|
||||
esm?: boolean
|
||||
cjs?: boolean
|
||||
umd?: boolean
|
||||
entries: Array<'main' | 'module' | 'svelte' | 'types'>
|
||||
}
|
||||
|
||||
export type BranchConfig = {
|
||||
prerelease: boolean
|
||||
ghRelease: boolean
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["DOM", "DOM.Iterable", "ES2020"],
|
||||
"target": "ES2020",
|
||||
"module": "ES2020",
|
||||
"moduleResolution": "node",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"strictNullChecks": true,
|
||||
"jsx": "react",
|
||||
"declaration": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"noImplicitReturns": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@tanstack/form-core": ["packages/form-core/src"],
|
||||
"@tanstack/react-form": ["packages/react-form/src"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,31 @@
|
||||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "packages/form-core" },
|
||||
{ "path": "packages/react-form" }
|
||||
// { "path": "packages/react-form-devtools" }
|
||||
// { "path": "packages/solid-form" },
|
||||
// { "path": "packages/vue-form" },
|
||||
]
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"allowUnreachableCode": false,
|
||||
"allowUnusedLabels": false,
|
||||
"baseUrl": ".",
|
||||
"checkJs": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"isolatedModules": true,
|
||||
"lib": ["DOM", "DOM.Iterable", "ES2020"],
|
||||
"module": "ES2020",
|
||||
"moduleResolution": "node",
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"strictNullChecks": true,
|
||||
"target": "ES2020"
|
||||
},
|
||||
"include": [".eslintrc.cjs", "rollup.config.js", "scripts"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user