build: move larger scripts into tools dir in workspace (#10653)

Having the `scripts` dir re-use all packages from the top-level was
getting quite unwieldy. Created new `tools` directory that is part of
the workspace. Packages are exported with the `@tools` package
namespace.
This commit is contained in:
Elliot DeNolf
2025-01-20 11:34:51 -05:00
committed by GitHub
parent ef4b8d9b00
commit f18ca9cc2b
32 changed files with 448 additions and 262 deletions

View File

@@ -457,7 +457,9 @@ jobs:
- name: Build Template - name: Build Template
run: | run: |
pnpm run script:pack --dest templates/${{ matrix.template }} pnpm run script:pack --dest templates/${{ matrix.template }}
pnpm runts scripts/build-template-with-local-pkgs.ts ${{ matrix.template }} $POSTGRES_URL pnpm run script:build-template-with-local-pkgs ${{ matrix.template }} $POSTGRES_URL
env:
NODE_OPTIONS: --max-old-space-size=8096
tests-type-generation: tests-type-generation:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04

View File

@@ -68,6 +68,14 @@ export const rootEslintConfig = [
'perfectionist/sort-objects': 'off', 'perfectionist/sort-objects': 'off',
}, },
}, },
{
files: ['tools/**/*.ts'],
rules: {
'no-console': 'off',
'perfectionist/sort-object-types': 'off',
'perfectionist/sort-objects': 'off',
},
},
] ]
export default [ export default [

View File

@@ -28,6 +28,7 @@
"build:live-preview-react": "turbo build --filter \"@payloadcms/live-preview-react\"", "build:live-preview-react": "turbo build --filter \"@payloadcms/live-preview-react\"",
"build:live-preview-vue": "turbo build --filter \"@payloadcms/live-preview-vue\"", "build:live-preview-vue": "turbo build --filter \"@payloadcms/live-preview-vue\"",
"build:next": "turbo build --filter \"@payloadcms/next\"", "build:next": "turbo build --filter \"@payloadcms/next\"",
"build:packages": "turbo build --filter=./packages/*",
"build:payload": "turbo build --filter payload", "build:payload": "turbo build --filter payload",
"build:payload-cloud": "turbo build --filter \"@payloadcms/payload-cloud\"", "build:payload-cloud": "turbo build --filter \"@payloadcms/payload-cloud\"",
"build:plugin-cloud-storage": "turbo build --filter \"@payloadcms/plugin-cloud-storage\"", "build:plugin-cloud-storage": "turbo build --filter \"@payloadcms/plugin-cloud-storage\"",
@@ -40,6 +41,7 @@
"build:plugin-seo": "turbo build --filter \"@payloadcms/plugin-seo\"", "build:plugin-seo": "turbo build --filter \"@payloadcms/plugin-seo\"",
"build:plugin-stripe": "turbo build --filter \"@payloadcms/plugin-stripe\"", "build:plugin-stripe": "turbo build --filter \"@payloadcms/plugin-stripe\"",
"build:plugins": "turbo build --filter \"@payloadcms/plugin-*\"", "build:plugins": "turbo build --filter \"@payloadcms/plugin-*\"",
"build:releaser": "turbo build --filter \"@tools/releaser\"",
"build:richtext-lexical": "turbo build --filter \"@payloadcms/richtext-lexical\"", "build:richtext-lexical": "turbo build --filter \"@payloadcms/richtext-lexical\"",
"build:richtext-slate": "turbo build --filter \"@payloadcms/richtext-slate\"", "build:richtext-slate": "turbo build --filter \"@payloadcms/richtext-slate\"",
"build:storage-azure": "turbo build --filter \"@payloadcms/storage-azure\"", "build:storage-azure": "turbo build --filter \"@payloadcms/storage-azure\"",
@@ -48,6 +50,7 @@
"build:storage-uploadthing": "turbo build --filter \"@payloadcms/storage-uploadthing\"", "build:storage-uploadthing": "turbo build --filter \"@payloadcms/storage-uploadthing\"",
"build:storage-vercel-blob": "turbo build --filter \"@payloadcms/storage-vercel-blob\"", "build:storage-vercel-blob": "turbo build --filter \"@payloadcms/storage-vercel-blob\"",
"build:tests": "pnpm --filter payload-test-suite run typecheck", "build:tests": "pnpm --filter payload-test-suite run typecheck",
"build:tools": "turbo build --filter=./tools/*",
"build:translations": "turbo build --filter \"@payloadcms/translations\"", "build:translations": "turbo build --filter \"@payloadcms/translations\"",
"build:ui": "turbo build --filter \"@payloadcms/ui\"", "build:ui": "turbo build --filter \"@payloadcms/ui\"",
"clean": "turbo clean", "clean": "turbo clean",
@@ -77,12 +80,13 @@
"prepare-run-test-against-prod": "pnpm bf && rm -rf test/packed && rm -rf test/node_modules && rm -rf app && rm -f test/pnpm-lock.yaml && pnpm run script:pack --all --no-build --dest test/packed && pnpm runts test/setupProd.ts && cd test && pnpm i --ignore-workspace && cd ..", "prepare-run-test-against-prod": "pnpm bf && rm -rf test/packed && rm -rf test/node_modules && rm -rf app && rm -f test/pnpm-lock.yaml && pnpm run script:pack --all --no-build --dest test/packed && pnpm runts test/setupProd.ts && cd test && pnpm i --ignore-workspace && cd ..",
"prepare-run-test-against-prod:ci": "rm -rf test/node_modules && rm -rf app && rm -f test/pnpm-lock.yaml && pnpm run script:pack --all --no-build --dest test/packed && pnpm runts test/setupProd.ts && cd test && pnpm i --ignore-workspace && cd ..", "prepare-run-test-against-prod:ci": "rm -rf test/node_modules && rm -rf app && rm -f test/pnpm-lock.yaml && pnpm run script:pack --all --no-build --dest test/packed && pnpm runts test/setupProd.ts && cd test && pnpm i --ignore-workspace && cd ..",
"reinstall": "pnpm clean:all && pnpm install", "reinstall": "pnpm clean:all && pnpm install",
"release": "pnpm runts ./scripts/release.ts --tag latest", "release": "pnpm --filter releaser release --tag latest",
"release:beta": "pnpm runts ./scripts/release.ts --bump prerelease --tag beta", "release:beta": "pnpm runts ./scripts/release.ts --bump prerelease --tag beta",
"runts": "cross-env NODE_OPTIONS=--no-deprecation node --no-deprecation --import @swc-node/register/esm-register", "runts": "cross-env NODE_OPTIONS=--no-deprecation node --no-deprecation --import @swc-node/register/esm-register",
"script:gen-templates": "pnpm runts ./scripts/generate-template-variations.ts", "script:build-template-with-local-pkgs": "pnpm --filter scripts build-template-with-local-pkgs",
"script:list-published": "pnpm runts scripts/lib/getPackageRegistryVersions.ts", "script:gen-templates": "pnpm --filter scripts gen-templates",
"script:pack": "pnpm runts scripts/pack-all-to-dest.ts", "script:list-published": "pnpm --filter releaser list-published",
"script:pack": "pnpm --filter scripts pack-all-to-dest",
"pretest": "pnpm build", "pretest": "pnpm build",
"test": "pnpm test:int && pnpm test:components && pnpm test:e2e", "test": "pnpm test:int && pnpm test:components && pnpm test:e2e",
"test:components": "cross-env NODE_OPTIONS=\" --no-deprecation\" jest --config=jest.components.config.js", "test:components": "cross-env NODE_OPTIONS=\" --no-deprecation\" jest --config=jest.components.config.js",
@@ -127,13 +131,10 @@
"@types/jest": "29.5.12", "@types/jest": "29.5.12",
"@types/minimist": "1.2.5", "@types/minimist": "1.2.5",
"@types/node": "22.5.4", "@types/node": "22.5.4",
"@types/prompts": "^2.4.5",
"@types/react": "19.0.1", "@types/react": "19.0.1",
"@types/react-dom": "19.0.1", "@types/react-dom": "19.0.1",
"@types/semver": "^7.5.3",
"@types/shelljs": "0.8.15", "@types/shelljs": "0.8.15",
"chalk": "^4.1.2", "chalk": "^4.1.2",
"changelogen": "^0.5.5",
"comment-json": "^4.2.3", "comment-json": "^4.2.3",
"copyfiles": "2.4.1", "copyfiles": "2.4.1",
"create-payload-app": "workspace:*", "create-payload-app": "workspace:*",
@@ -157,11 +158,9 @@
"playwright": "1.49.1", "playwright": "1.49.1",
"playwright-core": "1.49.1", "playwright-core": "1.49.1",
"prettier": "3.3.3", "prettier": "3.3.3",
"prompts": "2.4.2",
"react": "19.0.0", "react": "19.0.0",
"react-dom": "19.0.0", "react-dom": "19.0.0",
"rimraf": "6.0.1", "rimraf": "6.0.1",
"semver": "^7.5.4",
"sharp": "0.32.6", "sharp": "0.32.6",
"shelljs": "0.8.5", "shelljs": "0.8.5",
"slash": "3.0.0", "slash": "3.0.0",

119
pnpm-lock.yaml generated
View File

@@ -45,7 +45,7 @@ importers:
version: 1.49.1 version: 1.49.1
'@sentry/nextjs': '@sentry/nextjs':
specifier: ^8.33.1 specifier: ^8.33.1
version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.1.5(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4))(react@19.0.0)(webpack@5.96.1(@swc/core@1.9.3(@swc/helpers@0.5.15))) version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.1.5(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4))(react@19.0.0)(webpack@5.96.1(@swc/core@1.9.3(@swc/helpers@0.5.15)))
'@sentry/node': '@sentry/node':
specifier: ^8.33.1 specifier: ^8.33.1
version: 8.37.1 version: 8.37.1
@@ -70,27 +70,18 @@ importers:
'@types/node': '@types/node':
specifier: 22.5.4 specifier: 22.5.4
version: 22.5.4 version: 22.5.4
'@types/prompts':
specifier: ^2.4.5
version: 2.4.9
'@types/react': '@types/react':
specifier: 19.0.1 specifier: 19.0.1
version: 19.0.1 version: 19.0.1
'@types/react-dom': '@types/react-dom':
specifier: 19.0.1 specifier: 19.0.1
version: 19.0.1 version: 19.0.1
'@types/semver':
specifier: ^7.5.3
version: 7.5.8
'@types/shelljs': '@types/shelljs':
specifier: 0.8.15 specifier: 0.8.15
version: 0.8.15 version: 0.8.15
chalk: chalk:
specifier: ^4.1.2 specifier: ^4.1.2
version: 4.1.2 version: 4.1.2
changelogen:
specifier: ^0.5.5
version: 0.5.7
comment-json: comment-json:
specifier: ^4.2.3 specifier: ^4.2.3
version: 4.2.5 version: 4.2.5
@@ -144,7 +135,7 @@ importers:
version: 10.1.3(@aws-sdk/credential-providers@3.687.0(@aws-sdk/client-sso-oidc@3.687.0(@aws-sdk/client-sts@3.687.0)))(socks@2.8.3) version: 10.1.3(@aws-sdk/credential-providers@3.687.0(@aws-sdk/client-sso-oidc@3.687.0(@aws-sdk/client-sts@3.687.0)))(socks@2.8.3)
next: next:
specifier: 15.1.5 specifier: 15.1.5
version: 15.1.5(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4) version: 15.1.5(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4)
open: open:
specifier: ^10.1.0 specifier: ^10.1.0
version: 10.1.0 version: 10.1.0
@@ -160,9 +151,6 @@ importers:
prettier: prettier:
specifier: 3.3.3 specifier: 3.3.3
version: 3.3.3 version: 3.3.3
prompts:
specifier: 2.4.2
version: 2.4.2
react: react:
specifier: 19.0.0 specifier: 19.0.0
version: 19.0.0 version: 19.0.0
@@ -172,9 +160,6 @@ importers:
rimraf: rimraf:
specifier: 6.0.1 specifier: 6.0.1
version: 6.0.1 version: 6.0.1
semver:
specifier: ^7.5.4
version: 7.6.3
sharp: sharp:
specifier: 0.32.6 specifier: 0.32.6
version: 0.32.6 version: 0.32.6
@@ -1020,7 +1005,7 @@ importers:
dependencies: dependencies:
next: next:
specifier: ^15.0.3 specifier: ^15.0.3
version: 15.1.3(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4) version: 15.1.3(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4)
devDependencies: devDependencies:
'@payloadcms/eslint-config': '@payloadcms/eslint-config':
specifier: workspace:* specifier: workspace:*
@@ -1082,7 +1067,7 @@ importers:
dependencies: dependencies:
'@sentry/nextjs': '@sentry/nextjs':
specifier: ^8.33.1 specifier: ^8.33.1
version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.1.5(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4))(react@19.0.0)(webpack@5.96.1(@swc/core@1.9.3(@swc/helpers@0.5.15))) version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.1.5(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4))(react@19.0.0)(webpack@5.96.1(@swc/core@1.9.3(@swc/helpers@0.5.15)))
'@sentry/types': '@sentry/types':
specifier: ^8.33.1 specifier: ^8.33.1
version: 8.37.1 version: 8.37.1
@@ -1432,7 +1417,7 @@ importers:
version: link:../plugin-cloud-storage version: link:../plugin-cloud-storage
uploadthing: uploadthing:
specifier: 7.3.0 specifier: 7.3.0
version: 7.3.0(next@15.1.5(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4)) version: 7.3.0(next@15.1.5(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4))
devDependencies: devDependencies:
payload: payload:
specifier: workspace:* specifier: workspace:*
@@ -1712,10 +1697,13 @@ importers:
version: link:../packages/ui version: link:../packages/ui
'@sentry/nextjs': '@sentry/nextjs':
specifier: ^8.33.1 specifier: ^8.33.1
version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.1.5(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4))(react@19.0.0)(webpack@5.96.1(@swc/core@1.9.3(@swc/helpers@0.5.15))) version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.1.5(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4))(react@19.0.0)(webpack@5.96.1(@swc/core@1.9.3(@swc/helpers@0.5.15)))
'@sentry/react': '@sentry/react':
specifier: ^7.77.0 specifier: ^7.77.0
version: 7.119.2(react@19.0.0) version: 7.119.2(react@19.0.0)
'@types/jest':
specifier: 29.5.12
version: 29.5.12
'@types/react': '@types/react':
specifier: 19.0.1 specifier: 19.0.1
version: 19.0.1 version: 19.0.1
@@ -1749,6 +1737,9 @@ importers:
http-status: http-status:
specifier: 1.6.2 specifier: 1.6.2
version: 1.6.2 version: 1.6.2
jest:
specifier: 29.7.0
version: 29.7.0(@types/node@22.5.4)(babel-plugin-macros@3.1.0)
jwt-decode: jwt-decode:
specifier: 4.0.0 specifier: 4.0.0
version: 4.0.0 version: 4.0.0
@@ -1757,7 +1748,7 @@ importers:
version: 8.9.5(@aws-sdk/credential-providers@3.687.0(@aws-sdk/client-sso-oidc@3.687.0(@aws-sdk/client-sts@3.687.0)))(socks@2.8.3) version: 8.9.5(@aws-sdk/credential-providers@3.687.0(@aws-sdk/client-sso-oidc@3.687.0(@aws-sdk/client-sts@3.687.0)))(socks@2.8.3)
next: next:
specifier: 15.1.5 specifier: 15.1.5
version: 15.1.5(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4) version: 15.1.5(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4)
nodemailer: nodemailer:
specifier: 6.9.16 specifier: 6.9.16
version: 6.9.16 version: 6.9.16
@@ -1792,6 +1783,78 @@ importers:
specifier: 10.0.0 specifier: 10.0.0
version: 10.0.0 version: 10.0.0
tools/constants: {}
tools/releaser:
dependencies:
'@swc-node/register':
specifier: 1.10.9
version: 1.10.9(@swc/core@1.9.3(@swc/helpers@0.5.15))(@swc/types@0.1.17)(typescript@5.7.3)
'@tools/constants':
specifier: workspace:*
version: link:../constants
chalk:
specifier: ^4.1.2
version: 4.1.2
changelogen:
specifier: ^0.5.5
version: 0.5.7
execa:
specifier: 5.1.1
version: 5.1.1
minimist:
specifier: 1.2.8
version: 1.2.8
open:
specifier: ^10.1.0
version: 10.1.0
p-limit:
specifier: ^5.0.0
version: 5.0.0
prompts:
specifier: 2.4.2
version: 2.4.2
semver:
specifier: ^7.5.4
version: 7.6.3
tsx:
specifier: ^4.19.2
version: 4.19.2
devDependencies:
'@types/minimist':
specifier: 1.2.5
version: 1.2.5
'@types/prompts':
specifier: ^2.4.5
version: 2.4.9
'@types/semver':
specifier: ^7.5.3
version: 7.5.8
tools/scripts:
dependencies:
'@swc-node/register':
specifier: 1.10.9
version: 1.10.9(@swc/core@1.9.3(@swc/helpers@0.5.15))(@swc/types@0.1.17)(typescript@5.7.3)
'@tools/constants':
specifier: workspace:*
version: link:../constants
'@tools/releaser':
specifier: workspace:*
version: link:../releaser
chalk:
specifier: ^4.1.2
version: 4.1.2
changelogen:
specifier: ^0.5.5
version: 0.5.7
create-payload-app:
specifier: workspace:*
version: link:../../packages/create-payload-app
open:
specifier: ^10.1.0
version: 10.1.0
packages: packages:
'@ampproject/remapping@2.3.0': '@ampproject/remapping@2.3.0':
@@ -13458,7 +13521,7 @@ snapshots:
'@sentry/utils': 7.119.2 '@sentry/utils': 7.119.2
localforage: 1.10.0 localforage: 1.10.0
'@sentry/nextjs@8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.1.5(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4))(react@19.0.0)(webpack@5.96.1(@swc/core@1.9.3(@swc/helpers@0.5.15)))': '@sentry/nextjs@8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.1.5(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4))(react@19.0.0)(webpack@5.96.1(@swc/core@1.9.3(@swc/helpers@0.5.15)))':
dependencies: dependencies:
'@opentelemetry/api': 1.9.0 '@opentelemetry/api': 1.9.0
'@opentelemetry/instrumentation-http': 0.53.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-http': 0.53.0(@opentelemetry/api@1.9.0)
@@ -13474,7 +13537,7 @@ snapshots:
'@sentry/vercel-edge': 8.37.1 '@sentry/vercel-edge': 8.37.1
'@sentry/webpack-plugin': 2.22.6(webpack@5.96.1(@swc/core@1.9.3(@swc/helpers@0.5.15))) '@sentry/webpack-plugin': 2.22.6(webpack@5.96.1(@swc/core@1.9.3(@swc/helpers@0.5.15)))
chalk: 3.0.0 chalk: 3.0.0
next: 15.1.5(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4) next: 15.1.5(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4)
resolve: 1.22.8 resolve: 1.22.8
rollup: 3.29.5 rollup: 3.29.5
stacktrace-parser: 0.1.10 stacktrace-parser: 0.1.10
@@ -17973,7 +18036,7 @@ snapshots:
- '@babel/core' - '@babel/core'
- babel-plugin-macros - babel-plugin-macros
next@15.1.3(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4): next@15.1.3(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4):
dependencies: dependencies:
'@next/env': 15.1.3 '@next/env': 15.1.3
'@swc/counter': 0.1.3 '@swc/counter': 0.1.3
@@ -18001,7 +18064,7 @@ snapshots:
- '@babel/core' - '@babel/core'
- babel-plugin-macros - babel-plugin-macros
next@15.1.5(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4): next@15.1.5(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4):
dependencies: dependencies:
'@next/env': 15.1.5 '@next/env': 15.1.5
'@swc/counter': 0.1.3 '@swc/counter': 0.1.3
@@ -19667,14 +19730,14 @@ snapshots:
escalade: 3.2.0 escalade: 3.2.0
picocolors: 1.1.1 picocolors: 1.1.1
uploadthing@7.3.0(next@15.1.5(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4)): uploadthing@7.3.0(next@15.1.5(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4)):
dependencies: dependencies:
'@effect/platform': 0.69.8(effect@3.10.3) '@effect/platform': 0.69.8(effect@3.10.3)
'@uploadthing/mime-types': 0.3.2 '@uploadthing/mime-types': 0.3.2
'@uploadthing/shared': 7.1.1 '@uploadthing/shared': 7.1.1
effect: 3.10.3 effect: 3.10.3
optionalDependencies: optionalDependencies:
next: 15.1.5(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4) next: 15.1.5(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4)
uri-js@4.4.1: uri-js@4.4.1:
dependencies: dependencies:

