Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions .github/workflows/auto-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
name: auto-release

on:
push:
branches:
- main
paths-ignore:
- "**.md"
- "website/**"
- "docs/**"
- ".github/**"
- "!.github/workflows/**"

concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false

jobs:
auto-release:
name: Auto Release
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, 'release:')"
permissions:
contents: write
pull-requests: read
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22.x

- name: Configure Git
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"

- name: Get latest release
id: latest_release
run: |
# Get the latest release tag, fallback to v0.0.0 if none exists
latest_tag=$(git tag --sort=-version:refname | head -n1 || echo "v0.0.0")
echo "latest_tag=$latest_tag" >> $GITHUB_OUTPUT
echo "Latest release tag: $latest_tag"

- name: Get commits since last release
id: commits
run: |
latest_tag="${{ steps.latest_release.outputs.latest_tag }}"
if [ "$latest_tag" = "v0.0.0" ]; then
# If no previous release, get all commits
commits=$(git log --oneline --pretty=format:"%s" | head -10)
else
# Get commits since last release
commits=$(git log ${latest_tag}..HEAD --oneline --pretty=format:"%s")
fi

echo "Commits since $latest_tag:"
echo "$commits"

# Check if there are any commits to release
if [ -z "$commits" ]; then
echo "No new commits to release"
echo "should_release=false" >> $GITHUB_OUTPUT
exit 0
fi

echo "should_release=true" >> $GITHUB_OUTPUT

- name: Determine version bump type
id: bump_type
if: steps.commits.outputs.should_release == 'true'
run: |
latest_tag="${{ steps.latest_release.outputs.latest_tag }}"
commits=$(git log ${latest_tag}..HEAD --oneline --pretty=format:"%s" || git log --oneline --pretty=format:"%s" | head -10)

# Default to patch
bump_type="patch"

# Check for breaking changes (major)
if echo "$commits" | grep -qE "^[^:]+!:|BREAKING CHANGE"; then
bump_type="major"
# Check for features (minor)
elif echo "$commits" | grep -qE "^feat(\(.+\))?:"; then
bump_type="minor"
# Check for fixes and other changes (patch)
elif echo "$commits" | grep -qE "^(fix|perf|refactor|style|docs|test|build|ci|chore)(\(.+\))?:"; then
bump_type="patch"
fi

echo "Determined bump type: $bump_type"
echo "bump_type=$bump_type" >> $GITHUB_OUTPUT

- name: Bump version
id: version_bump
if: steps.commits.outputs.should_release == 'true'
run: |
bump_type="${{ steps.bump_type.outputs.bump_type }}"

# Get current version from package.json
current_version=$(node -p "require('./package.json').version")
echo "Current version: $current_version"

# Bump version using npm
npm version $bump_type --no-git-tag-version

# Get new version
new_version=$(node -p "require('./package.json').version")
echo "New version: $new_version"
echo "new_version=$new_version" >> $GITHUB_OUTPUT

- name: Commit version bump and create tag
if: steps.commits.outputs.should_release == 'true'
run: |
new_version="${{ steps.version_bump.outputs.new_version }}"

# Commit the version bump
git add package.json
git commit -m "release: $new_version"

# Create and push tag
git tag "v$new_version"
git push origin main
git push origin "v$new_version"

echo "Created and pushed tag v$new_version"

- name: Summary
run: |
if [ "${{ steps.commits.outputs.should_release }}" = "true" ]; then
echo "✅ Auto-release completed!"
echo "New version: ${{ steps.version_bump.outputs.new_version }}"
echo "Tag created: v${{ steps.version_bump.outputs.new_version }}"
echo ""
echo "The check and release workflows will now run automatically."
else
echo "ℹ️ No new commits to release - skipping auto-release"
fi
8 changes: 2 additions & 6 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ name: check

on:
push:
branches:
- master
tags:
- v*
pull_request:
branches:
- master
- main

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
Expand Down Expand Up @@ -45,7 +43,7 @@ jobs:
uses: pozetroninc/github-action-get-latest-release@master
id: version_v_github
with:
owner: MichalLytek
owner: scope3data
repo: type-graphql
excludes: prerelease, draft

Expand Down Expand Up @@ -105,8 +103,6 @@ jobs:

check:
name: Build & Lint & Test
needs: version
if: always() && (needs.version.result == 'success' || needs.version.result == 'skipped')
runs-on: ubuntu-latest
strategy:
fail-fast: true
Expand Down
28 changes: 24 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,40 @@ concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true

permissions:
pull-requests: write
contents: read
packages: write

jobs:
release:
name: Release package on NPM
name: Release package on GitHub Packages
runs-on: ubuntu-latest
if: github.event.workflow_run.conclusion == 'success' && github.ref_name == 'master' && startsWith(github.event.workflow_run.head_branch, 'v')
if: github.event.workflow_run.conclusion == 'success' && startsWith(github.event.workflow_run.head_branch, 'v')
permissions:
contents: write
id-token: write
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_branch }}

