diff --git a/scripts/getTsupConfig.js b/getTsupConfig.js similarity index 100% rename from scripts/getTsupConfig.js rename to getTsupConfig.js diff --git a/package.json b/package.json index 18e4852..5077ef5 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,6 @@ "private": true, "repository": "https://github.com/tanstack/form.git", "packageManager": "pnpm@8.5.1", - "type": "module", "scripts": { "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", @@ -22,7 +21,8 @@ "dev": "pnpm run watch", "prettier": "prettier \"{packages,examples,scripts}/**/*.{md,js,jsx,cjs,ts,tsx,json,vue}\"", "prettier:write": "pnpm run prettier --write", - "cipublish": "node scripts/publish.js" + "cipublish": "ts-node scripts/publish.ts", + "cipublishforce": "CI=true pnpm cipublish" }, "nx": { "includedScripts": [ @@ -45,12 +45,15 @@ "@testing-library/react-hooks": "^8.0.1", "@testing-library/user-event": "^14.4.3", "@testing-library/vue": "^7.0.0", + "@types/current-git-branch": "^1.1.4", "@types/jest": "^26.0.4", + "@types/jsonfile": "^6.1.1", "@types/luxon": "^2.3.1", "@types/node": "^17.0.25", "@types/react": "^18.0.14", "@types/react-dom": "^18.0.5", "@types/semver": "^7.3.13", + "@types/stream-to-array": "^2.3.1", "@types/testing-library__jest-dom": "^5.14.5", "@typescript-eslint/eslint-plugin": "^6.4.1", "@typescript-eslint/parser": "^6.4.1", @@ -75,6 +78,7 @@ "eslint-plugin-import": "^2.28.1", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", + "fs-extra": "^11.1.1", "git-log-parser": "^1.2.0", "jsdom": "^22.0.0", "jsonfile": "^6.1.0", @@ -89,9 +93,9 @@ "react-dom-17": "npm:react-dom@^17.0.2", "rimraf": "^5.0.1", "semver": "^7.3.8", - "fs-extra": "^11.1.1", "solid-js": "^1.6.13", "stream-to-array": "^2.3.0", + "ts-node": "^10.9.1", "tsup": "^7.2.0", "type-fest": "^3.11.0", "typescript": "^5.2.2", diff --git a/packages/form-core/tsconfig.json b/packages/form-core/tsconfig.json index 1777264..8cb149f 100644 --- a/packages/form-core/tsconfig.json +++ b/packages/form-core/tsconfig.json @@ -1,5 +1,6 @@ { - "extends": "../../tsconfig.json", + "composite": true, + "extends": "../../tsconfig.base.json", "compilerOptions": { "outDir": "./build/lib", "types": ["vitest/globals"] diff --git a/packages/form-core/tsup.config.js b/packages/form-core/tsup.config.js index 5159fbe..7b19f5f 100644 --- a/packages/form-core/tsup.config.js +++ b/packages/form-core/tsup.config.js @@ -1,7 +1,7 @@ // @ts-check import { defineConfig } from 'tsup' -import { legacyConfig, modernConfig } from '../../scripts/getTsupConfig.js' +import { legacyConfig, modernConfig } from '../../getTsupConfig.js' export default defineConfig([ modernConfig({ entry: ['src/*.ts'] }), diff --git a/packages/react-form/tsconfig.json b/packages/react-form/tsconfig.json index 3559476..870eac0 100644 --- a/packages/react-form/tsconfig.json +++ b/packages/react-form/tsconfig.json @@ -1,5 +1,6 @@ { - "extends": "../../tsconfig.json", + "composite": true, + "extends": "../../tsconfig.base.json", "compilerOptions": { "jsx": "react", "outDir": "./build/lib", diff --git a/packages/react-form/tsup.config.js b/packages/react-form/tsup.config.js index 1031ae9..605f8e5 100644 --- a/packages/react-form/tsup.config.js +++ b/packages/react-form/tsup.config.js @@ -1,7 +1,7 @@ // @ts-check import { defineConfig } from 'tsup' -import { legacyConfig, modernConfig } from '../../scripts/getTsupConfig.js' +import { legacyConfig, modernConfig } from '../../getTsupConfig.js' export default defineConfig([ modernConfig({ entry: ['src/*.ts', 'src/*.tsx'] }), diff --git a/packages/vue-form/tsconfig.json b/packages/vue-form/tsconfig.json index aa2e165..e129c2e 100644 --- a/packages/vue-form/tsconfig.json +++ b/packages/vue-form/tsconfig.json @@ -1,5 +1,6 @@ { - "extends": "../../tsconfig.json", + "composite": true, + "extends": "../../tsconfig.base.json", "compilerOptions": { "types": ["vitest/globals", "vue/jsx"], "outDir": "./build/lib", diff --git a/packages/vue-form/tsup.config.js b/packages/vue-form/tsup.config.js index 1031ae9..605f8e5 100644 --- a/packages/vue-form/tsup.config.js +++ b/packages/vue-form/tsup.config.js @@ -1,7 +1,7 @@ // @ts-check import { defineConfig } from 'tsup' -import { legacyConfig, modernConfig } from '../../scripts/getTsupConfig.js' +import { legacyConfig, modernConfig } from '../../getTsupConfig.js' export default defineConfig([ modernConfig({ entry: ['src/*.ts', 'src/*.tsx'] }), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index febda8c..ad77dfb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -55,9 +55,15 @@ importers: '@testing-library/vue': specifier: ^7.0.0 version: 7.0.0(@vue/compiler-sfc@3.3.4)(vue@3.3.4) + '@types/current-git-branch': + specifier: ^1.1.4 + version: 1.1.4 '@types/jest': specifier: ^26.0.4 version: 26.0.24 + '@types/jsonfile': + specifier: ^6.1.1 + version: 6.1.1 '@types/luxon': specifier: ^2.3.1 version: 2.3.2 @@ -73,6 +79,9 @@ importers: '@types/semver': specifier: ^7.3.13 version: 7.3.13 + '@types/stream-to-array': + specifier: ^2.3.1 + version: 2.3.1 '@types/testing-library__jest-dom': specifier: ^5.14.5 version: 5.14.5(patch_hash=d573maxasnl5kxwdyzebcnmhpm) @@ -196,9 +205,12 @@ importers: stream-to-array: specifier: ^2.3.0 version: 2.3.0 + ts-node: + specifier: ^10.9.1 + version: 10.9.1(@types/node@17.0.45)(typescript@5.2.2) tsup: specifier: ^7.2.0 - version: 7.2.0(typescript@5.2.2) + version: 7.2.0(ts-node@10.9.1)(typescript@5.2.2) type-fest: specifier: ^3.11.0 version: 3.11.0 @@ -216,7 +228,7 @@ importers: dependencies: '@tanstack/react-form': specifier: ^0.2.1 - version: link:../../../packages/react-form + version: 0.2.1(@types/react@18.0.15)(react-dom@18.2.0)(react@18.2.0) axios: specifier: ^0.26.1 version: 0.26.1 @@ -241,7 +253,7 @@ importers: dependencies: '@tanstack/vue-form': specifier: ^0.2.2 - version: link:../../../packages/vue-form + version: 0.2.2(vue@3.3.4) vue: specifier: ^3.3.4 version: 3.3.4 @@ -1733,6 +1745,13 @@ packages: chalk: 4.1.2 dev: true + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: true + /@esbuild/android-arm64@0.18.20: resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} engines: {node: '>=12'} @@ -2166,6 +2185,13 @@ packages: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + /@mdn/browser-compat-data@5.3.9: resolution: {integrity: sha512-J7lLtHMEizYbI5T0Xlqpg1JXCz9JegZBeb7y3v/Nm8ScRw8TL9v3n+I3g1TFm+bLrRtwA33FKwX5znDwz+WzAQ==} dev: true @@ -2656,6 +2682,34 @@ packages: '@sinonjs/commons': 3.0.0 dev: false + /@tanstack/form-core@0.2.0: + resolution: {integrity: sha512-Kabl4c61z6tVDsSOjzyC7bNYKlJoY0k4T6u86YbpIOkBFqkX0S/J688pDw7vxhbgTJ3agVBsp73rptxPbDt7ZA==} + dependencies: + '@tanstack/store': 0.1.3 + dev: false + + /@tanstack/react-form@0.2.1(@types/react@18.0.15)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-2gRdDYYRIh/OW5Cu6GXpOC/tH7+fbwFPpSa0kuJEJq6mW321E5Ak4Fg2Lt3ygERpn6UTq+UwKGxjj747rpKvyg==} + peerDependencies: + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + dependencies: + '@tanstack/form-core': 0.2.0 + '@tanstack/react-store': 0.1.3(react-dom@18.2.0)(react@18.2.0) + '@tanstack/store': 0.1.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + use-isomorphic-layout-effect: 1.1.2(@types/react@18.0.15)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + dev: false + /@tanstack/react-store@0.1.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-nDOgSlarFFbIvVirAi/GcCyqyRMthgpuBhOhN87DkeQEau+ZNGsLKJifzrQYuWB0+4FXmgeoGaY/Dr383MPqZw==} peerDependencies: @@ -2672,6 +2726,22 @@ packages: resolution: {integrity: sha512-GnolmC8Fr4mvsHE1fGQmR3Nm0eBO3KnZjDU0a+P3TeQNM/dDscFGxtA7p31NplQNW3KwBw4t1RVFmz0VeKLxcw==} dev: false + /@tanstack/vue-form@0.2.2(vue@3.3.4): + resolution: {integrity: sha512-v8M08C3BIA7IUtGYmMejKpKSp4mkWA8y4t+WUIZBFA0yLycQHLSy2TLm7Wb+T4Up7c0CBGWum/VWUcu4tlQFhA==} + peerDependencies: + '@vue/composition-api': ^1.1.2 + vue: ^2.5.0 || ^3.0.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + dependencies: + '@tanstack/form-core': 0.2.0 + '@tanstack/store': 0.1.3 + '@tanstack/vue-store': 0.1.3(@vue/composition-api@1.7.2)(vue@3.3.4) + vue: 3.3.4 + vue-demi: 0.14.6(@vue/composition-api@1.7.2)(vue@3.3.4) + dev: false + /@tanstack/vue-store@0.1.3(@vue/composition-api@1.7.2)(vue@3.3.4): resolution: {integrity: sha512-vLG2t0N0nagS2YrCDtTGJiftBDWadX0M7vSkIjfl+I1SaeKDvhg+HbRxt7Vwc5iLcwHljHAIlf7Ak5o4q0Brhg==} peerDependencies: @@ -2783,10 +2853,22 @@ packages: engines: {node: '>= 10'} dev: true + /@tsconfig/node10@1.0.9: + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: true + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true + /@tsconfig/node14@1.0.3: resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} dev: true + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: true + /@types/aria-query@5.0.1: resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==} dev: true @@ -2830,6 +2912,10 @@ packages: resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==} dev: true + /@types/current-git-branch@1.1.4: + resolution: {integrity: sha512-laBj/aFKSEVEqyyOsogGCWoCFnfAQs5uDlSe9FWRsgUwrmhwe8R4fGbjb7q392cVX5BI9PqQw1ZRkTn4gmvDPw==} + dev: true + /@types/estree@1.0.1: resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} dev: true @@ -2875,6 +2961,12 @@ packages: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true + /@types/jsonfile@6.1.1: + resolution: {integrity: sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==} + dependencies: + '@types/node': 17.0.45 + dev: true + /@types/luxon@2.3.2: resolution: {integrity: sha512-WOehptuhKIXukSUUkRgGbj2c997Uv/iUgYgII8U7XLJqq9W2oF0kQ6frEznRQbdurioz+L/cdaIm4GutTQfgmA==} dev: true @@ -2925,6 +3017,12 @@ packages: resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} dev: false + /@types/stream-to-array@2.3.1: + resolution: {integrity: sha512-OqV/DIumEm5pT+m4LYGpDFRRLZ0VJRvrz58C8q8rjLGVgP5gRHxThG8eLZfhmK3GVAq9iq3eSvZ0vkZJ5ZH/Pg==} + dependencies: + '@types/node': 17.0.45 + dev: true + /@types/testing-library__jest-dom@5.14.5(patch_hash=d573maxasnl5kxwdyzebcnmhpm): resolution: {integrity: sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==} dependencies: @@ -3471,6 +3569,10 @@ packages: resolution: {integrity: sha512-Quji6+8kLBC3NnBeo14nPDq0+2jUs5s3/xEye+udFHumHhRk4M7aAMXp/PBJqkKYGuuyR9M/6Dq7d2AViiGmhw==} dev: false + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true + /argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} dependencies: @@ -4424,6 +4526,10 @@ packages: p-map: 6.0.0 dev: true + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: true + /cross-spawn@5.1.0: resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} dependencies: @@ -4648,6 +4754,11 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: true + /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -7051,6 +7162,10 @@ packages: semver: 7.5.4 dev: true + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + /makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} dependencies: @@ -8206,7 +8321,7 @@ packages: pathe: 1.1.1 dev: true - /postcss-load-config@4.0.1: + /postcss-load-config@4.0.1(ts-node@10.9.1): resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} engines: {node: '>= 14'} peerDependencies: @@ -8219,6 +8334,7 @@ packages: optional: true dependencies: lilconfig: 2.1.0 + ts-node: 10.9.1(@types/node@17.0.45)(typescript@5.2.2) yaml: 2.3.1 dev: true @@ -9521,6 +9637,37 @@ packages: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: true + /ts-node@10.9.1(@types/node@17.0.45)(typescript@5.2.2): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 17.0.45 + acorn: 8.10.0 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.2.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: true + /tsconfig-paths@3.14.2: resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} dependencies: @@ -9542,7 +9689,7 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - /tsup@7.2.0(typescript@5.2.2): + /tsup@7.2.0(ts-node@10.9.1)(typescript@5.2.2): resolution: {integrity: sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ==} engines: {node: '>=16.14'} hasBin: true @@ -9566,7 +9713,7 @@ packages: execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 - postcss-load-config: 4.0.1 + postcss-load-config: 4.0.1(ts-node@10.9.1) resolve-from: 5.0.0 rollup: 3.28.1 source-map: 0.8.0-beta.0 @@ -9788,6 +9935,10 @@ packages: engines: {node: '>= 0.4.0'} dev: false + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: true + /v8-compile-cache@2.3.0: resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} dev: true @@ -10311,6 +10462,11 @@ packages: y18n: 5.0.8 yargs-parser: 21.1.1 + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: true + /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} diff --git a/scripts/config.js b/scripts/config.ts similarity index 61% rename from scripts/config.js rename to scripts/config.ts index d08838c..03f2d92 100644 --- a/scripts/config.js +++ b/scripts/config.ts @@ -1,13 +1,8 @@ -// @ts-check +import path from 'path' +import { BranchConfig, Package } from './types' -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 = [ +// TODO: List your npm packages here. +export const packages: Package[] = [ { name: '@tanstack/form-core', packageDir: 'packages/form-core', @@ -35,24 +30,31 @@ export const packages = [ // }, ] -/** - * Contains config for publishable branches. - * @type {Record} - */ -export const branchConfigs = { +export const latestBranch = 'main' + +export const branchConfigs: Record = { main: { prerelease: false, + ghRelease: true, }, next: { prerelease: true, + ghRelease: true, }, beta: { prerelease: true, + ghRelease: true, }, alpha: { prerelease: true, + ghRelease: true, }, } -const __dirname = fileURLToPath(new URL('.', import.meta.url)) -export const rootDir = resolve(__dirname, '..') +export const rootDir = path.resolve(__dirname, '..') +export const examplesDirs = [ + 'examples/react', + 'examples/vue', + // 'examples/solid', + // 'examples/svelte', +] diff --git a/scripts/git-log-parser.d.ts b/scripts/git-log-parser.d.ts new file mode 100644 index 0000000..9aeda4c --- /dev/null +++ b/scripts/git-log-parser.d.ts @@ -0,0 +1,46 @@ +declare module 'git-log-parser' { + import { + SpawnOptions, + SpawnOptionsWithoutStdio, + SpawnOptionsWithStdioTuple, + } from 'child_process' + + interface Config { + commit: { + long: 'H' + short: 'h' + } + tree: { + long: 'T' + short: 't' + } + author: { + name: 'an' + email: 'ae' + date: { + key: 'ai' + type: Date + } + } + committer: { + name: 'cn' + email: 'ce' + date: { + key: 'ci' + type: Date + } + } + subject: 's' + body: 'b' + } + + export function parse( + config: object, + options?: + | SpawnOptionsWithoutStdio + | SpawnOptionsWithStdioTuple + | SpawnOptions, + ): NodeJS.ReadableStream + + export const fields: Config +} diff --git a/scripts/project.json b/scripts/project.json deleted file mode 100644 index 2cc7f7f..0000000 --- a/scripts/project.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "../node_modules/nx/schemas/project-schema.json", - "name": "scripts", - "sourceRoot": "scripts", - "targets": { - "test:eslint": { "command": "eslint ./scripts" } - } -} diff --git a/scripts/publish.js b/scripts/publish.js deleted file mode 100644 index 609d086..0000000 --- a/scripts/publish.js +++ /dev/null @@ -1,478 +0,0 @@ -// @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 - // changes to query-core affect query-persist-client-core, which affects react-query-persist-client and then indirectly the sync/async persisters - 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} */ ({})), - ) - .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} - */ -async function readPackageJson(pathName) { - return await jsonfile.readFile(pathName) -} - -/** - * @param {string} pathName - * @param {(json: import('type-fest').PackageJson) => Promise | 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 - } -} diff --git a/scripts/publish.ts b/scripts/publish.ts new file mode 100644 index 0000000..bbf58a6 --- /dev/null +++ b/scripts/publish.ts @@ -0,0 +1,485 @@ +import { + branchConfigs, + examplesDirs, + latestBranch, + packages, + rootDir, +} from './config' +import { BranchConfig, Commit } 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 { 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() as string) + + const branchConfig: 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 = ``; + + 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...`, + ), + ) + + // 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((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 (['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('SKIP_TESTS') || + commit.body.includes('SKIP_TESTS') + ) { + SKIP_TESTS = true + } + + return releaseLevel + }, + -1, + ) + + 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(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, + ), + ) + .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((commits) => [type, commits] 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`, + packages.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('Testing packages...') + execSync(`pnpm test:ci ${SKIP_TESTS ? '|| 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 packages) { + 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 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 + + console.info( + ` Updating ${exampleName}'s dependencies to version ${version}.`, + ) + 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( + packages.map(async (pkg) => { + config.dependencies![pkg.name] = 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 + } + + // 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 + packages.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, +) { + const json = await readPackageJson(pathName) + await transform(json) + await jsonfile.writeFile(pathName, json, { + spaces: 2, + }) +} + +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, '') +} diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json new file mode 100644 index 0000000..2899ee9 --- /dev/null +++ b/scripts/tsconfig.json @@ -0,0 +1,20 @@ +{ + "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 + } + } +} diff --git a/scripts/types.d.ts b/scripts/types.ts similarity index 80% rename from scripts/types.d.ts rename to scripts/types.ts index d01a0ef..a10965a 100644 --- a/scripts/types.d.ts +++ b/scripts/types.ts @@ -1,5 +1,3 @@ -import type { RollupOptions } from 'rollup' - export type Commit = { commit: CommitOrTree tree: CommitOrTree @@ -22,16 +20,16 @@ export type AuthorOrCommitter = { } export type Parsed = { - type: string | null + type: string scope?: string | null subject: string merge?: null header: string body?: null footer?: null - notes?: Array | null - references?: Array | null - mentions?: Array | null + notes?: null[] | null + references?: null[] | null + mentions?: null[] | null revert?: null raw: string } @@ -44,4 +42,5 @@ export type Package = { export type BranchConfig = { prerelease: boolean + ghRelease: boolean } diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000..7546a9d --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "lib": ["ES2022"], + "target": "ES2020", + "module": "ES2020", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "strict": true, + "noUncheckedIndexedAccess": true, + "strictNullChecks": true, + "declaration": true, + "noImplicitReturns": true, + "esModuleInterop": true, + "skipLibCheck": true, + "baseUrl": ".", + "allowUnreachableCode": true, + "paths": { + "@tanstack/form-core": ["packages/form-core"], + "@tanstack/react-form": ["packages/react-form"], + "@tanstack/vue-form": ["packages/vue-form"] + } + }, + "ts-node": { + "compilerOptions": { + "module": "commonjs", + "esModuleInterop": true + } + } +} diff --git a/tsconfig.json b/tsconfig.json index 07c7922..d523343 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,31 +1,10 @@ { - "$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": ["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"] + "files": [], + "references": [ + { "path": "packages/form-core" }, + { "path": "packages/react-form" }, + { "path": "packages/vue-form" } + ] + // "include": ["examples/*"] + // "exclude": ["node_modules"] }