View File

@@ -1,6 +1,7 @@
packages: packages:
# all packages in direct subdirs of packages/ # all packages in direct subdirs of packages/
- 'packages/*' - 'packages/*'
- 'tools/*'
- 'test' - 'test'
# exclude packages that are inside test directories # exclude packages that are inside test directories
# - '!**/test/**' # - '!**/test/**'

View File

@@ -1,58 +0,0 @@
import type { ExecSyncOptions } from 'child_process'
import type execa from 'execa'
import chalk from 'chalk'
import minimist from 'minimist'
import { fileURLToPath } from 'node:url'
import pLimit from 'p-limit'
import path from 'path'
import { getWorkspace } from './lib/getWorkspace.js'
const npmPublishLimit = pLimit(5)
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
const cwd = path.resolve(dirname, '..')
const execOpts: ExecSyncOptions = { stdio: 'inherit' }
const execaOpts: execa.Options = { stdio: 'inherit' }
const args = minimist(process.argv.slice(2))
// const {
// bump = 'patch', // Semver release type
// changelog = false, // Whether to update the changelog. WARNING: This gets throttled on too many commits
// 'dry-run': dryRun,
// 'git-tag': gitTag = true, // Whether to run git tag and commit operations
// 'git-commit': gitCommit = true, // Whether to run git commit operations
// tag = 'latest',
// } = args
const dryRun = true
async function main() {
const workspace = await getWorkspace()
await workspace.bumpVersion('canary')
await workspace.build()
await workspace.publishSync({ dryRun: false, tag: 'canary' })
header('🎉 Done!')
}
main().catch((error) => {
console.error(error)
process.exit(1)
})
function abort(message = 'Abort', exitCode = 1) {
console.error(chalk.bold.red(`\n${message}\n`))
process.exit(exitCode)
}
function header(message: string, opts?: { enable?: boolean }) {
const { enable } = opts ?? {}
if (!enable) return
console.log(chalk.bold.green(`${message}\n`))
}

