Skip to content

Commit d90a08a

Browse files
authored
Merge pull request #428 from objectstack-ai/copilot/update-node-version-warning
2 parents 0cd85ef + 18d9ad6 commit d90a08a

9 files changed

Lines changed: 49 additions & 20 deletions

File tree

apps/demo/api/[[...route]].ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,11 @@ function extractBody(incoming: VercelIncomingMessage, method: string, contentTyp
176176
if (method === 'GET' || method === 'HEAD' || method === 'OPTIONS') return null;
177177
if (incoming.rawBody != null) {
178178
if (typeof incoming.rawBody === 'string') return incoming.rawBody;
179-
return incoming.rawBody;
179+
// Convert Node.js Buffer to ArrayBuffer — required because the TypeScript lib
180+
// used during Vercel bundling (ES2019 without DOM) only guarantees ArrayBuffer
181+
// in the BodyInit union; Uint8Array is not listed in older lib.dom.d.ts.
182+
const buf = incoming.rawBody;
183+
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength) as ArrayBuffer;
180184
}
181185
if (incoming.body != null) {
182186
if (typeof incoming.body === 'string') return incoming.body;
@@ -355,7 +359,8 @@ async function bootstrap(): Promise<Hono> {
355359
...(process.env.VERCEL_PROJECT_PRODUCTION_URL ? [`https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`] : []),
356360
...(process.env.AUTH_TRUSTED_ORIGINS ? process.env.AUTH_TRUSTED_ORIGINS.split(',').map(s => s.trim()) : []),
357361
],
358-
})), PLUGIN_TIMEOUT_MS, 'AuthPlugin');
362+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
363+
} as any)), PLUGIN_TIMEOUT_MS, 'AuthPlugin');
359364
log('AuthPlugin registered.');
360365

361366
// 6. Application config — empty manifest; demo metadata is loaded via

