Skip to content
Draft
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
47 changes: 24 additions & 23 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# CI workflow for egg monorepo
name: CI

on:
Expand Down Expand Up @@ -27,31 +28,31 @@ jobs:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6

- name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4
- name: Setup utoo
uses: utooland/setup-utoo@3a51006d0b66afcc32d1b9177a4b200b74f4a8cb # main

- name: Set up Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
with:
node-version: '24'

- name: Install dependencies
run: pnpm install --no-frozen-lockfile
run: ut install --from pnpm

- name: Run lint
run: pnpm run lint
run: ut run lint

- name: Run typecheck
run: pnpm run typecheck
run: ut run typecheck

- name: Run format check
run: pnpm run fmtcheck
run: ut run fmtcheck

- name: Run build
run: pnpm run build
run: ut run build

- name: Run site build
run: pnpm run site:build
run: ut run site:build

test:
strategy:
Expand Down Expand Up @@ -150,24 +151,24 @@ jobs:
# & mysqladmin -u root password root
& mysql -uroot -e "CREATE DATABASE IF NOT EXISTS test;"

- name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4
- name: Setup utoo
uses: utooland/setup-utoo@3a51006d0b66afcc32d1b9177a4b200b74f4a8cb # main

- name: Set up Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
with:
node-version: ${{ matrix.node }}

- name: Install dependencies
run: pnpm install --no-frozen-lockfile
run: ut install --from pnpm

- name: Run tests
run: pnpm run ci
run: ut run ci

- name: Run example tests
if: ${{ matrix.os != 'windows-latest' }}
run: |
pnpm run example:test:all
ut run example:test:all

- name: Code Coverage
# skip on windows, it will hangup on codecov
Expand All @@ -194,21 +195,21 @@ jobs:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6

- name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4
- name: Setup utoo
uses: utooland/setup-utoo@3a51006d0b66afcc32d1b9177a4b200b74f4a8cb # main

- name: Set up Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
with:
node-version: ${{ matrix.node }}

- name: Install dependencies
run: pnpm install --no-frozen-lockfile
run: ut install --from pnpm

- name: Run tests
run: |
pnpm build --workspace ./tools/egg-bin
pnpm run --filter ./tools/egg-bin ci
ut run build -- --workspace ./tools/egg-bin
ut run ci --workspace @eggjs/bin

- name: Code Coverage
# skip on windows, it will hangup on codecov https://github.com/codecov/codecov-action/issues/1787
Expand All @@ -235,21 +236,21 @@ jobs:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6

- name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4
- name: Setup utoo
uses: utooland/setup-utoo@3a51006d0b66afcc32d1b9177a4b200b74f4a8cb # main

- name: Set up Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
with:
node-version: ${{ matrix.node }}

- name: Install dependencies
run: pnpm install --no-frozen-lockfile
run: ut install --from pnpm

- name: Run tests
run: |
pnpm build
pnpm run --filter=./tools/scripts ci
ut run build -- --workspace ./tools/scripts
ut run ci --workspace tools/scripts

