From 6d404fa47857dafd4b284523da9053ff006d0085 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:59:44 +0000 Subject: [PATCH 1/2] Initial plan From c5949942849e5209e5696f586d59ac181c8694b3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 16:10:06 +0000 Subject: [PATCH 2/2] feat: upgrade @objectstack to 2.0.4 and add server test environment - Upgrade @objectstack/client and @objectstack/client-react from ^2.0.1 to ^2.0.4 - Add server-side devDependencies: @objectstack/core, plugin-hono-server, plugin-auth, objectql, driver-memory, tsx - Create server/dev.ts following the authentication guide - Create server/test-auth.ts for auth flow smoke testing - Add server:dev and server:test npm scripts Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- package.json | 12 ++- pnpm-lock.yaml | 210 +++++++++++++++++++++++++++++++++++--------- server/dev.ts | 82 +++++++++++++++++ server/test-auth.ts | 62 +++++++++++++ 4 files changed, 321 insertions(+), 45 deletions(-) create mode 100644 server/dev.ts create mode 100644 server/test-auth.ts diff --git a/package.json b/package.json index 367179b..8af350b 100644 --- a/package.json +++ b/package.json @@ -13,14 +13,16 @@ "format": "prettier --write \"**/*.{ts,tsx,js,json}\"", "format:check": "prettier --check \"**/*.{ts,tsx,js,json}\"", "bundle:analyze": "npx expo export --dump-sourcemap --platform ios && npx source-map-explorer dist/bundles/ios/*.js", + "server:dev": "tsx server/dev.ts", + "server:test": "tsx server/test-auth.ts", "changeset": "changeset", "version-packages": "changeset version", "release": "changeset publish" }, "dependencies": { "@better-auth/expo": "^1.4.18", - "@objectstack/client": "^2.0.1", - "@objectstack/client-react": "^2.0.1", + "@objectstack/client": "^2.0.4", + "@objectstack/client-react": "^2.0.4", "@sentry/react-native": "^7.12.0", "@shopify/flash-list": "^2.2.2", "@tanstack/react-query": "^5.90.20", @@ -71,6 +73,11 @@ "@babel/core": "^7.29.0", "@changesets/changelog-github": "^0.5.2", "@changesets/cli": "^2.29.8", + "@objectstack/core": "^2.0.4", + "@objectstack/driver-memory": "^2.0.4", + "@objectstack/objectql": "^2.0.4", + "@objectstack/plugin-auth": "^2.0.3", + "@objectstack/plugin-hono-server": "^2.0.4", "@testing-library/jest-native": "^5.4.3", "@testing-library/react-native": "^12.9.0", "@types/jest": "^29.5.14", @@ -87,6 +94,7 @@ "msw": "^2.12.9", "prettier": "^3.5.3", "react-test-renderer": "19.1.0", + "tsx": "^4.21.0", "typescript": "~5.9.2" }, "private": true diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 290126e..3487788 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,11 +12,11 @@ importers: specifier: ^1.4.18 version: 1.4.18(@better-auth/core@1.4.18(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))(better-auth@1.4.18(next@16.1.6(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(expo-constants@18.0.13)(expo-linking@8.0.11)(expo-network@8.0.8(expo@54.0.33)(react@19.1.0))(expo-web-browser@15.0.10(expo@54.0.33)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))) '@objectstack/client': - specifier: ^2.0.1 - version: 2.0.1 + specifier: ^2.0.4 + version: 2.0.4 '@objectstack/client-react': - specifier: ^2.0.1 - version: 2.0.1(react@19.1.0) + specifier: ^2.0.4 + version: 2.0.4(react@19.1.0) '@sentry/react-native': specifier: ^7.12.0 version: 7.12.0(expo@54.0.33)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) @@ -106,7 +106,7 @@ importers: version: 0.563.0(react-native-svg@15.15.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) nativewind: specifier: ^4.2.1 - version: 4.2.1(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-svg@15.15.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(tailwindcss@3.4.19(yaml@2.8.2)) + version: 4.2.1(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-svg@15.15.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)) react: specifier: 19.1.0 version: 19.1.0 @@ -148,7 +148,7 @@ importers: version: 3.4.0 tailwindcss: specifier: ^3.4.19 - version: 3.4.19(yaml@2.8.2) + version: 3.4.19(tsx@4.21.0)(yaml@2.8.2) zustand: specifier: ^5.0.11 version: 5.0.11(@types/react@19.1.17)(react@19.1.0)(use-sync-external-store@1.6.0(react@19.1.0)) @@ -162,6 +162,21 @@ importers: '@changesets/cli': specifier: ^2.29.8 version: 2.29.8(@types/node@25.2.2) + '@objectstack/core': + specifier: ^2.0.4 + version: 2.0.4 + '@objectstack/driver-memory': + specifier: ^2.0.4 + version: 2.0.4 + '@objectstack/objectql': + specifier: ^2.0.4 + version: 2.0.4 + '@objectstack/plugin-auth': + specifier: ^2.0.3 + version: 2.0.3(next@16.1.6(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@objectstack/plugin-hono-server': + specifier: ^2.0.4 + version: 2.0.4 '@testing-library/jest-native': specifier: ^5.4.3 version: 5.4.3(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react-test-renderer@19.1.0(react@19.1.0))(react@19.1.0) @@ -210,6 +225,9 @@ importers: react-test-renderer: specifier: 19.1.0 version: 19.1.0(react@19.1.0) + tsx: + specifier: ^4.21.0 + version: 4.21.0 typescript: specifier: ~5.9.2 version: 5.9.3 @@ -1246,6 +1264,12 @@ packages: tailwindcss: optional: true + '@hono/node-server@1.19.9': + resolution: {integrity: sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + '@humanwhocodes/config-array@0.13.0': resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} engines: {node: '>=10.10.0'} @@ -1657,26 +1681,41 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@objectstack/client-react@2.0.1': - resolution: {integrity: sha512-PoSZnhNVzVLdldDxBnvAEjE7C6O4ME3FnkX9GldGQmIa4o27Wogh5DnvvvyR2PKt94xYPwPdJSt/7QftBTO5CQ==} + '@objectstack/client-react@2.0.4': + resolution: {integrity: sha512-pV/9RhxRpzPe5rRi9qOswm26w8WikFRxeQFLrsixAeNC5dyJiRyh2r1dJKGfCiUAIszKf6eKvd/KpHCOWXgP8w==} peerDependencies: react: '>=18.0.0' - '@objectstack/client@2.0.1': - resolution: {integrity: sha512-2+JUM+oxqhNger8mF/NN3AzQUkm/VZx9/6wjMoJxVklgiiLfqHELLWpkZXmVGR4g2A+mq4aqULqYsAg+gwV6qA==} + '@objectstack/client@2.0.4': + resolution: {integrity: sha512-6/1g8XBWVXqy3b6cxUDLwuRY0wDbrUAcC8m4h18NJ+ZyH9R+7FrZFt7HIknIOJx3HfHPZuCqlQNDRjsnqO9csg==} - '@objectstack/core@2.0.1': - resolution: {integrity: sha512-RX+SEBE3mLrXyR6/KZwjlvu41CepxJjmhTvt0LX05kqaX6UgGz9T5UBQUdXUSMDUsxg53mwDRkQXgrffcKSPDg==} + '@objectstack/core@2.0.4': + resolution: {integrity: sha512-mFqDxZek7n74oBxHbvAppQgAO2uGUkdJHn3Vm1+eroX5GcKB+zAz3g91uzln9wKqQNo3ZQaq/F8PBqJB1kjQxg==} peerDependencies: pino: ^8.0.0 peerDependenciesMeta: pino: optional: true - '@objectstack/spec@2.0.1': - resolution: {integrity: sha512-NgaMpmcXBT+AGQuCTwIYqVxKZkGs9WO5zeNIz17J8lPQ0SrhS+Hzv+5KVhOO98G4MqyJCDkodI8XMms/TVSMTg==} + '@objectstack/driver-memory@2.0.4': + resolution: {integrity: sha512-LdPvf2IB+5y+mVhl36tG89AL9rwRM8YShQ0wUUCE75/JqiAnpb9klcVvytA4bBVIped/dXZUP/zvqYCeq9lP8w==} + + '@objectstack/objectql@2.0.4': + resolution: {integrity: sha512-c3bim7bhmcFnSCWDM2cDbZMJvxaDPYYDTEq6CvBcpBnae7X87PpovSO0xxz7RTV3fYm8pBWMEAx0NgfSgzmlZA==} + + '@objectstack/plugin-auth@2.0.3': + resolution: {integrity: sha512-9kzUCEfqa95OqIkPvK4DpelgdcowRawKMxGs4Hbky2kz9ru2fDsv9pIBgyt7fOGD+QmMFvtMpf5U8wc7I4EHHQ==} + + '@objectstack/plugin-hono-server@2.0.4': + resolution: {integrity: sha512-/Wz+UMmuWXRbI+M41y74LNdPA9k7IeehNOaAKc1A2pUitACdMNErR0plFKLzVYfaFzOVixGBO7yu50P0pu3Z9g==} + + '@objectstack/spec@2.0.4': + resolution: {integrity: sha512-aK7/+f9KV1f2xoQsvxq7yoktevKjR51hq5on6bGBtKYU2MtxHs7TGcXG4D7EbXeQxNmYdtE3OX9Vow0GRPYNdQ==} engines: {node: '>=18.0.0'} + '@objectstack/types@2.0.4': + resolution: {integrity: sha512-Iap9gIoMen+1mEGZOmSvMZXdpNtpc+9saJqg7fbc+qd8DUCoSky+tCK13c52YAvYcBJppusB3jVKEGQHjtEoRg==} + '@open-draft/deferred-promise@2.2.0': resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} @@ -4152,6 +4191,9 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} + get-tsconfig@4.13.6: + resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} + getenv@2.0.0: resolution: {integrity: sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==} engines: {node: '>=6'} @@ -4272,6 +4314,10 @@ packages: hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + hono@4.11.9: + resolution: {integrity: sha512-Eaw2YTGM6WOxA6CXbckaEvslr2Ne4NFsKrvc0v97JD5awbmeBLO5w9Ho9L9kmKonrwF9RJlW6BxT1PVv/agBHQ==} + engines: {node: '>=16.9.0'} + hosted-git-info@7.0.2: resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} engines: {node: ^16.14.0 || >=18.0.0} @@ -6272,6 +6318,9 @@ packages: resolution: {integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==} engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve-workspace-root@2.0.1: resolution: {integrity: sha512-nR23LHAvaI6aHtMg6RWoaHpdR4D881Nydkzi2CixINyg9T00KgaJdJI6Vwty+Ps8WLxZHuxsS0BseWjxSA4C+w==} @@ -6479,8 +6528,8 @@ packages: resolution: {integrity: sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==} engines: {node: '>=8.0.0'} - sonic-boom@4.2.0: - resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + sonic-boom@4.2.1: + resolution: {integrity: sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==} source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} @@ -6811,6 +6860,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -7197,9 +7251,6 @@ packages: resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} engines: {node: '>=18'} - zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - zod@4.3.6: resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} @@ -8524,6 +8575,10 @@ snapshots: optionalDependencies: tailwindcss: 4.1.18 + '@hono/node-server@1.19.9(hono@4.11.9)': + dependencies: + hono: 4.11.9 + '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 @@ -8977,31 +9032,86 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@objectstack/client-react@2.0.1(react@19.1.0)': + '@objectstack/client-react@2.0.4(react@19.1.0)': dependencies: - '@objectstack/client': 2.0.1 - '@objectstack/core': 2.0.1 - '@objectstack/spec': 2.0.1 + '@objectstack/client': 2.0.4 + '@objectstack/core': 2.0.4 + '@objectstack/spec': 2.0.4 react: 19.1.0 transitivePeerDependencies: - pino - '@objectstack/client@2.0.1': + '@objectstack/client@2.0.4': dependencies: - '@objectstack/core': 2.0.1 - '@objectstack/spec': 2.0.1 + '@objectstack/core': 2.0.4 + '@objectstack/spec': 2.0.4 transitivePeerDependencies: - pino - '@objectstack/core@2.0.1': + '@objectstack/core@2.0.4': dependencies: - '@objectstack/spec': 2.0.1 + '@objectstack/spec': 2.0.4 pino-pretty: 13.1.3 - zod: 3.25.76 + zod: 4.3.6 + + '@objectstack/driver-memory@2.0.4': + dependencies: + '@objectstack/core': 2.0.4 + '@objectstack/spec': 2.0.4 + transitivePeerDependencies: + - pino - '@objectstack/spec@2.0.1': + '@objectstack/objectql@2.0.4': dependencies: - zod: 3.25.76 + '@objectstack/core': 2.0.4 + '@objectstack/spec': 2.0.4 + '@objectstack/types': 2.0.4 + transitivePeerDependencies: + - pino + + '@objectstack/plugin-auth@2.0.3(next@16.1.6(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@objectstack/core': 2.0.4 + '@objectstack/spec': 2.0.4 + better-auth: 1.4.18(next@16.1.6(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + transitivePeerDependencies: + - '@lynx-js/react' + - '@prisma/client' + - '@sveltejs/kit' + - '@tanstack/react-start' + - '@tanstack/solid-start' + - better-sqlite3 + - drizzle-kit + - drizzle-orm + - mongodb + - mysql2 + - next + - pg + - pino + - prisma + - react + - react-dom + - solid-js + - svelte + - vitest + - vue + + '@objectstack/plugin-hono-server@2.0.4': + dependencies: + '@hono/node-server': 1.19.9(hono@4.11.9) + '@objectstack/core': 2.0.4 + '@objectstack/spec': 2.0.4 + hono: 4.11.9 + transitivePeerDependencies: + - pino + + '@objectstack/spec@2.0.4': + dependencies: + zod: 4.3.6 + + '@objectstack/types@2.0.4': + dependencies: + '@objectstack/spec': 2.0.4 '@open-draft/deferred-promise@2.2.0': {} @@ -11930,6 +12040,10 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 + get-tsconfig@4.13.6: + dependencies: + resolve-pkg-maps: 1.0.0 + getenv@2.0.0: {} github-slugger@2.0.0: {} @@ -12094,6 +12208,8 @@ snapshots: dependencies: react-is: 16.13.1 + hono@4.11.9: {} + hosted-git-info@7.0.2: dependencies: lru-cache: 10.4.3 @@ -13811,12 +13927,12 @@ snapshots: nanostores@1.1.0: {} - nativewind@4.2.1(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-svg@15.15.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(tailwindcss@3.4.19(yaml@2.8.2)): + nativewind@4.2.1(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-svg@15.15.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)): dependencies: comment-json: 4.5.1 debug: 4.4.3 - react-native-css-interop: 0.2.1(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-svg@15.15.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(tailwindcss@3.4.19(yaml@2.8.2)) - tailwindcss: 3.4.19(yaml@2.8.2) + react-native-css-interop: 0.2.1(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-svg@15.15.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)) + tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - react - react-native @@ -14144,7 +14260,7 @@ snapshots: pino-abstract-transport: 3.0.0 pump: 3.0.3 secure-json-parse: 4.1.0 - sonic-boom: 4.2.0 + sonic-boom: 4.2.1 strip-json-comments: 5.0.3 pirates@4.0.7: {} @@ -14175,12 +14291,13 @@ snapshots: camelcase-css: 2.0.1 postcss: 8.5.6 - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.2): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 1.21.7 postcss: 8.5.6 + tsx: 4.21.0 yaml: 2.8.2 postcss-nested@6.2.0(postcss@8.5.6): @@ -14347,7 +14464,7 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - react-native-css-interop@0.2.1(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-svg@15.15.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(tailwindcss@3.4.19(yaml@2.8.2)): + react-native-css-interop@0.2.1(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-svg@15.15.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@babel/helper-module-imports': 7.28.6 '@babel/traverse': 7.29.0 @@ -14358,7 +14475,7 @@ snapshots: react-native: 0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0) react-native-reanimated: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) semver: 7.7.4 - tailwindcss: 3.4.19(yaml@2.8.2) + tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.2) optionalDependencies: react-native-safe-area-context: 5.6.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) react-native-svg: 15.15.2(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) @@ -14750,6 +14867,8 @@ snapshots: dependencies: global-dirs: 0.1.1 + resolve-pkg-maps@1.0.0: {} + resolve-workspace-root@2.0.1: {} resolve.exports@2.0.3: {} @@ -15002,7 +15121,7 @@ snapshots: slugify@1.6.6: {} - sonic-boom@4.2.0: + sonic-boom@4.2.1: dependencies: atomic-sleep: 1.0.0 @@ -15234,7 +15353,7 @@ snapshots: tailwind-merge@3.4.0: {} - tailwindcss@3.4.19(yaml@2.8.2): + tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -15253,7 +15372,7 @@ snapshots: postcss: 8.5.6 postcss-import: 15.1.0(postcss@8.5.6) postcss-js: 4.1.0(postcss@8.5.6) - postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.2) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2) postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 resolve: 1.22.11 @@ -15358,6 +15477,13 @@ snapshots: tslib@2.8.1: {} + tsx@4.21.0: + dependencies: + esbuild: 0.27.3 + get-tsconfig: 4.13.6 + optionalDependencies: + fsevents: 2.3.3 + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -15743,8 +15869,6 @@ snapshots: yoctocolors-cjs@2.1.3: {} - zod@3.25.76: {} - zod@4.3.6: {} zustand@5.0.11(@types/react@19.1.17)(react@19.1.0)(use-sync-external-store@1.6.0(react@19.1.0)): diff --git a/server/dev.ts b/server/dev.ts new file mode 100644 index 0000000..0e69a75 --- /dev/null +++ b/server/dev.ts @@ -0,0 +1,82 @@ +/** + * ObjectStack Development Server + * + * Minimal test server following the ObjectStack Authentication Guide. + * Uses in-memory driver so no external database is required. + * + * Usage: + * pnpm server:dev # Start the dev server on port 3000 + * pnpm server:test # Run the auth flow smoke test + * + * @see https://protocol.objectstack.ai/docs/guides/authentication + */ + +import { ObjectKernel } from "@objectstack/core"; +import { ObjectQL } from "@objectstack/objectql"; +import { InMemoryDriver } from "@objectstack/driver-memory"; +import { HonoServerPlugin } from "@objectstack/plugin-hono-server"; +import { AuthPlugin } from "@objectstack/plugin-auth"; + +const PORT = Number(process.env.PORT) || 3000; +const AUTH_SECRET = + process.env.AUTH_SECRET || + "dev-secret-please-change-in-production-min-32-chars"; + +async function main() { + console.log("🚀 Starting ObjectStack dev server…\n"); + + // 1. Data layer — in-memory, zero config + const objectql = new ObjectQL(); + await objectql.registerDriver(new InMemoryDriver()); + + // 2. Microkernel + const kernel = new ObjectKernel(); + kernel.registerService("data", objectql); + + // 3. HTTP adapter (Hono) + await kernel.use( + new HonoServerPlugin({ + port: PORT, + }) + ); + + // 4. Authentication plugin (better-auth) + await kernel.use( + new AuthPlugin({ + secret: AUTH_SECRET, + baseUrl: `http://localhost:${PORT}`, + }) + ); + + // 5. Boot + await kernel.bootstrap(); + + console.log("✅ Server started successfully!\n"); + console.log("📍 Authentication Endpoints:"); + console.log( + ` POST http://localhost:${PORT}/api/v1/auth/sign-up/email` + ); + console.log( + ` POST http://localhost:${PORT}/api/v1/auth/sign-in/email` + ); + console.log( + ` POST http://localhost:${PORT}/api/v1/auth/sign-out` + ); + console.log( + ` GET http://localhost:${PORT}/api/v1/auth/get-session` + ); + console.log( + `\n💡 Point the mobile app at http://localhost:${PORT}\n` + ); + + process.on("SIGINT", async () => { + console.log("\n🛑 Shutting down…"); + await kernel.shutdown(); + process.exit(0); + }); +} + +main().catch((err) => { + console.error("❌ Server failed to start:", err); + process.exit(1); +}); diff --git a/server/test-auth.ts b/server/test-auth.ts new file mode 100644 index 0000000..272bed0 --- /dev/null +++ b/server/test-auth.ts @@ -0,0 +1,62 @@ +/** + * Smoke-test for the ObjectStack dev server authentication flow. + * + * Requires the dev server to be running (`pnpm server:dev`). + * + * @see https://protocol.objectstack.ai/docs/guides/authentication + */ + +import { ObjectStackClient } from "@objectstack/client"; + +const BASE_URL = process.env.BASE_URL || "http://localhost:3000"; + +async function testAuthFlow() { + console.log("🧪 Testing Authentication Flow\n"); + + const client = new ObjectStackClient({ baseUrl: BASE_URL }); + + // 1. Register + console.log("📝 Registering new user…"); + const reg = await client.auth.register({ + email: "test@example.com", + password: "SecurePassword123!", + name: "Test User", + }); + + if (reg.data?.user) { + console.log(" ✅ Registered:", reg.data.user.email); + } + + // 2. Logout + console.log("🚪 Logging out…"); + await client.auth.logout(); + console.log(" ✅ Logged out"); + + // 3. Login + console.log("🔐 Logging in…"); + const login = await client.auth.login({ + type: "email", + email: "test@example.com", + password: "SecurePassword123!", + }); + + if (login.data?.user) { + console.log(" ✅ Logged in:", login.data.user.email); + } + + // 4. Session + console.log("👤 Getting session…"); + const session = await client.auth.me(); + + if (session.data?.user) { + console.log(" ✅ Session user:", session.data.user.email); + } + + console.log("\n✨ All authentication tests passed!\n"); +} + +testAuthFlow().catch((err) => { + console.error("\n❌ Auth test failed:", err.message); + console.error("💡 Make sure the server is running: pnpm server:dev\n"); + process.exit(1); +});