apps/demo/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"scripts": {
88
"dev": "objectstack serve --dev",
99
"build": "tsc --noEmit",
10-
"start": "objectstack serve"
10+
"start": "objectstack serve",
11+
"postinstall": "node scripts/patch-symlinks.cjs"
1112
},
1213
"devDependencies": {
1314
"@hono/node-server": "^1.19.11",
@@ -26,9 +27,11 @@
2627
"@objectql/types": "workspace:*",
2728
"@objectstack/cli": "^3.2.8",
2829
"@objectstack/core": "^3.2.8",
30+
"@objectstack/driver-memory": "^3.2.8",
2931
"@objectstack/objectql": "^3.2.8",
3032
"@objectstack/plugin-auth": "^3.2.8",
3133
"@objectstack/plugin-hono-server": "^3.2.8",
34+
"@objectstack/runtime": "^3.2.8",
3235
"@objectstack/studio": "^3.2.8",
3336
"@types/node": "^20.19.37",
3437
"hono": "^4.12.8",

apps/demo/public/.gitkeep

Whitespace-only changes.

apps/demo/scripts/build-vercel.sh

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
# Vercel build step.
66
#
77
# Steps:
8-
# 1. Build foundation packages (types → core → platform-node)
9-
# 2. Build drivers, plugins, and protocols
8+
# 1. Build foundation packages (types → plugin-optimizations → plugins → core → platform-node)
9+
# 2. Build drivers and protocols
1010
# 3. Build the project-tracker showcase example
11-
# 4. Patch pnpm symlinks so Vercel can bundle the serverless function
1211
#
1312
# Usage (called automatically by Vercel via vercel.json):
1413
# bash scripts/build-vercel.sh
@@ -18,20 +17,25 @@ set -euo pipefail
1817
echo "▸ Building @objectql/types…"
1918
pnpm --filter @objectql/types build
2019

20+
echo "▸ Building @objectql/plugin-optimizations…"
21+
pnpm --filter @objectql/plugin-optimizations build
22+
23+
echo "▸ Building plugins…"
24+
pnpm --filter @objectql/plugin-query \
25+
--filter @objectql/plugin-validator \
26+
--filter @objectql/plugin-formula \
27+
--filter @objectql/plugin-security \
28+
build
29+
2130
echo "▸ Building @objectql/core…"
2231
pnpm --filter @objectql/core build
2332

2433
echo "▸ Building @objectql/platform-node…"
2534
pnpm --filter @objectql/platform-node build
2635

2736
echo "▸ Building drivers…"
28-
pnpm --filter @objectql/driver-memory build
29-
30-
echo "▸ Building plugins…"
31-
pnpm --filter @objectql/plugin-query \
32-
--filter @objectql/plugin-validator \
33-
--filter @objectql/plugin-formula \
34-
--filter @objectql/plugin-security \
37+
pnpm --filter @objectql/driver-memory \
38+
--filter @objectql/driver-sql \
3539
build
3640

3741
echo "▸ Building protocols…"
@@ -43,7 +47,7 @@ pnpm --filter @objectql/protocol-graphql \
4347
echo "▸ Building project-tracker example…"
4448
pnpm --filter @objectql/example-project-tracker build
4549

46-
echo "▸ Patching pnpm symlinks for Vercel"
47-
node scripts/patch-symlinks.cjs
50+
# Ensure the output directory exists (Vercel requires it when framework=null)
51+
mkdir -p public
4852

4953
echo "✓ Vercel build complete."

apps/demo/scripts/patch-symlinks.cjs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,18 @@
88
* "invalid deployment package … symlinked directories". This script
99
* replaces ALL top-level symlinks with real copies of the target
1010
* directories so that Vercel can bundle the serverless function.
11+
*
12+
* This script is invoked as a postinstall hook and is a no-op outside
13+
* the Vercel build environment (process.env.VERCEL is not set locally).
1114
*/
1215
'use strict';
1316

17+
// Only run during Vercel builds. Skip in local development to preserve
18+
// pnpm workspace symlinks for live-reload.
19+
if (!process.env.VERCEL) {
20+
process.exit(0);
21+
}
22+
1423
const fs = require('fs');
1524
const path = require('path');
1625

@@ -34,9 +43,11 @@ function derefSymlink(pkgPath) {
3443
const realPath = fs.realpathSync(abs);
3544
console.log(` → Dereferencing ${pkgPath}`);
3645

37-
// Copy to a temp location first, then swap — avoids data loss if cpSync fails
46+
// Copy to a temp location first, then swap — avoids data loss if cpSync fails.
47+
// dereference:true ensures nested pnpm .pnpm-store symlinks inside the package
48+
// are also resolved to real files, which is required by Vercel's function bundler.
3849
const tmpPath = abs + '.tmp';
39-
fs.cpSync(realPath, tmpPath, { recursive: true });
50+
fs.cpSync(realPath, tmpPath, { recursive: true, dereference: true });
4051
fs.unlinkSync(abs);
4152
fs.renameSync(tmpPath, abs);
4253
return true;

apps/demo/vercel.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"api/**/*.ts": {
88
"memory": 1024,
99
"maxDuration": 60,
10-
"includeFiles": "{packages/*/dist,node_modules/@object-ui/console/dist,node_modules/@objectstack/plugin-auth/dist,node_modules/@objectstack/studio/dist}/**"
10+
"includeFiles": "{node_modules/@object-ui/console/dist,node_modules/@objectstack/plugin-auth/dist,node_modules/@objectstack/studio/dist,node_modules/@objectql/example-project-tracker/dist}/**"
1111
}
1212
},
1313
"rewrites": [

examples/showcase/enterprise-erp/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"scripts": {
2828
"start": "ts-node src/index.ts",
2929
"codegen": "objectql types -s src -o src/types",
30-
"build": "tsc && rsync -a --include '*/' --include '*.yml' --exclude '*' src/ dist/",
30+
"build": "tsc && node -e \"const fs=require('fs'),p=require('path');function c(s,d){fs.readdirSync(s,{withFileTypes:true}).forEach(e=>{const sp=p.join(s,e.name),dp=p.join(d,e.name);if(e.isDirectory())c(sp,dp);else if(e.name.endsWith('.yml')){fs.mkdirSync(d,{recursive:true});fs.copyFileSync(sp,dp)}})}c('src','dist')\"",
3131
"test": "vitest run"
3232
},
3333
"peerDependencies": {

examples/showcase/project-tracker/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"start": "objectql start --dir src",
2929
"seed": "ts-node src/seed.ts",
3030
"codegen": "objectql types -s src -o src/types",
31-
"build": "tsc && rsync -a --include '*/' --include '*.yml' --exclude '*' src/ dist/",
31+
"build": "tsc && node -e \"const fs=require('fs'),p=require('path');function c(s,d){fs.readdirSync(s,{withFileTypes:true}).forEach(e=>{const sp=p.join(s,e.name),dp=p.join(d,e.name);if(e.isDirectory())c(sp,dp);else if(e.name.endsWith('.yml')){fs.mkdirSync(d,{recursive:true});fs.copyFileSync(sp,dp)}})}c('src','dist')\"",
3232
"repl": "objectql repl",
3333
"test": "vitest run"
3434
},

pnpm-lock.yaml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)