View File

@@ -80,13 +80,13 @@ const app = nextImport({
const handle = app.getRequestHandler() const handle = app.getRequestHandler()
let resolveServer let resolveServer: () => void
const serverPromise = new Promise((res) => (resolveServer = res)) const serverPromise = new Promise<void>((res) => (resolveServer = res))
void app.prepare().then(() => { void app.prepare().then(() => {
createServer(async (req, res) => { createServer(async (req, res) => {
const parsedUrl = parse(req.url, true) const parsedUrl = parse(req.url || '', true)
await handle(req, res, parsedUrl) await handle(req, res, parsedUrl)
}).listen(port, () => { }).listen(port, () => {
resolveServer() resolveServer()

View File

@@ -1,3 +1,4 @@
import { jest } from '@jest/globals'
import console from 'console' import console from 'console'
global.console = console global.console = console

View File

@@ -58,6 +58,7 @@
"@payloadcms/ui": "workspace:*", "@payloadcms/ui": "workspace:*",
"@sentry/nextjs": "^8.33.1", "@sentry/nextjs": "^8.33.1",
"@sentry/react": "^7.77.0", "@sentry/react": "^7.77.0",
"@types/jest": "29.5.12",
"@types/react": "19.0.1", "@types/react": "19.0.1",
"@types/react-dom": "19.0.1", "@types/react-dom": "19.0.1",
"babel-plugin-react-compiler": "19.0.0-beta-df7b47d-20241124", "babel-plugin-react-compiler": "19.0.0-beta-df7b47d-20241124",
@@ -69,6 +70,7 @@
"execa": "5.1.1", "execa": "5.1.1",
"file-type": "19.3.0", "file-type": "19.3.0",
"http-status": "1.6.2", "http-status": "1.6.2",
"jest": "29.7.0",
"jwt-decode": "4.0.0", "jwt-decode": "4.0.0",
"mongoose": "8.9.5", "mongoose": "8.9.5",
"next": "15.1.5", "next": "15.1.5",

View File

@@ -0,0 +1,17 @@
{
"name": "@tools/constants",
"version": "0.0.1",
"description": "",
"keywords": [],
"license": "ISC",
"author": "",
"type": "module",
"exports": {
".": {
"import": "./src/index.ts"
}
},
"scripts": {
"build": "tsc"
}
}

View File

@@ -0,0 +1,13 @@
import { fileURLToPath } from 'node:url'
import path from 'path'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
/**
* Path to the project root
*/
export const PROJECT_ROOT = path.resolve(dirname, '../../../')
export const ROOT_PACKAGE_JSON = path.resolve(PROJECT_ROOT, 'package.json')
export const PACKAGES_DIR = path.resolve(PROJECT_ROOT, 'packages')
export const TEMPLATES_DIR = path.resolve(PROJECT_ROOT, 'templates')

View File

@@ -0,0 +1,6 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"strict": true,
}
}

View File

@@ -0,0 +1,53 @@
{
"name": "@tools/releaser",
"version": "0.0.1",
"description": "",
"keywords": [],
"license": "ISC",
"author": "",
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",
"types": "./src/index.ts",
"default": "./src/index.ts"
},
"./lib": {
"import": "./src/lib/*.ts",
"types": "./src/lib/*.ts",
"default": "./src/lib/*.ts"
},
"./utils": {
"import": "./src/utils/*.ts",
"types": "./src/utils/*.ts",
"default": "./src/utils/*.ts"
}
},
"main": "src/index.ts",
"scripts": {
"build": "tsc",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"list-published": "tsx src/lib/getPackageRegistryVersions.ts",
"release": "tsx src/release.ts",
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"@swc-node/register": "1.10.9",
"@tools/constants": "workspace:*",
"chalk": "^4.1.2",
"changelogen": "^0.5.5",
"execa": "5.1.1",
"minimist": "1.2.8",
"open": "^10.1.0",
"p-limit": "^5.0.0",
"prompts": "2.4.2",
"semver": "^7.5.4",
"tsx": "^4.19.2"
},
"devDependencies": {
"@types/minimist": "1.2.5",
"@types/prompts": "^2.4.5",
"@types/semver": "^7.5.3"
}
}

View File

@@ -0,0 +1,2 @@
export { getPackageDetails } from './lib/getPackageDetails.js'
export type { PackageDetails } from './lib/getPackageDetails.js'

View File

@@ -1,12 +1,7 @@
import { PROJECT_ROOT } from '@tools/constants'
import fse from 'fs-extra' import fse from 'fs-extra'
import globby from 'globby' import globby from 'globby'
import path, { dirname } from 'path' import path, { dirname } from 'path'
import { fileURLToPath } from 'url'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const projectRoot = path.resolve(__dirname, '../../')
export type PackageDetails = { export type PackageDetails = {
/** Name in package.json / npm registry */ /** Name in package.json / npm registry */
@@ -22,10 +17,10 @@ export type PackageDetails = {
/** /**
* Accepts package whitelist (directory names inside packages dir) and returns details for each package * Accepts package whitelist (directory names inside packages dir) and returns details for each package
*/ */
export const getPackageDetails = async (packages: string[]): Promise<PackageDetails[]> => { export const getPackageDetails = async (packages?: null | string[]): Promise<PackageDetails[]> => {
// Fetch all package.json files, filter out packages not in the whitelist // Fetch all package.json files, filter out packages not in the whitelist
const packageJsons = await globby('packages/*/package.json', { const packageJsons = await globby('packages/*/package.json', {
cwd: projectRoot, cwd: PROJECT_ROOT,
absolute: true, absolute: true,
}) })
@@ -33,16 +28,20 @@ export const getPackageDetails = async (packages: string[]): Promise<PackageDeta
packageJsons.map(async (packageJsonPath) => { packageJsons.map(async (packageJsonPath) => {
const packageJson = await fse.readJson(packageJsonPath) const packageJson = await fse.readJson(packageJsonPath)
const isPublic = packageJson.private !== true const isPublic = packageJson.private !== true
if (!isPublic) return null if (!isPublic) {
return null
}
const isInWhitelist = packages const isInWhitelist = packages
? packages.includes(path.basename(path.dirname(packageJsonPath))) ? packages.includes(path.basename(path.dirname(packageJsonPath)))
: true : true
if (!isInWhitelist) return null if (!isInWhitelist) {
return null
}
return { return {
name: packageJson.name as string, name: packageJson.name as string,
packagePath: path.relative(projectRoot, dirname(packageJsonPath)), packagePath: path.relative(PROJECT_ROOT, dirname(packageJsonPath)),
shortName: path.dirname(packageJsonPath), shortName: path.dirname(packageJsonPath),
version: packageJson.version, version: packageJson.version,
} as PackageDetails } as PackageDetails

View File

@@ -150,6 +150,12 @@ export const getWorkspace = async () => {
nextReleaseVersion = semver.inc(monorepoVersion, bumpType) nextReleaseVersion = semver.inc(monorepoVersion, bumpType)
} }
if (!nextReleaseVersion) {
throw new Error(
`Invalid bump type: ${bumpType}. Could not determine next version from ${monorepoVersion}.`,
)
}
console.log(`\n Version: ${monorepoVersion} => ${nextReleaseVersion}\n`) console.log(`\n Version: ${monorepoVersion} => ${nextReleaseVersion}\n`)
console.log(` Bump: ${bumpType}`) console.log(` Bump: ${bumpType}`)
console.log(` Changes (${packageDetails.length} packages):\n`) console.log(` Changes (${packageDetails.length} packages):\n`)

View File

@@ -0,0 +1,31 @@
import chalk from 'chalk'
import { getWorkspace } from './lib/getWorkspace.js'
async function main() {
const workspace = await getWorkspace()
await workspace.bumpVersion('canary')
await workspace.build()
await workspace.publishSync({ dryRun: false, tag: 'canary' })
header('🎉 Done!')
}
main().catch((error) => {
console.error(error)
process.exit(1)
})
function abort(message = 'Abort', exitCode = 1) {
console.error(chalk.bold.red(`\n${message}\n`))
process.exit(exitCode)
}
function header(message: string, opts?: { enable?: boolean }) {
const { enable } = opts ?? {}
if (!enable) {
return
}
console.log(chalk.bold.green(`${message}\n`))
}

View File

@@ -7,13 +7,13 @@
import type { ExecSyncOptions } from 'child_process' import type { ExecSyncOptions } from 'child_process'
import { PROJECT_ROOT, ROOT_PACKAGE_JSON } from '@tools/constants'
import chalk from 'chalk' import chalk from 'chalk'
import { loadChangelogConfig } from 'changelogen' import { loadChangelogConfig } from 'changelogen'
import { execSync } from 'child_process' import { execSync } from 'child_process'
import execa from 'execa' import execa from 'execa'
import fse from 'fs-extra' import fse from 'fs-extra'
import minimist from 'minimist' import minimist from 'minimist'
import { fileURLToPath } from 'node:url'
import path from 'path' import path from 'path'
import prompts from 'prompts' import prompts from 'prompts'
import semver from 'semver' import semver from 'semver'
@@ -26,12 +26,10 @@ import { createDraftGitHubRelease } from './utils/createDraftGitHubRelease.js'
import { generateReleaseNotes } from './utils/generateReleaseNotes.js' import { generateReleaseNotes } from './utils/generateReleaseNotes.js'
import { getRecommendedBump } from './utils/getRecommendedBump.js' import { getRecommendedBump } from './utils/getRecommendedBump.js'
const filename = fileURLToPath(import.meta.url) // Always execute in project root
const dirname = path.dirname(filename) const cwd = PROJECT_ROOT
const cwd = path.resolve(dirname, '..') const execOpts: ExecSyncOptions = { stdio: 'inherit', cwd }
const execaOpts: execa.Options = { stdio: 'inherit', cwd }
const execOpts: ExecSyncOptions = { stdio: 'inherit' }
const execaOpts: execa.Options = { stdio: 'inherit' }
const args = minimist(process.argv.slice(2)) const args = minimist(process.argv.slice(2))
@@ -39,8 +37,8 @@ const {
bump, // Semver release type: major, minor, patch, premajor, preminor, prepatch, prerelease bump, // Semver release type: major, minor, patch, premajor, preminor, prepatch, prerelease
changelog = false, // Whether to update the changelog. WARNING: This gets throttled on too many commits changelog = false, // Whether to update the changelog. WARNING: This gets throttled on too many commits
'dry-run': dryRun, 'dry-run': dryRun,
'git-tag': gitTag = true, // Whether to run git tag and commit operations
'git-commit': gitCommit = true, // Whether to run git commit operations 'git-commit': gitCommit = true, // Whether to run git commit operations
'git-tag': gitTag = true, // Whether to run git tag and commit operations
tag, // Tag to publish to: latest, beta, canary tag, // Tag to publish to: latest, beta, canary
} = args } = args
@@ -67,6 +65,8 @@ const cmdRunnerAsync =
} }
async function main() { async function main() {
console.log({ projectRoot: PROJECT_ROOT })
if (!process.env.GITHUB_TOKEN) { if (!process.env.GITHUB_TOKEN) {
throw new Error('GITHUB_TOKEN env var is required') throw new Error('GITHUB_TOKEN env var is required')
} }
@@ -108,7 +108,7 @@ async function main() {
abort(`Prerelease bumps must have tag: beta or canary`) abort(`Prerelease bumps must have tag: beta or canary`)
} }
const monorepoVersion = fse.readJSONSync('package.json')?.version const monorepoVersion = fse.readJSONSync(ROOT_PACKAGE_JSON)?.version
if (!monorepoVersion) { if (!monorepoVersion) {
throw new Error('Could not find version in package.json') throw new Error('Could not find version in package.json')
@@ -125,14 +125,14 @@ async function main() {
header(`${logPrefix}📝 Updating changelog...`) header(`${logPrefix}📝 Updating changelog...`)
const { const {
changelog: changelogContent, changelog: changelogContent,
releaseUrl: prefilledReleaseUrl,
releaseNotes, releaseNotes,
releaseUrl: prefilledReleaseUrl,
} = await generateReleaseNotes({ } = await generateReleaseNotes({
bump, bump,
dryRun, dryRun,
toVersion: 'HEAD',
fromVersion, fromVersion,
openReleaseUrl: true, openReleaseUrl: true,
toVersion: 'HEAD',
}) })
console.log(chalk.green('\nFull Release Notes:\n\n')) console.log(chalk.green('\nFull Release Notes:\n\n'))
@@ -160,7 +160,8 @@ async function main() {
await execa('pnpm', ['install'], execaOpts) await execa('pnpm', ['install'], execaOpts)
const buildResult = await execa('pnpm', ['build:all', '--output-logs=errors-only'], execaOpts) // const buildResult = await execa('pnpm', ['build:all', '--output-logs=errors-only'], execaOpts)
const buildResult = await execa('pnpm', ['build:all'], execaOpts)
if (buildResult.exitCode !== 0) { if (buildResult.exitCode !== 0) {
console.error(chalk.bold.red('Build failed')) console.error(chalk.bold.red('Build failed'))
console.log(buildResult.stderr) console.log(buildResult.stderr)
@@ -171,21 +172,21 @@ async function main() {
header(`${logPrefix}📦 Updating package.json versions...`) header(`${logPrefix}📦 Updating package.json versions...`)
await Promise.all( await Promise.all(
packageDetails.map(async (pkg) => { packageDetails.map(async (pkg) => {
const packageJson = await fse.readJSON(`${pkg.packagePath}/package.json`) const packageJsonPath = path.join(PROJECT_ROOT, `${pkg.packagePath}/package.json`)
const packageJson = await fse.readJSON(packageJsonPath)
packageJson.version = nextReleaseVersion packageJson.version = nextReleaseVersion
if (!dryRun) { if (!dryRun) {
await fse.writeJSON(`${pkg.packagePath}/package.json`, packageJson, { spaces: 2 }) await fse.writeJSON(packageJsonPath, packageJson, { spaces: 2 })
} }
}), }),
) )
// Set version in root package.json // Set version in root package.json
header(`${logPrefix}📦 Updating root package.json...`) header(`${logPrefix}📦 Updating root package.json...`)
const rootPackageJsonPath = path.resolve(dirname, '../package.json') const rootPackageJson = await fse.readJSON(ROOT_PACKAGE_JSON)
const rootPackageJson = await fse.readJSON(rootPackageJsonPath)
rootPackageJson.version = nextReleaseVersion rootPackageJson.version = nextReleaseVersion
if (!dryRun) { if (!dryRun) {
await fse.writeJSON(rootPackageJsonPath, rootPackageJson, { spaces: 2 }) await fse.writeJSON(ROOT_PACKAGE_JSON, rootPackageJson, { spaces: 2 })
} }
// Commit // Commit
@@ -241,15 +242,19 @@ async function main() {
try { try {
const { releaseUrl: draftReleaseUrl } = await createDraftGitHubRelease({ const { releaseUrl: draftReleaseUrl } = await createDraftGitHubRelease({
branch: 'main', branch: 'main',
tag: `v${nextReleaseVersion}`,
releaseNotes, releaseNotes,
tag: `v${nextReleaseVersion}`,
}) })
console.log(chalk.bold.green(`Draft release created on GitHub: ${draftReleaseUrl}`)) console.log(chalk.bold.green(`Draft release created on GitHub: ${draftReleaseUrl}`))
} catch (error) { } catch (error: unknown) {
console.log(chalk.bold.red('\nFull Release Notes:\n\n')) console.log(chalk.bold.red('\nFull Release Notes:\n\n'))
console.log(chalk.gray(releaseNotes) + '\n\n') console.log(chalk.gray(releaseNotes) + '\n\n')
console.log(`\n\nRelease URL: ${chalk.dim(prefilledReleaseUrl)}`) console.log(`\n\nRelease URL: ${chalk.dim(prefilledReleaseUrl)}`)
console.log(chalk.bold.red(`Error creating draft release on GitHub: ${error.message}`)) console.log(
chalk.bold.red(
`Error creating draft release on GitHub: ${error instanceof Error ? error.message : JSON.stringify(error)}`,
),
)
console.log( console.log(
chalk.bold.red( chalk.bold.red(
`Use the above link to create the release manually and optionally add the release notes.`, `Use the above link to create the release manually and optionally add the release notes.`,
@@ -273,6 +278,7 @@ async function publishSinglePackage(pkg: PackageDetails, opts?: { dryRun?: boole
const cmdArgs = ['publish', '-C', pkg.packagePath, '--no-git-checks', '--json', '--tag', tag] const cmdArgs = ['publish', '-C', pkg.packagePath, '--no-git-checks', '--json', '--tag', tag]
if (dryRun) { if (dryRun) {
cmdArgs.push('--dry-run') cmdArgs.push('--dry-run')
console.log(chalk.gray(`\n${logPrefix} pnpm ${cmdArgs.join(' ')}\n`))
} }
const { exitCode, stderr } = await execa('pnpm', cmdArgs, { const { exitCode, stderr } = await execa('pnpm', cmdArgs, {
cwd, cwd,
@@ -300,8 +306,8 @@ async function publishSinglePackage(pkg: PackageDetails, opts?: { dryRun?: boole
return { return {
name: pkg.name, name: pkg.name,
success: false,
details: `Exit Code: ${retryExitCode}, stderr: ${retryStdError}`, details: `Exit Code: ${retryExitCode}, stderr: ${retryStdError}`,
success: false,
} }
} }
@@ -311,11 +317,11 @@ async function publishSinglePackage(pkg: PackageDetails, opts?: { dryRun?: boole
console.error(err) console.error(err)
return { return {
name: pkg.name, name: pkg.name,
success: false,
details: details:
err instanceof Error err instanceof Error
? `Error publishing ${pkg.name}: ${err.message}` ? `Error publishing ${pkg.name}: ${err.message}`
: `Unexpected error publishing ${pkg.name}: ${JSON.stringify(err)}`, : `Unexpected error publishing ${pkg.name}: ${JSON.stringify(err)}`,
success: false,
} }
} }
} }
@@ -370,7 +376,7 @@ function header(message: string, opts?: { enable?: boolean }) {
} }
type PublishResult = { type PublishResult = {
details?: string
name: string name: string
success: boolean success: boolean
details?: string
} }

View File

@@ -1,7 +1,6 @@
import type { GitCommit } from 'changelogen' import type { GitCommit } from 'changelogen'
import { execSync } from 'child_process' import { execSync } from 'child_process'
import fse from 'fs-extra'
import minimist from 'minimist' import minimist from 'minimist'
import open from 'open' import open from 'open'
import semver from 'semver' import semver from 'semver'
@@ -10,18 +9,14 @@ import { getLatestCommits } from './getLatestCommits.js'
import { getRecommendedBump } from './getRecommendedBump.js' import { getRecommendedBump } from './getRecommendedBump.js'
type Args = { type Args = {
fromVersion?: string
toVersion?: string
bump?: 'major' | 'minor' | 'patch' | 'prerelease' bump?: 'major' | 'minor' | 'patch' | 'prerelease'
dryRun?: boolean dryRun?: boolean
fromVersion?: string
openReleaseUrl?: boolean openReleaseUrl?: boolean
toVersion?: string
} }
type ChangelogResult = { type ChangelogResult = {
/**
* URL to open releases/new with the changelog pre-filled
*/
releaseUrl: string
/** /**
* The changelog content, does not include contributors * The changelog content, does not include contributors
*/ */
@@ -34,10 +29,14 @@ type ChangelogResult = {
* The release tag, includes prefix 'v' * The release tag, includes prefix 'v'
*/ */
releaseTag: string releaseTag: string
/**
* URL to open releases/new with the changelog pre-filled
*/
releaseUrl: string
} }
export const generateReleaseNotes = async (args: Args = {}): Promise<ChangelogResult> => { export const generateReleaseNotes = async (args: Args = {}): Promise<ChangelogResult> => {
const { toVersion = 'HEAD', dryRun, bump, openReleaseUrl } = args const { bump, dryRun, openReleaseUrl, toVersion = 'HEAD' } = args
const fromVersion = const fromVersion =
args.fromVersion || execSync('git describe --match "v*" --tags --abbrev=0').toString().trim() args.fromVersion || execSync('git describe --match "v*" --tags --abbrev=0').toString().trim()
@@ -62,11 +61,11 @@ export const generateReleaseNotes = async (args: Args = {}): Promise<ChangelogRe
console.log(`Generating release notes for ${fromVersion} to ${toVersion}...`) console.log(`Generating release notes for ${fromVersion} to ${toVersion}...`)
console.log({ console.log({
tag,
recommendedBump,
fromVersion, fromVersion,
toVersion,
proposedVersion: proposedReleaseVersion, proposedVersion: proposedReleaseVersion,
recommendedBump,
tag,
toVersion,
}) })
const conventionalCommits = await getLatestCommits(fromVersion, toVersion) const conventionalCommits = await getLatestCommits(fromVersion, toVersion)
@@ -87,22 +86,22 @@ export const generateReleaseNotes = async (args: Args = {}): Promise<ChangelogRe
'breaking', 'breaking',
] as const ] as const
type Sections = (typeof commitTypesForChangelog)[number] type Section = (typeof commitTypesForChangelog)[number]
const emojiHeaderMap: Record<Sections, string> = { const emojiHeaderMap: Record<Section, string> = {
feat: '🚀 Features',
fix: '🐛 Bug Fixes',
perf: '⚡ Performance',
refactor: '🛠 Refactors',
docs: '📚 Documentation',
style: '🎨 Styles',
test: '🧪 Tests',
templates: '📝 Templates',
examples: '📓 Examples',
build: '🔨 Build',
ci: '⚙️ CI',
chore: '🏡 Chores',
breaking: '⚠️ BREAKING CHANGES', breaking: '⚠️ BREAKING CHANGES',
build: '<27> Build',
chore: '🏡 Chores',
ci: '⚙️ CI',
docs: '📚 Documentation',
examples: '📓 Examples',
feat: '🚀 Features',
fix: '<27> Bug Fixes',
perf: '⚡ Performance',
refactor: '<27> Refactors',
style: '🎨 Styles',
templates: '📝 Templates',
test: '🧪 Tests',
} }
const sections = conventionalCommits.reduce( const sections = conventionalCommits.reduce(
@@ -111,16 +110,18 @@ export const generateReleaseNotes = async (args: Args = {}): Promise<ChangelogRe
sections.breaking.push(c) sections.breaking.push(c)
} }
if (commitTypesForChangelog.includes(c.type as Sections)) { const typedCommitType: Section = c.type as Section
if (!sections[c.type]) {
sections[c.type] = [] if (commitTypesForChangelog.includes(typedCommitType)) {
if (!sections[typedCommitType]) {
sections[typedCommitType] = []
} }
sections[c.type].push(c) sections[typedCommitType].push(c)
} }
return sections return sections
}, },
{} as Record<'breaking' | Sections, GitCommit[]>, {} as Record<Section, GitCommit[]>,
) )
// Sort commits by scope, unscoped first // Sort commits by scope, unscoped first
@@ -160,10 +161,10 @@ export const generateReleaseNotes = async (args: Args = {}): Promise<ChangelogRe
} }
return { return {
releaseUrl,
changelog, changelog,
releaseNotes, releaseNotes,
releaseTag: proposedReleaseVersion, releaseTag: proposedReleaseVersion,
releaseUrl,
} }
} }
@@ -213,7 +214,7 @@ async function getContributors(commits: GitCommit[]): Promise<Contributor[]> {
continue continue
} }
const { author } = (await res.json()) as { author: { login: string; email: string } } const { author } = (await res.json()) as { author: { email: string; login: string } }
if (!contributors.some((c) => c.username === author.login)) { if (!contributors.some((c) => c.username === author.login)) {
contributors.push({ name: commit.author.name, username: author.login }) contributors.push({ name: commit.author.name, username: author.login })
@@ -225,7 +226,7 @@ async function getContributors(commits: GitCommit[]): Promise<Contributor[]> {
const coAuthors = Array.from( const coAuthors = Array.from(
commit.body.matchAll(coAuthorPattern), commit.body.matchAll(coAuthorPattern),
(match) => match.groups, (match) => match.groups,
).filter((e) => !e?.email.includes('[bot]')) as { name: string; email: string }[] ).filter((e) => !e?.email?.includes('[bot]')) as { email: string; name: string }[]
if (!coAuthors.length) { if (!coAuthors.length) {
continue continue
@@ -289,7 +290,7 @@ async function getContributors(commits: GitCommit[]): Promise<Contributor[]> {
type Contributor = { name: string; username: string } type Contributor = { name: string; username: string }
function formatCommitForChangelog(commit: GitCommit, includeBreakingNotes = false): string { function formatCommitForChangelog(commit: GitCommit, includeBreakingNotes = false): string {
const { scope, references, description, isBreaking } = commit const { description, isBreaking, references, scope } = commit
let formatted = `* ${scope ? `**${scope}:** ` : ''}${description}` let formatted = `* ${scope ? `**${scope}:** ` : ''}${description}`
references.forEach((ref) => { references.forEach((ref) => {
@@ -310,7 +311,7 @@ function formatCommitForChangelog(commit: GitCommit, includeBreakingNotes = fals
let notes = let notes =
` ` + ` ` +
rawNotes rawNotes
.split('\n') ?.split('\n')
.map((l) => ` ${l}`) // Indent notes .map((l) => ` ${l}`) // Indent notes
.join('\n') .join('\n')
.trim() .trim()
@@ -329,13 +330,13 @@ function formatCommitForChangelog(commit: GitCommit, includeBreakingNotes = fals
// module import workaround for ejs // module import workaround for ejs
if (import.meta.url === `file://${process.argv[1]}`) { if (import.meta.url === `file://${process.argv[1]}`) {
// This module is being run directly // This module is being run directly
const { fromVersion, toVersion, bump, openReleaseUrl } = minimist(process.argv.slice(2)) const { bump, fromVersion, openReleaseUrl, toVersion } = minimist(process.argv.slice(2))
generateReleaseNotes({ generateReleaseNotes({
bump, bump,
fromVersion,
toVersion,
dryRun: false, dryRun: false,
fromVersion,
openReleaseUrl, openReleaseUrl,
toVersion,
}) })
.then(() => { .then(() => {
console.log('Done') console.log('Done')

View File

@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"strict": true,
"strictNullChecks": true
}
}

View File

@@ -0,0 +1,34 @@
{
"name": "@tools/scripts",
"version": "0.0.1",
"description": "",
"keywords": [],
"license": "ISC",
"author": "",
"type": "module",
"exports": {
".": {
"import": "./src/index.ts"
}
},
"main": "src/index.ts",
"scripts": {
"build": "tsc",
"build-template-with-local-pkgs": "pnpm runts src/build-template-with-local-pkgs.ts",
"gen-templates": "pnpm runts src/generate-template-variations.ts",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"pack-all-to-dest": "pnpm runts src/pack-all-to-dest.ts",
"runts": "cross-env NODE_OPTIONS=--no-deprecation node --no-deprecation --import @swc-node/register/esm-register",
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"@swc-node/register": "1.10.9",
"@tools/constants": "workspace:*",
"@tools/releaser": "workspace:*",
"chalk": "^4.1.2",
"changelogen": "^0.5.5",
"create-payload-app": "workspace:*",
"open": "^10.1.0"
}
}

View File

@@ -1,21 +1,20 @@
import { TEMPLATES_DIR } from '@tools/constants'
import chalk from 'chalk' import chalk from 'chalk'
import { exec as execOrig, execSync } from 'child_process' import { exec as execOrig, execSync } from 'child_process'
import fs from 'fs/promises' import fs from 'fs/promises'
import { fileURLToPath } from 'node:url'
import path from 'path' import path from 'path'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
main().catch((error) => { main().catch((error) => {
console.error(error) console.error(error)
process.exit(1) process.exit(1)
}) })
async function main() { async function main() {
const templateDir = path.resolve(dirname, '../templates')
const templateName = process.argv[2] const templateName = process.argv[2]
const templatePath = path.join(templateDir, templateName) if (!templateName) {
throw new Error('Please provide a template name')
}
const templatePath = path.join(TEMPLATES_DIR, templateName)
const databaseConnection = process.argv[3] || 'mongodb://127.0.0.1/your-database-name' const databaseConnection = process.argv[3] || 'mongodb://127.0.0.1/your-database-name'
console.log({ console.log({

View File

@@ -9,45 +9,42 @@
* There is no way currently to have lint-staged ignore the templates directory. * There is no way currently to have lint-staged ignore the templates directory.
*/ */
import type { DbType, StorageAdapterType } from 'create-payload-app/types'
import { PROJECT_ROOT, TEMPLATES_DIR } from '@tools/constants'
import chalk from 'chalk' import chalk from 'chalk'
import { execSync } from 'child_process' import { execSync } from 'child_process'
import { configurePayloadConfig } from 'create-payload-app/lib/configure-payload-config.js' import { configurePayloadConfig } from 'create-payload-app/lib/configure-payload-config.js'
import { copyRecursiveSync } from 'create-payload-app/utils/copy-recursive-sync.js' import { copyRecursiveSync } from 'create-payload-app/utils/copy-recursive-sync.js'
import minimist from 'minimist' import minimist from 'minimist'
import * as fs from 'node:fs/promises' import * as fs from 'node:fs/promises'
import { fileURLToPath } from 'node:url'
import path from 'path' import path from 'path'
import type { DbType, StorageAdapterType } from '../packages/create-payload-app/src/types.js'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
type TemplateVariations = { type TemplateVariations = {
/** package.json name */
name: string
/** Base template to copy from */ /** Base template to copy from */
base?: string base?: string
configureConfig?: boolean
db: DbType
/** Directory in templates dir */ /** Directory in templates dir */
dirname: string dirname: string
db: DbType
storage: StorageAdapterType
sharp: boolean
vercelDeployButtonLink?: string
envNames?: { envNames?: {
dbUri: string dbUri: string
} }
/** generateLockfile?: boolean
* @default false /** package.json name */
*/ name: string
skipReadme?: boolean sharp: boolean
skipConfig?: boolean skipConfig?: boolean
/** /**
* @default false * @default false
*/ */
skipDockerCompose?: boolean skipDockerCompose?: boolean
configureConfig?: boolean /**
generateLockfile?: boolean * @default false
*/
skipReadme?: boolean
storage: StorageAdapterType
vercelDeployButtonLink?: string
} }
main().catch((error) => { main().catch((error) => {
@@ -58,17 +55,20 @@ main().catch((error) => {
async function main() { async function main() {
const args = minimist(process.argv.slice(2)) const args = minimist(process.argv.slice(2))
const template = args['template'] // template directory name const template = args['template'] // template directory name
const templatesDir = path.resolve(dirname, '../templates')
const templateRepoUrlBase = `https://github.com/payloadcms/payload/tree/main/templates` const templateRepoUrlBase = `https://github.com/payloadcms/payload/tree/main/templates`
let variations: TemplateVariations[] = [ let variations: TemplateVariations[] = [
{ {
name: 'payload-vercel-postgres-template', name: 'payload-vercel-postgres-template',
dirname: 'with-vercel-postgres',
db: 'vercel-postgres', db: 'vercel-postgres',
storage: 'vercelBlobStorage', dirname: 'with-vercel-postgres',
envNames: {
// This will replace the process.env.DATABASE_URI to process.env.POSTGRES_URL
dbUri: 'POSTGRES_URL',
},
sharp: false, sharp: false,
storage: 'vercelBlobStorage',
vercelDeployButtonLink: vercelDeployButtonLink:
`https://vercel.com/new/clone?repository-url=` + `https://vercel.com/new/clone?repository-url=` +
encodeURI( encodeURI(
@@ -78,18 +78,20 @@ async function main() {
'&build-command=pnpm run ci' + '&build-command=pnpm run ci' +
'&stores=[{"type":"postgres"},{"type":"blob"}]', // Postgres and Vercel Blob Storage '&stores=[{"type":"postgres"},{"type":"blob"}]', // Postgres and Vercel Blob Storage
), ),
envNames: {
// This will replace the process.env.DATABASE_URI to process.env.POSTGRES_URL
dbUri: 'POSTGRES_URL',
},
}, },
{ {
name: 'payload-vercel-website-template', name: 'payload-vercel-website-template',
base: 'website', // This is the base template to copy from base: 'website', // This is the base template to copy from
dirname: 'with-vercel-website',
db: 'vercel-postgres', db: 'vercel-postgres',
storage: 'vercelBlobStorage', dirname: 'with-vercel-website',
envNames: {
// This will replace the process.env.DATABASE_URI to process.env.POSTGRES_URL
dbUri: 'POSTGRES_URL',
},
sharp: true, sharp: true,
skipDockerCompose: true,
skipReadme: true,
storage: 'vercelBlobStorage',
vercelDeployButtonLink: vercelDeployButtonLink:
`https://vercel.com/new/clone?repository-url=` + `https://vercel.com/new/clone?repository-url=` +
encodeURI( encodeURI(
@@ -99,26 +101,23 @@ async function main() {
'&build-command=pnpm run ci' + '&build-command=pnpm run ci' +
'&stores=[{"type":"postgres"},{"type":"blob"}]', // Postgres and Vercel Blob Storage '&stores=[{"type":"postgres"},{"type":"blob"}]', // Postgres and Vercel Blob Storage
), ),
envNames: {
// This will replace the process.env.DATABASE_URI to process.env.POSTGRES_URL
dbUri: 'POSTGRES_URL',
},
skipReadme: true,
skipDockerCompose: true,
}, },
{ {
name: 'payload-postgres-template', name: 'payload-postgres-template',
dirname: 'with-postgres',
db: 'postgres', db: 'postgres',
storage: 'localDisk', dirname: 'with-postgres',
sharp: true, sharp: true,
storage: 'localDisk',
}, },
{ {
name: 'payload-vercel-mongodb-template', name: 'payload-vercel-mongodb-template',
dirname: 'with-vercel-mongodb',
db: 'mongodb', db: 'mongodb',
storage: 'vercelBlobStorage', dirname: 'with-vercel-mongodb',
envNames: {
dbUri: 'MONGODB_URI',
},
sharp: false, sharp: false,
storage: 'vercelBlobStorage',
vercelDeployButtonLink: vercelDeployButtonLink:
`https://vercel.com/new/clone?repository-url=` + `https://vercel.com/new/clone?repository-url=` +
encodeURI( encodeURI(
@@ -129,18 +128,15 @@ async function main() {
'&stores=[{"type":"blob"}]' + // Vercel Blob Storage '&stores=[{"type":"blob"}]' + // Vercel Blob Storage
'&integration-ids=oac_jnzmjqM10gllKmSrG0SGrHOH', // MongoDB Atlas '&integration-ids=oac_jnzmjqM10gllKmSrG0SGrHOH', // MongoDB Atlas
), ),
envNames: {
dbUri: 'MONGODB_URI',
},
}, },
{ {
name: 'blank', name: 'blank',
dirname: 'blank',
db: 'mongodb', db: 'mongodb',
dirname: 'blank',
generateLockfile: true, generateLockfile: true,
storage: 'localDisk',
sharp: true, sharp: true,
skipConfig: true, // Do not copy the payload.config.ts file from the base template skipConfig: true, // Do not copy the payload.config.ts file from the base template
storage: 'localDisk',
// The blank template is used as a base for create-payload-app functionality, // The blank template is used as a base for create-payload-app functionality,
// so we do not configure the payload.config.ts file, which leaves the placeholder comments. // so we do not configure the payload.config.ts file, which leaves the placeholder comments.
configureConfig: false, configureConfig: false,
@@ -159,21 +155,21 @@ async function main() {
for (const { for (const {
name, name,
base, base,
dirname,
db,
generateLockfile,
storage,
vercelDeployButtonLink,
envNames,
sharp,
configureConfig, configureConfig,
skipReadme = false, db,
dirname,
envNames,
generateLockfile,
sharp,
skipConfig = false, skipConfig = false,
skipDockerCompose = false, skipDockerCompose = false,
skipReadme = false,
storage,
vercelDeployButtonLink,
} of variations) { } of variations) {
header(`Generating ${name}...`) header(`Generating ${name}...`)
const destDir = path.join(templatesDir, dirname) const destDir = path.join(TEMPLATES_DIR, dirname)
copyRecursiveSync(path.join(templatesDir, base || '_template'), destDir, [ copyRecursiveSync(path.join(TEMPLATES_DIR, base || '_template'), destDir, [
'node_modules', 'node_modules',
'\\*\\.tgz', '\\*\\.tgz',
'.next', '.next',
@@ -190,32 +186,32 @@ async function main() {
log('Configuring payload.config.ts') log('Configuring payload.config.ts')
const configureArgs = { const configureArgs = {
dbType: db, dbType: db,
envNames,
packageJsonName: name, packageJsonName: name,
projectDirOrConfigPath: { projectDir: destDir }, projectDirOrConfigPath: { projectDir: destDir },
storageAdapter: storage,
sharp, sharp,
envNames, storageAdapter: storage,
} }
await configurePayloadConfig(configureArgs) await configurePayloadConfig(configureArgs)
log('Configuring .env.example') log('Configuring .env.example')
// Replace DATABASE_URI with the correct env name if set // Replace DATABASE_URI with the correct env name if set
await writeEnvExample({ await writeEnvExample({
dbType: db,
destDir, destDir,
envNames, envNames,
dbType: db,
}) })
} }
if (!skipReadme) { if (!skipReadme) {
await generateReadme({ await generateReadme({
destDir,
data: { data: {
name, name,
description: name, // TODO: Add descriptions
attributes: { db, storage }, attributes: { db, storage },
description: name, // TODO: Add descriptions
...(vercelDeployButtonLink && { vercelDeployButtonLink }), ...(vercelDeployButtonLink && { vercelDeployButtonLink }),
}, },
destDir,
}) })
} }
@@ -240,7 +236,7 @@ async function main() {
const migrationDestDir = path.join(destDir, 'src/migrations') const migrationDestDir = path.join(destDir, 'src/migrations')
// Delete and recreate migrations directory // Delete and recreate migrations directory
await fs.rm(migrationDestDir, { recursive: true, force: true }) await fs.rm(migrationDestDir, { force: true, recursive: true })
await fs.mkdir(migrationDestDir, { recursive: true }) await fs.mkdir(migrationDestDir, { recursive: true })
log(`Generating initial migrations in ${migrationDestDir}`) log(`Generating initial migrations in ${migrationDestDir}`)
@@ -249,9 +245,9 @@ async function main() {
cwd: destDir, cwd: destDir,
env: { env: {
...process.env, ...process.env,
PAYLOAD_SECRET: 'asecretsolongnotevensantacouldguessit',
BLOB_READ_WRITE_TOKEN: 'vercel_blob_rw_TEST_asdf', BLOB_READ_WRITE_TOKEN: 'vercel_blob_rw_TEST_asdf',
DATABASE_URI: process.env.POSTGRES_URL || 'postgres://localhost:5432/your-database-name', DATABASE_URI: process.env.POSTGRES_URL || 'postgres://localhost:5432/your-database-name',
PAYLOAD_SECRET: 'asecretsolongnotevensantacouldguessit',
}, },
}) })
} }
@@ -262,24 +258,23 @@ async function main() {
log(`Done configuring payload config for ${destDir}/src/payload.config.ts`) log(`Done configuring payload config for ${destDir}/src/payload.config.ts`)
} }
// TODO: Run prettier manually on the generated files, husky blows up
log('Running prettier on generated files...') log('Running prettier on generated files...')
execSyncSafe(`pnpm prettier --write templates "*.{js,jsx,ts,tsx}"`) execSyncSafe(`pnpm prettier --write templates "*.{js,jsx,ts,tsx}"`, { cwd: PROJECT_ROOT })
log('Template generation complete!') log('Template generation complete!')
} }
async function generateReadme({ async function generateReadme({
data: { name, attributes, description, vercelDeployButtonLink },
destDir, destDir,
data: { name, description, attributes, vercelDeployButtonLink },
}: { }: {
destDir: string
data: { data: {
name: string
description: string
attributes: Pick<TemplateVariations, 'db' | 'storage'> attributes: Pick<TemplateVariations, 'db' | 'storage'>
description: string
name: string
vercelDeployButtonLink?: string vercelDeployButtonLink?: string
} }
destDir: string
}) { }) {
let header = `# ${name}\n` let header = `# ${name}\n`
if (vercelDeployButtonLink) { if (vercelDeployButtonLink) {
@@ -302,13 +297,13 @@ ${description}
} }
async function writeEnvExample({ async function writeEnvExample({
dbType,
destDir, destDir,
envNames, envNames,
dbType,
}: { }: {
dbType: DbType
destDir: string destDir: string
envNames?: TemplateVariations['envNames'] envNames?: TemplateVariations['envNames']
dbType: DbType
}) { }) {
const envExamplePath = path.join(destDir, '.env.example') const envExamplePath = path.join(destDir, '.env.example')
const envFileContents = await fs.readFile(envExamplePath, 'utf8') const envFileContents = await fs.readFile(envExamplePath, 'utf8')
@@ -363,7 +358,9 @@ function execSyncSafe(command: string, options?: Parameters<typeof execSync>[1])
execSync(command, { stdio: 'inherit', ...options }) execSync(command, { stdio: 'inherit', ...options })
} catch (error) { } catch (error) {
if (error instanceof Error) { if (error instanceof Error) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const stderr = (error as any).stderr?.toString() const stderr = (error as any).stderr?.toString()
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const stdout = (error as any).stdout?.toString() const stdout = (error as any).stdout?.toString()
if (stderr && stderr.trim()) { if (stderr && stderr.trim()) {

View File

View File

@@ -1,23 +1,15 @@
import type { PackageDetails } from '@tools/releaser'
import type { ExecSyncOptions } from 'child_process' import type { ExecSyncOptions } from 'child_process'
import type execa from 'execa'
import { PROJECT_ROOT } from '@tools/constants'
import { getPackageDetails } from '@tools/releaser'
import chalk from 'chalk' import chalk from 'chalk'
import { exec as execOrig, execSync } from 'child_process' import { exec as execOrig, execSync } from 'child_process'
import fse from 'fs-extra'
import minimist from 'minimist' import minimist from 'minimist'
import { fileURLToPath } from 'node:url'
import path from 'path' import path from 'path'
import util from 'util' import util from 'util'
import type { PackageDetails } from './lib/getPackageDetails.js' const execOpts: ExecSyncOptions = { stdio: 'inherit', cwd: PROJECT_ROOT }
import { getPackageDetails } from './lib/getPackageDetails.js'
const execOpts: ExecSyncOptions = { stdio: 'inherit' }
const execaOpts: execa.Options = { stdio: 'inherit' }
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const exec = util.promisify(execOrig) const exec = util.promisify(execOrig)
@@ -39,10 +31,10 @@ async function main() {
throw new Error('--dest is required') throw new Error('--dest is required')
} }
const resolvedDest = path.resolve(dest) const resolvedDest = path.resolve(path.isAbsolute(dest) ? dest : path.join(PROJECT_ROOT, dest))
const packageWhitelist = all const packageWhitelist = all
? null ? undefined
: [ : [
'payload', 'payload',
'db-mongodb', 'db-mongodb',
@@ -73,18 +65,18 @@ async function main() {
const filtered = packageDetails.filter((p): p is Exclude<typeof p, null> => p !== null) const filtered = packageDetails.filter((p): p is Exclude<typeof p, null> => p !== null)
if (!noBuild) { if (!noBuild) {
execSync('pnpm build:all --output-logs=errors-only', { stdio: 'inherit' }) execSync('pnpm build:all --output-logs=errors-only', execOpts)
} }
header(`\nOutputting ${filtered.length} packages... header(`\nOutputting ${filtered.length} packages...
${chalk.white.bold(listPackages(filtered))}`) ${chalk.white.bold(listPackages(filtered))}`)
header(`\n📦 Packing all packages to ${dest}...`) header(`\n📦 Packing all packages to ${resolvedDest}...`)
await Promise.all( await Promise.all(
filtered.map(async (p) => { filtered.map(async (p) => {
await exec(`pnpm pack -C ${p.packagePath} --pack-destination ${resolvedDest}`) await exec(`pnpm pack -C ${p.packagePath} --pack-destination ${resolvedDest}`, execOpts)
}), }),
) )

View File

@@ -0,0 +1,6 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"strict": true,
}
}

View File

@@ -4,7 +4,6 @@
"strict": true, "strict": true,
"noUncheckedIndexedAccess": true, "noUncheckedIndexedAccess": true,
"noImplicitOverride": true, "noImplicitOverride": true,
"composite": true, "composite": true,
"declaration": true, "declaration": true,
"declarationMap": true, "declarationMap": true,