- name: Verify version validation passed
env:
TYPE_GRAPHQL_VERSION: ${{ github.event.workflow_run.head_branch }}
run: |
echo "Verifying release for version: $TYPE_GRAPHQL_VERSION"

# Ensure this is a valid version tag format
if ! printf "%s\n" "$TYPE_GRAPHQL_VERSION" | grep -q -P '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-(alpha|beta|rc)\.(0|[1-9][0-9]*))?$'; then
printf '[ERROR]: Invalid version tag format (%s)\n' "$TYPE_GRAPHQL_VERSION"
exit 1
fi

echo "✅ Version tag format is valid"

- name: Determine if version is prerelease
id: prerelease
env:
Expand All @@ -43,7 +63,7 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: 22.x
registry-url: "https://registry.npmjs.org"
registry-url: "https://npm.pkg.github.com"

- name: Install latest npm
run: |
Expand Down Expand Up @@ -77,7 +97,7 @@ jobs:

- name: Publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TYPE_GRAPHQL_PRERELEASE: ${{ steps.prerelease.outputs.value }}
run: |
_tag=
Expand Down
2 changes: 1 addition & 1 deletion .npmrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
engine-strict=true
@scope3data:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}
74 changes: 74 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,80 @@
![logo](./images/logo.png)
<!-- prettier-ignore-end -->

---

## Performance-Optimized Fork by [Scope3](https://scope3.com/home)

> **Context**: This is a high-performance fork maintained by [Scope3](https://github.com/scope3data) with significant optimization improvements. Our changes have been submitted as [PR #1779](https://github.com/MichalLytek/type-graphql/pull/1779) to the original repository but remain unmerged after 6+ months.

### Performance Improvements

#### What’s Different in the Scope3 Fork?

This fork introduces a major refactor of the TypeGraphQL metadata build process, focused on dramatically improving performance for large schemas. It works very well! Scope3 has been running this fork in production for over 6 months, dropping our schema generation time from 4-5 minutes to under 10 seconds in our K8s deployments.

**Problem:**
Schema generation in the upstream project was exponentially slow for large schemas, taking 30+ seconds with 3k-15k metadata objects due to repeated O(n) array `.filter()` lookups.

**Scope3 Solution:**
We replaced all repeated array lookups with O(1) HashMap-based caching.

- Added cache initialization for all major metadata types (object types, fields, params, middlewares, directives, resolver classes, etc.).
- All metadata lookups now use these caches instead of array `.filter()` calls.
- Refactored resolver and field metadata construction to leverage these caches.

**Technical Details:**

- Introduced `Map` caches for object types, fields, params, middlewares, directives, and resolver classes.
- Added an `initCache()` method to populate these caches before schema building.
- All metadata construction logic now uses these caches for instant lookup.

**Performance Impact:**

- Schema generation time reduced from tens of seconds to milliseconds for large schemas.
- Example:
- `buildClassMetadata`: 31.3s → 268ms (116x faster)
- `buildFieldResolverMetadata`: 314ms → 39ms (8x faster)
- `buildResolversMetadata`: 1.4s → 126ms (11x faster)

**Compatibility:**

- The fork remains 100% backward compatible with the original TypeGraphQL API.
- All original TypeGraphQL tests pass with these changes.
- Scope3 has been running this fork in production for over 6 months.
- All recent upstream changes are documentation-only (sponsor updates).

---

If you want more technical details or code samples, see the source or reach out to Scope3!

### Installation

```bash
# Add to .npmrc
@scope3data:registry=https://npm.pkg.github.com

# Install with npm
npm install @scope3data/type-graphql

# Install with Yarn
yarn add @scope3data/type-graphql

# Install with PNPM
pnpm add @scope3data/type-graphql
```

### What's Coming

- Prisma 6 support – Upgrading to the latest Prisma version
- GraphQL 16.11 – Latest GraphQL version with improved performance and features

### Compatibility

100% backward compatible – drop-in replacement for the original `type-graphql` package.

---

# TypeGraphQL

[![release](https://github.com/MichalLytek/type-graphql/actions/workflows/release.yml/badge.svg)](https://github.com/MichalLytek/type-graphql/actions/workflows/release.yml)
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "type-graphql",
"name": "@scope3data/type-graphql",
"version": "2.0.0-rc.3",
"private": false,
"description": "Create GraphQL schema and resolvers with TypeScript, using classes and decorators!",
Expand All @@ -15,11 +15,11 @@
],
"homepage": "https://typegraphql.com",
"bugs": {
"url": "https://github.com/MichalLytek/type-graphql/issues"
"url": "https://github.com/scope3data/type-graphql/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/MichalLytek/type-graphql.git"
"url": "git+https://github.com/scope3data/type-graphql.git"
},
"funding": [
{
Expand Down