- name: Code Coverage
if: ${{ matrix.os != 'windows-latest' }}
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,5 @@ tegg/plugin/tegg/test/fixtures/apps/**/*.js
ecosystem-ci/cnpmcore
ecosystem-ci/examples
pnpm-lock.yaml
.utoo.toml
.claude/
3 changes: 2 additions & 1 deletion .oxfmtrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"packages/core/test/fixtures/load_dirs/syntax_error/*",
"packages/core/test/fixtures/syntaxerror/*",
"packages/core/test/fixtures/load_context_syntax_error/**/*",
"CHANGELOG.md"
"CHANGELOG.md",
"/package.json"
],
"experimentalSortImports": {
"groups": [
Expand Down
2 changes: 1 addition & 1 deletion ecosystem-ci/repo.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"cnpmcore": {
"repository": "https://github.com/cnpm/cnpmcore.git",
"branch": "master",
"hash": "e82df3f4093c0ec9fd5354563605e60f7f613035"
"hash": "98463c33188bbd32513a74e6c3a2c4cc559ef5da"
},
"examples": {
"repository": "https://github.com/eggjs/examples.git",
Expand Down
28 changes: 14 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,25 @@
],
"type": "module",
"scripts": {
"clean-dist": "pnpm -r --parallel exec rimraf dist",
"clean": "pnpm -r --parallel run clean && pnpm clean-dist",
"clean-dist": "ut run clean --workspaces --if-present",
"build": "tsdown",
"prelint": "pnpm clean-dist",
"prelint": "ut run clean-dist",
"lint": "oxlint --type-aware --type-check --quiet",
"fmt": "oxfmt",
"typecheck": "pnpm clean && pnpm -r run typecheck",
"typecheck": "ut run clean-dist && ut run typecheck --workspaces --if-present",
"fmtcheck": "oxfmt --check .",
"pretest": "pnpm run clean && pnpm -r run pretest",
"pretest": "ut run clean-dist && ut run pretest --workspaces --if-present",
"test": "vitest run --bail 1 --retry 2 --testTimeout 20000 --hookTimeout 20000",
"test:cov": "pnpm run test --coverage",
"preci": "pnpm -r --parallel run pretest",
"ci": "pnpm run test --coverage",
"site:dev": "pnpm --filter=site run dev",
"site:build": "pnpm --filter=site run build",
"test:cov": "ut run test -- --coverage",
"preci": "ut run pretest --workspaces --if-present",
"ci": "ut run test -- --coverage",
"site:dev": "ut run dev --workspace site",
"site:build": "ut run build --workspace site",
"puml": "puml . --dest ./site",
"example:dev:commonjs": "pnpm --filter=helloworld-commonjs run dev",
"example:dev:typescript": "pnpm --filter=helloworld-typescript run dev",
"example:dev:tegg": "pnpm --filter=helloworld-tegg run dev",
"example:test:all": "pnpm --filter=helloworld-* run test",
"example:dev:commonjs": "ut run dev --workspace helloworld-commonjs",
"example:dev:typescript": "ut run dev --workspace helloworld-typescript",
"example:dev:tegg": "ut run dev --workspace helloworld-tegg",
"example:test:all": "ut run test --workspace 'helloworld-*' --if-present",
"prepare": "husky",
"version:patch": "node scripts/version.js patch",
"version:minor": "node scripts/version.js minor",
Expand Down Expand Up @@ -69,6 +68,7 @@
"typescript": "catalog:",
"unplugin-unused": "catalog:",
"urllib": "catalog:",
"utoo": "catalog:",
"vitest": "catalog:"
},
"lint-staged": {
Expand Down
6 changes: 4 additions & 2 deletions packages/cluster/test/options.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,10 +239,12 @@ describe('test/options.test.ts', () => {
baseDir,
});
const expectPaths = [
// run int workspace root
// run in workspace root
path.join(__dirname, '../../egg'),
// run in project root
// run in project root (pnpm nested)
path.join(__dirname, '../node_modules/egg'),
// run with flat/hoisted node_modules (e.g. ut install)
path.join(__dirname, '../../../node_modules/egg'),
];
assert(
expectPaths.includes(options.framework),
Expand Down
5 changes: 4 additions & 1 deletion packages/tsconfig/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import fs from 'node:fs/promises';
import { createRequire } from 'node:module';
import path from 'node:path';

import coffee from 'coffee';
import { test, expect } from 'vitest';

const require = createRequire(import.meta.url);

test('should tsc build work', async () => {
const tsc = path.join(import.meta.dirname, '..', 'node_modules', 'typescript', 'bin', 'tsc');
const tsc = require.resolve('typescript/bin/tsc');
const fixturePath = path.join(import.meta.dirname, 'fixtures/apps/ts-proj');
const tsconfigPath = path.join(fixturePath, 'tsconfig.json');
console.log('%s -p %s, cwd: %s', tsc, tsconfigPath, fixturePath);
Expand Down
4 changes: 2 additions & 2 deletions packages/utils/test/import.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ describe('test/import.test.ts', () => {
assert.equal(err.name, 'ImportResolveError');
assert.equal(err.filepath, 'tsconfig-paths-demo-not-exists/register');
assert.deepEqual(err.paths, [getFilepath('cjs/node_modules/inject')]);
assert.match(err.stack ?? '', /Cannot find package/);
assert.match(err.message, /Cannot find package/);
assert.match(err.stack ?? '', /Cannot find (package|module)/);
assert.match(err.message, /Cannot find (package|module)/);
return true;
},
);
Expand Down
4 changes: 4 additions & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ catalog:
urijs: ^1.19.11
urllib: ^4.8.2
utility: ^2.5.0
utoo: ^1
vary: ^1.1.2
vitepress: 2.0.0-alpha.15
vitepress-plugin-llms: ^1.10.0
Expand All @@ -227,6 +228,9 @@ catalogs:
path-to-regexp1:
path-to-regexp: ^1.9.0

onlyBuiltDependencies:
- utoo

minimumReleaseAge: 1440

minimumReleaseAgeExclude:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import { isInitializeRequest, isJSONRPCRequest } from '@modelcontextprotocol/sdk
import type { JSONRPCMessage, MessageExtraInfo } from '@modelcontextprotocol/sdk/types.js';
// @ts-expect-error await-event is not typed
import awaitEvent from 'await-event';
// @ts-expect-error content-type is not typed
import contentType from 'content-type';
import type { Application, Context, Router } from 'egg';
import compose from 'koa-compose';
Expand Down
2 changes: 0 additions & 2 deletions tegg/plugin/mcp-proxy/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/
import awaitEvent from 'await-event';
// @ts-expect-error cluster-client is not typed
import { APIClientBase } from 'cluster-client';
// @ts-expect-error content-type is not typed
import contentType from 'content-type';
import type { Application, Context } from 'egg';
import type { EggLogger } from 'egg';
import { EventSourceParserStream } from 'eventsource-parser/stream';
// @ts-expect-error koa-compose is not typed
import compose from 'koa-compose';
import getRawBody from 'raw-body';

Expand Down
2 changes: 1 addition & 1 deletion tools/egg-bin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@
}
},
"scripts": {
"build": "tsdown -c tsdown.config.ts",
"typecheck": "tsgo --noEmit",
"pretest": "tsdown",
"test": "vitest run",
"cov": "vitest run --coverage",
"ci": "npm run cov"
Expand Down
31 changes: 21 additions & 10 deletions tools/egg-bin/src/baseCommand.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { fork, type ForkOptions, ChildProcess } from 'node:child_process';
import { createRequire } from 'node:module';
import os from 'node:os';
import path from 'node:path';
import { pathToFileURL } from 'node:url';
import { debuglog } from 'node:util';

import { importResolve } from '@eggjs/utils';
import { Command, Flags, Interfaces } from '@oclif/core';

import { type PackageEgg } from './types.ts';
Expand Down Expand Up @@ -207,12 +207,27 @@ export abstract class BaseCommand<T extends typeof Command> extends Command {
// try app baseDir first on custom tscompiler
// then try to find tscompiler in @eggjs/bin/node_modules
const findPaths: string[] = [flags.base, rootDir];
// ts-node, tsconfig-paths are CJS packages without `exports` field.
// Must use CJS resolver (createRequire) instead of importResolve because:
// - ESM resolver (Node ≥22) doesn't auto-append .js for bare subpaths
// of packages without `exports` (e.g. tsconfig-paths/register → register.js)
// - importResolve's import.meta.resolve is scoped to @eggjs/utils, not here
// createRequire resolves from the caller's location with CJS semantics,
// correctly handling extension resolution and flat-hoisted node_modules.
const cjsResolve = (specifier: string): string => {
for (const p of findPaths) {
try {
return createRequire(path.join(p, 'package.json')).resolve(specifier);
} catch {
/* try next path */
}
}
throw new Error(`Cannot resolve '${specifier}' from ${findPaths.join(', ')}`);
};
this.isESM = pkg.type === 'module';
if (typescript) {
flags.tscompiler = flags.tscompiler ?? 'ts-node/register';
const tsNodeRegister = importResolve(flags.tscompiler, {
paths: findPaths,
});
const tsNodeRegister = cjsResolve(flags.tscompiler);
flags.tscompiler = tsNodeRegister;
// should require tsNodeRegister on current process, let it can require *.ts files
// e.g.: dev command will execute egg loader to find configs and plugins
Expand All @@ -228,16 +243,12 @@ export abstract class BaseCommand<T extends typeof Command> extends Command {
this.env.TS_NODE_FILES = process.env.TS_NODE_FILES ?? 'true';
// keep same logic with egg-core, test cmd load files need it
// see https://github.com/eggjs/egg-core/blob/master/lib/loader/egg_loader.js#L49
const tsConfigPathsRegister = importResolve('tsconfig-paths/register', {
paths: findPaths,
});
const tsConfigPathsRegister = cjsResolve('tsconfig-paths/register');
this.addNodeOptions(this.formatImportModule(tsConfigPathsRegister));
}
if (this.isESM) {
// use ts-node/esm loader on esm
let esmLoader = importResolve('ts-node/esm', {
paths: findPaths,
});
let esmLoader = cjsResolve('ts-node/esm');
// ES Module loading with absolute path fails on windows
// https://github.com/nodejs/node/issues/31710#issuecomment-583916239
// https://nodejs.org/api/url.html#url_url_pathtofileurl_path
Expand Down
Loading
Loading