bhooai-nexus 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +184 -0
- package/apps/admin/index.html +12 -0
- package/apps/admin/package.json +25 -0
- package/apps/admin/postcss.config.js +6 -0
- package/apps/admin/public/anime-girl.svg +84 -0
- package/apps/admin/public/bhooai-nexus-logo.png +0 -0
- package/apps/admin/public/bhooai-nexus-logo.svg +135 -0
- package/apps/admin/public/favicon.ico +0 -0
- package/apps/admin/src/main.tsx +10 -0
- package/apps/admin/src/vite-env.d.ts +18 -0
- package/apps/admin/tailwind.config.js +10 -0
- package/apps/admin/tsconfig.json +17 -0
- package/apps/admin/vite.config.ts +68 -0
- package/bin/nexus.js +52 -0
- package/package.json +108 -0
- package/packages/nexus-admin/package.json +32 -0
- package/packages/nexus-admin/src/App.tsx +4878 -0
- package/packages/nexus-admin/src/alertCenter.tsx +150 -0
- package/packages/nexus-admin/src/api.ts +601 -0
- package/packages/nexus-admin/src/assets/bhooai-nexus-logo.svg +25 -0
- package/packages/nexus-admin/src/index.css +3635 -0
- package/packages/nexus-admin/src/vite-env.d.ts +19 -0
- package/packages/nexus-ads/package.json +20 -0
- package/packages/nexus-ads/src/GaqlBuilder.ts +72 -0
- package/packages/nexus-ads/src/GoogleAdsClient.ts +121 -0
- package/packages/nexus-ads/src/fetchTransport.ts +10 -0
- package/packages/nexus-ads/src/index.ts +20 -0
- package/packages/nexus-ads/src/types.ts +41 -0
- package/packages/nexus-ai-client/package.json +18 -0
- package/packages/nexus-ai-client/src/client.ts +159 -0
- package/packages/nexus-ai-client/src/errors.ts +21 -0
- package/packages/nexus-ai-client/src/index.ts +4 -0
- package/packages/nexus-ai-client/src/sse.ts +53 -0
- package/packages/nexus-ai-client/src/types.ts +174 -0
- package/packages/nexus-auth/package.json +22 -0
- package/packages/nexus-auth/src/auth.ts +116 -0
- package/packages/nexus-auth/src/bcryptjs.d.ts +10 -0
- package/packages/nexus-auth/src/cors.ts +91 -0
- package/packages/nexus-auth/src/csrf.ts +158 -0
- package/packages/nexus-auth/src/headers.ts +55 -0
- package/packages/nexus-auth/src/index.ts +11 -0
- package/packages/nexus-auth/src/jwt.ts +65 -0
- package/packages/nexus-auth/src/middleware.ts +94 -0
- package/packages/nexus-auth/src/oauth.ts +199 -0
- package/packages/nexus-auth/src/password.ts +33 -0
- package/packages/nexus-auth/src/rateLimit.ts +59 -0
- package/packages/nexus-auth/src/rbac.ts +94 -0
- package/packages/nexus-auth/src/session.ts +91 -0
- package/packages/nexus-cache/package.json +21 -0
- package/packages/nexus-cache/src/Cache.ts +155 -0
- package/packages/nexus-cache/src/PubSub.ts +98 -0
- package/packages/nexus-cache/src/RateLimiter.ts +43 -0
- package/packages/nexus-cache/src/index.ts +9 -0
- package/packages/nexus-cache/src/types.ts +47 -0
- package/packages/nexus-cli/package.json +25 -0
- package/packages/nexus-cli/src/commands/cluster.ts +133 -0
- package/packages/nexus-cli/src/commands/dev.ts +200 -0
- package/packages/nexus-cli/src/commands/doctor.ts +199 -0
- package/packages/nexus-cli/src/commands/init.ts +1009 -0
- package/packages/nexus-cli/src/commands/node.ts +106 -0
- package/packages/nexus-cli/src/commands/pysetup.ts +142 -0
- package/packages/nexus-cli/src/commands/sync.ts +116 -0
- package/packages/nexus-cli/src/commands/uninstall.ts +287 -0
- package/packages/nexus-cli/src/config-sync.ts +384 -0
- package/packages/nexus-cli/src/dotenv.ts +39 -0
- package/packages/nexus-cli/src/index.ts +94 -0
- package/packages/nexus-cli/src/supervisor.ts +394 -0
- package/packages/nexus-cli/src/util.ts +132 -0
- package/packages/nexus-cli/src/wizard.ts +149 -0
- package/packages/nexus-cli/templates/Dockerfile +60 -0
- package/packages/nexus-cli/templates/README.md +69 -0
- package/packages/nexus-cli/templates/apps/admin/index.html +12 -0
- package/packages/nexus-cli/templates/apps/admin/package.json +24 -0
- package/packages/nexus-cli/templates/apps/admin/postcss.config.js +6 -0
- package/packages/nexus-cli/templates/apps/admin/src/main.tsx +10 -0
- package/packages/nexus-cli/templates/apps/admin/src/vite-env.d.ts +18 -0
- package/packages/nexus-cli/templates/apps/admin/tailwind.config.js +9 -0
- package/packages/nexus-cli/templates/apps/admin/tsconfig.json +17 -0
- package/packages/nexus-cli/templates/apps/admin/vite.config.ts +64 -0
- package/packages/nexus-cli/templates/apps/ai-server/main.py +43 -0
- package/packages/nexus-cli/templates/apps/ai-server/providers/__init__.py +3 -0
- package/packages/nexus-cli/templates/apps/ai-server/providers/base.py +111 -0
- package/packages/nexus-cli/templates/apps/ai-server/requirements.txt +3 -0
- package/packages/nexus-cli/templates/apps/ai-server/routers/__init__.py +3 -0
- package/packages/nexus-cli/templates/apps/ai-server/routers/chat.py +47 -0
- package/packages/nexus-cli/templates/apps/ai-server/routers/embeddings.py +30 -0
- package/packages/nexus-cli/templates/apps/ai-server/routers/lint.py +167 -0
- package/packages/nexus-cli/templates/apps/ai-server/routers/models.py +23 -0
- package/packages/nexus-cli/templates/apps/ai-server/routers/preflight.py +169 -0
- package/packages/nexus-cli/templates/apps/ai-server/settings.py +48 -0
- package/packages/nexus-cli/templates/apps/backend/package.json +34 -0
- package/packages/nexus-cli/templates/apps/backend/src/main.ts +375 -0
- package/packages/nexus-cli/templates/apps/backend/src/modules/admin/adminRoutes.ts +732 -0
- package/packages/nexus-cli/templates/apps/backend/src/modules/admin/clusterRoutes.ts +391 -0
- package/packages/nexus-cli/templates/apps/backend/src/modules/admin/databaseRoutes.ts +161 -0
- package/packages/nexus-cli/templates/apps/backend/src/modules/admin/lintProxy.ts +89 -0
- package/packages/nexus-cli/templates/apps/backend/src/modules/admin/preflightProxy.ts +242 -0
- package/packages/nexus-cli/templates/apps/backend/src/modules/admin/roleCatalog.ts +78 -0
- package/packages/nexus-cli/templates/apps/backend/src/modules/admin/schemaRoutes.ts +449 -0
- package/packages/nexus-cli/templates/apps/backend/src/modules/ai/aiProxy.ts +265 -0
- package/packages/nexus-cli/templates/apps/backend/src/modules/auth/authRoutes.ts +220 -0
- package/packages/nexus-cli/templates/apps/backend/src/modules/payments/paymentRoutes.ts +100 -0
- package/packages/nexus-cli/templates/apps/backend/src/modules/payments/paymentStore.ts +172 -0
- package/packages/nexus-cli/templates/apps/backend/src/modules/requests/requestLog.ts +175 -0
- package/packages/nexus-cli/templates/apps/backend/src/modules/users/userGraph.ts +83 -0
- package/packages/nexus-cli/templates/apps/backend/src/modules/users/userModel.ts +88 -0
- package/packages/nexus-cli/templates/apps/backend/src/plugins/CronScheduler.ts +69 -0
- package/packages/nexus-cli/templates/apps/backend/src/plugins/loadPlugins.ts +107 -0
- package/packages/nexus-cli/templates/apps/backend/tsconfig.json +14 -0
- package/packages/nexus-cli/templates/apps/frontend/index.html +12 -0
- package/packages/nexus-cli/templates/apps/frontend/package.json +19 -0
- package/packages/nexus-cli/templates/apps/frontend/src/main.tsx +64 -0
- package/packages/nexus-cli/templates/apps/frontend/vite.config.ts +72 -0
- package/packages/nexus-cli/templates/bin/nexus.js +35 -0
- package/packages/nexus-cli/templates/bin/serve-all.mjs +45 -0
- package/packages/nexus-cli/templates/dockerignore +15 -0
- package/packages/nexus-cli/templates/gitignore +12 -0
- package/packages/nexus-cli/templates/nexus.config.ts +69 -0
- package/packages/nexus-cli/templates/package.json +47 -0
- package/packages/nexus-cli/templates/tsconfig.json +17 -0
- package/packages/nexus-cli/templates/uploads/.gitkeep +0 -0
- package/packages/nexus-core/package.json +38 -0
- package/packages/nexus-core/src/config/ConfigLoader.ts +161 -0
- package/packages/nexus-core/src/config/defaults.ts +155 -0
- package/packages/nexus-core/src/config/env.ts +113 -0
- package/packages/nexus-core/src/config/index.ts +6 -0
- package/packages/nexus-core/src/config/merge.ts +28 -0
- package/packages/nexus-core/src/config/schema.ts +184 -0
- package/packages/nexus-core/src/config/types.ts +352 -0
- package/packages/nexus-core/src/di/Container.ts +98 -0
- package/packages/nexus-core/src/di/index.ts +1 -0
- package/packages/nexus-core/src/errors.ts +62 -0
- package/packages/nexus-core/src/http/Router.ts +149 -0
- package/packages/nexus-core/src/http/Server.ts +145 -0
- package/packages/nexus-core/src/http/bodyParser.ts +129 -0
- package/packages/nexus-core/src/http/context.ts +112 -0
- package/packages/nexus-core/src/http/index.ts +6 -0
- package/packages/nexus-core/src/http/static.ts +85 -0
- package/packages/nexus-core/src/http/uploads.ts +94 -0
- package/packages/nexus-core/src/index.ts +4 -0
- package/packages/nexus-crypto/package.json +18 -0
- package/packages/nexus-crypto/src/csr.ts +165 -0
- package/packages/nexus-crypto/src/der.ts +262 -0
- package/packages/nexus-crypto/src/https.ts +36 -0
- package/packages/nexus-crypto/src/index.ts +5 -0
- package/packages/nexus-crypto/src/keypair.ts +59 -0
- package/packages/nexus-crypto/src/x509.ts +156 -0
- package/packages/nexus-data/package.json +27 -0
- package/packages/nexus-data/src/connection/Connection.ts +57 -0
- package/packages/nexus-data/src/connection/ConnectionManager.ts +37 -0
- package/packages/nexus-data/src/errors.ts +17 -0
- package/packages/nexus-data/src/index.ts +66 -0
- package/packages/nexus-data/src/model/Document.ts +126 -0
- package/packages/nexus-data/src/model/Model.ts +189 -0
- package/packages/nexus-data/src/model/hydrate.ts +12 -0
- package/packages/nexus-data/src/populate/populate.ts +114 -0
- package/packages/nexus-data/src/projects.ts +185 -0
- package/packages/nexus-data/src/query/Query.ts +158 -0
- package/packages/nexus-data/src/schema/Schema.ts +173 -0
- package/packages/nexus-data/src/schema/SchemaType.ts +80 -0
- package/packages/nexus-data/src/schema/validators.ts +88 -0
- package/packages/nexus-email/package.json +22 -0
- package/packages/nexus-email/src/EmailService.ts +76 -0
- package/packages/nexus-email/src/TemplateEngine.ts +62 -0
- package/packages/nexus-email/src/index.ts +37 -0
- package/packages/nexus-email/src/providers.ts +63 -0
- package/packages/nexus-email/src/queue.ts +103 -0
- package/packages/nexus-email/src/types.ts +49 -0
- package/packages/nexus-graphql/package.json +24 -0
- package/packages/nexus-graphql/src/federation/composeSupergraph.ts +153 -0
- package/packages/nexus-graphql/src/federation/createFederatedGateway.ts +36 -0
- package/packages/nexus-graphql/src/federation/executor.ts +305 -0
- package/packages/nexus-graphql/src/federation/parseMetadata.ts +87 -0
- package/packages/nexus-graphql/src/gateway/createGateway.ts +77 -0
- package/packages/nexus-graphql/src/gateway/fieldResolver.ts +45 -0
- package/packages/nexus-graphql/src/gateway/graphqlHttpHandler.ts +90 -0
- package/packages/nexus-graphql/src/gateway/publicSchema.ts +26 -0
- package/packages/nexus-graphql/src/index.ts +14 -0
- package/packages/nexus-graphql/src/subgraph/defineSubgraph.ts +115 -0
- package/packages/nexus-graphql/src/subgraph/federationDirectives.ts +47 -0
- package/packages/nexus-graphql/src/subgraph/parseKeys.ts +25 -0
- package/packages/nexus-graphql/src/subscriptions/PubSub.ts +64 -0
- package/packages/nexus-graphql/src/subscriptions/SubscriptionServer.ts +203 -0
- package/packages/nexus-graphql/src/types.ts +77 -0
- package/packages/nexus-payments/package.json +20 -0
- package/packages/nexus-payments/src/errors.ts +15 -0
- package/packages/nexus-payments/src/http.ts +53 -0
- package/packages/nexus-payments/src/index.ts +106 -0
- package/packages/nexus-payments/src/providers/PayPalProvider.ts +192 -0
- package/packages/nexus-payments/src/providers/PayUProvider.ts +164 -0
- package/packages/nexus-payments/src/providers/PayoneerProvider.ts +122 -0
- package/packages/nexus-payments/src/providers/RazorpayProvider.ts +184 -0
- package/packages/nexus-payments/src/providers/SkrillProvider.ts +117 -0
- package/packages/nexus-payments/src/signature.ts +24 -0
- package/packages/nexus-payments/src/types.ts +150 -0
- package/packages/nexus-payments/src/webhooks.ts +58 -0
- package/packages/nexus-plugins/package.json +20 -0
- package/packages/nexus-plugins/src/HookBus.ts +42 -0
- package/packages/nexus-plugins/src/admin/adminExtensions.ts +53 -0
- package/packages/nexus-plugins/src/host.ts +105 -0
- package/packages/nexus-plugins/src/index.ts +8 -0
- package/packages/nexus-plugins/src/manifest.ts +73 -0
- package/packages/nexus-plugins/src/registry.ts +123 -0
- package/packages/nexus-plugins/src/runtime/TrustedPlugin.ts +134 -0
- package/packages/nexus-plugins/src/sandbox/SandboxedPlugin.ts +279 -0
- package/packages/nexus-plugins/src/sandbox/capabilityPolicy.ts +68 -0
- package/packages/nexus-plugins/src/sandbox/workerBootstrap.mjs +211 -0
- package/packages/nexus-realtime/package.json +26 -0
- package/packages/nexus-realtime/src/adapter/PubSubAdapter.ts +42 -0
- package/packages/nexus-realtime/src/adapter/RedisPubSubAdapter.ts +59 -0
- package/packages/nexus-realtime/src/index.ts +5 -0
- package/packages/nexus-realtime/src/mediasoup/MediasoupAdapter.ts +176 -0
- package/packages/nexus-realtime/src/server/RealtimeServer.ts +252 -0
- package/packages/nexus-realtime/src/types.ts +52 -0
- package/packages/nexus-telemetry/package.json +20 -0
- package/packages/nexus-telemetry/src/index.ts +3 -0
- package/packages/nexus-telemetry/src/logger/Logger.ts +178 -0
- package/packages/nexus-telemetry/src/metrics/Metrics.ts +123 -0
- package/packages/nexus-telemetry/src/trace.ts +28 -0
package/README.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# BhooAI Nexus
|
|
2
|
+
|
|
3
|
+
A Node-based full-stack framework: websockets, GraphQL federation (no Apollo), inbuilt CSRF/CORS, a from-scratch ODM on the MongoDB driver, Google/Facebook OAuth, five payment gateways, email, public/private certificate generation, Redis cache, Google Ads, WebRTC live streaming, a Python AI server (OpenAI + Ollama), an admin project, and a plugin system — all driven by a single `nexus.config.ts` and a `/bin` CLI.
|
|
4
|
+
|
|
5
|
+
This directory is the package and workspace root. Its `package.json` and
|
|
6
|
+
`package-lock.json` live here; the parent `BhooAI-Nexus/` directory is only a
|
|
7
|
+
container and is not an npm project.
|
|
8
|
+
|
|
9
|
+
The `apps/admin/` panel is built into this package and shared by every project created
|
|
10
|
+
with `nexus init`. Generated projects only contain a launcher; the common panel
|
|
11
|
+
source remains owned by this package.
|
|
12
|
+
|
|
13
|
+
## Layout
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
packages/ scoped framework packages (@bhooai/nexus-*)
|
|
17
|
+
apps/ backend (Node), frontend (React+Vite+Tailwind), ai-server (Python FastAPI)
|
|
18
|
+
apps/admin/ admin project (React+Vite+TS) — manages config, plugins, the user project
|
|
19
|
+
bin/ CLI entry — `node bin/nexus.js <command>`
|
|
20
|
+
contracts/ Node↔Python contract (single source of truth)
|
|
21
|
+
plugins/ user-created plugins
|
|
22
|
+
tests/ cross-service e2e (Playwright) driving the real backend
|
|
23
|
+
logs/ certs/ generated at runtime (gitignored)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick start
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install # install workspaces
|
|
30
|
+
npm run doctor # verify node/python/mongo/redis
|
|
31
|
+
npm run dev # start the four terminals under the supervisor
|
|
32
|
+
npm test # vitest (Node) + pytest (Python)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Use as an npm package
|
|
36
|
+
|
|
37
|
+
Publish the public workspace packages together from the framework repository:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm publish
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Then a new app can be created without copying the framework repository:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
mkdir my-app
|
|
47
|
+
cd my-app
|
|
48
|
+
npm init -y
|
|
49
|
+
npm install C:\server\BhooAI\BhooAI-Nexus\BhooAI-Nexus\bhooai-nexus
|
|
50
|
+
npx nexus init .
|
|
51
|
+
npm run doctor
|
|
52
|
+
npm run dev
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`bhooai-nexus` installs the `nexus` executable. `nexus init` copies the backend, frontend, AI,
|
|
56
|
+
admin, config, and `uploads/` scaffold into the current directory, then automatically runs
|
|
57
|
+
`npm install` for React, Vite, the admin workspace, and framework packages. Use
|
|
58
|
+
`nexus init . --skip-install` when dependency installation should be deferred.
|
|
59
|
+
|
|
60
|
+
Four terminals boot under one supervisor: backend (`:4000`), frontend (`:3000`),
|
|
61
|
+
admin (`:3001`), and the Python AI server (`:8000`). Each is also runnable standalone.
|
|
62
|
+
|
|
63
|
+
## Scaffold a new project
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
node bin/nexus.js init ./my-app
|
|
67
|
+
cd my-app
|
|
68
|
+
npm run doctor # check the environment
|
|
69
|
+
npm run dev # start all four terminals
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`init` copies a real, runnable project tree from `packages/nexus-cli/templates/`
|
|
73
|
+
— the generated backend boots a Nexus HTTP server with the full security stack
|
|
74
|
+
(CSRF/CORS/security headers) and serves `/health`, `/csrf-token`, `/echo`, and the CSRF-protected
|
|
75
|
+
multipart upload endpoint `/uploads`. Uploaded files are stored below the project-local `uploads/`
|
|
76
|
+
directory and served at `/uploads/<generated-name>`.
|
|
77
|
+
|
|
78
|
+
## Configuration
|
|
79
|
+
|
|
80
|
+
Edit `nexus.config.ts`. Precedence (low → high): code defaults < `nexus.config.ts`
|
|
81
|
+
< `nexus.runtime.json` (admin write-back, gitignored) < env vars < CLI flags.
|
|
82
|
+
Put secrets directly in a project-root `.env` (no `.env.example` — the framework
|
|
83
|
+
loads `.env` itself). Admin overrides write only to
|
|
84
|
+
`nexus.runtime.json` so the human config file stays clean.
|
|
85
|
+
|
|
86
|
+
## Admin console
|
|
87
|
+
|
|
88
|
+
The admin app (`apps/admin/`, Vite on `:3001`, backend-adjacent) is an `admin`-role
|
|
89
|
+
login gate plus a glass dashboard. Overview, Processes, Configuration, Environment,
|
|
90
|
+
Plugins, Users, Monitoring, Payments, Databases, and AI Schema.
|
|
91
|
+
|
|
92
|
+
- **Theme & mode** — three themes (Aurora, Midnight, Violet) and three interface
|
|
93
|
+
modes (Workspace, Compact, Focus), persisted in browser local storage and applied
|
|
94
|
+
to the login screen too. Desktop shell is a fixed 80% of the actual screen width;
|
|
95
|
+
responsive down to a full-width mobile drawer.
|
|
96
|
+
- **Configuration** — grouped key/value editor (add-key box on top, autoloads the
|
|
97
|
+
current config) writing to `nexus.runtime.json`, plus an effective merged view
|
|
98
|
+
and a raw source editor for `nexus.config.ts`.
|
|
99
|
+
- **Environment** — masked grouped key/value editor for `.env`; secrets stay on
|
|
100
|
+
disk and are never returned to the browser.
|
|
101
|
+
- **Safety** — custom restart-required dialog after config/env saves and a
|
|
102
|
+
confirmation dialog for destructive database/collection drops; writes are
|
|
103
|
+
schema-validated with atomic file replacement.
|
|
104
|
+
|
|
105
|
+
See [`apps/admin/README.md`](apps/admin/README.md) for full details and routes.
|
|
106
|
+
|
|
107
|
+
## Testing & CI
|
|
108
|
+
|
|
109
|
+
- **Unit/integration:** `npx vitest run` across all workspace packages (real MongoDB
|
|
110
|
+
via `.env`; Redis optional). Frontend client tests run under `apps/frontend`.
|
|
111
|
+
- **Python:** `pytest` in `apps/ai-server` (FastAPI contract tests).
|
|
112
|
+
- **E2E:** `npx playwright test --config=playwright.config.ts` boots the real backend
|
|
113
|
+
on a throwaway port + DB and drives auth → CSRF → GraphQL → payments end to end.
|
|
114
|
+
- **CI:** `workflows/ci.yml` runs a **Linux** job (full suite with Mongo + Redis
|
|
115
|
+
service containers, pytest, Playwright e2e) and a **Windows** job (build, the
|
|
116
|
+
Mongo/Redis-free unit suites, frontend tests, and `nexus init`/`doctor` verification).
|
|
117
|
+
|
|
118
|
+
## Documentation
|
|
119
|
+
|
|
120
|
+
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — full architecture, data flow, and
|
|
121
|
+
component deep-dives (federation, ODM, plugins).
|
|
122
|
+
- [`docs/IMPROVEMENTS.md`](docs/IMPROVEMENTS.md) — improvements made during the build,
|
|
123
|
+
28 suggested next steps, and an honest seams table.
|
|
124
|
+
- Per-package READMEs under `packages/nexus-*/README.md`.
|
|
125
|
+
- [`apps/admin/README.md`](apps/admin/README.md) — admin console UI, theme, and config/env editing.
|
|
126
|
+
|
|
127
|
+
## Status — complete (12/12 phases)
|
|
128
|
+
|
|
129
|
+
- ✅ Phase 0 — Foundations (config loader + precedence, DI, telemetry, CLI doctor/init, supervisor)
|
|
130
|
+
- ✅ Phase 1 — HTTP + Security (custom `node:http` server, trie router, CSRF/CORS/headers/rate-limit)
|
|
131
|
+
- ✅ Phase 2 — Data layer (custom ODM on the `mongodb` driver — schemas, hooks, populate, transactions, indexes)
|
|
132
|
+
- ✅ Phase 3 — Auth (local JWT+refresh+sessions, Google + Facebook OAuth2, CSRF on auth + WS upgrade)
|
|
133
|
+
- ✅ Phase 4 — Realtime + WebRTC signaling (WS rooms, Redis adapter, WS auth, mediasoup SFU)
|
|
134
|
+
- ✅ Phase 5 — GraphQL (single subgraph, `_service`/`_entities`, subscriptions over WS)
|
|
135
|
+
- ✅ Phase 6 — Federation (composition, supergraph SDL, query planner, entity joins, `@provides`/`@requires`)
|
|
136
|
+
- ✅ Phase 7 — Payments (Razorpay + PayPal full, PayU/Skrill/Payoneer happy-path) + Email + Crypto (keypair/X.509/CSR) + Cache + Ads
|
|
137
|
+
- ✅ Phase 8 — Plugins (trusted in-process + sandboxed worker_threads, capability policy, admin extensions)
|
|
138
|
+
- ✅ Phase 9 — Python AI server (FastAPI, OpenAI + Ollama, SSE) + Node AI client
|
|
139
|
+
- ✅ Phase 10 — Admin + supervisor (process control API, config editor → runtime.json, plugins, users, monitoring)
|
|
140
|
+
- ✅ Phase 11 — Frontend (React + Vite + Tailwind; auth UI, non-Apollo graphql client, WS client, checkout, live-stream viewer)
|
|
141
|
+
- ✅ Phase 12 — Hardening, docs, e2e, release (Playwright e2e, Win+Linux CI, `nexus init` upgrade, docs)
|
|
142
|
+
|
|
143
|
+
## Dependency policy
|
|
144
|
+
|
|
145
|
+
Built from scratch where it matters: **no Apollo**, **no mongoose**, **no express**.
|
|
146
|
+
Allowed: `graphql` (graphql-js core), `mongodb`, `ws`, `nodemailer`, `node-redis`,
|
|
147
|
+
`bcrypt`, `jose`, `mediasoup`/`mediasoup-client`, `google-ads-api`. The federation
|
|
148
|
+
layer, ODM, HTTP server, and plugin sandbox are all hand-rolled.
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
## Docker Windows
|
|
152
|
+
|
|
153
|
+
In project directory, open PowerShell and run:
|
|
154
|
+
```bash
|
|
155
|
+
`.\docker.ps1 run` # start the container
|
|
156
|
+
`.\docker.ps1 build` # build the image first
|
|
157
|
+
`.\docker.ps1 run -f` # start + follow logs
|
|
158
|
+
`.\docker.ps1 logs` # tail logs
|
|
159
|
+
`.\docker.ps1 stop` # stop container
|
|
160
|
+
`.\docker.ps1 rm` # stop + remove
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Or from cmd:
|
|
164
|
+
```bash
|
|
165
|
+
`docker.bat build`
|
|
166
|
+
`docker.bat run`
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Note: if PowerShell blocks it, allow first with:
|
|
170
|
+
Set-ExecutionPolicy -Scope Process Bypass
|
|
171
|
+
After run, access:
|
|
172
|
+
```ps1
|
|
173
|
+
frontend http://localhost:3000
|
|
174
|
+
admin http://localhost:3001
|
|
175
|
+
backend http://localhost:4000/health
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Docker Linux
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
cd project-directory
|
|
182
|
+
./docker.sh build
|
|
183
|
+
./docker.sh run
|
|
184
|
+
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>BhooAI Nexus Admin</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body class="bg-mesh text-slate-100">
|
|
9
|
+
<div id="root"></div>
|
|
10
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bhooai/admin-host",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite --port 3300",
|
|
8
|
+
"build": "tsc -b && vite build",
|
|
9
|
+
"preview": "vite preview"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"react": "^18.3.1",
|
|
13
|
+
"react-dom": "^18.3.1"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@types/react": "^18.3.0",
|
|
17
|
+
"@types/react-dom": "^18.3.0",
|
|
18
|
+
"@vitejs/plugin-react": "^4.3.0",
|
|
19
|
+
"autoprefixer": "^10.4.20",
|
|
20
|
+
"postcss": "^8.4.47",
|
|
21
|
+
"tailwindcss": "^3.4.13",
|
|
22
|
+
"typescript": "^5.6.2",
|
|
23
|
+
"vite": "^5.4.0"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 1000" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">Anime girl portrait</title>
|
|
3
|
+
<desc id="desc">A colorful anime-style girl portrait with violet hair and teal eyes.</desc>
|
|
4
|
+
<defs>
|
|
5
|
+
<linearGradient id="sky" x1="0" y1="0" x2="1" y2="1">
|
|
6
|
+
<stop offset="0" stop-color="#17133d"/>
|
|
7
|
+
<stop offset="0.52" stop-color="#5c2e83"/>
|
|
8
|
+
<stop offset="1" stop-color="#f08cae"/>
|
|
9
|
+
</linearGradient>
|
|
10
|
+
<linearGradient id="hair" x1="0" y1="0" x2="1" y2="1">
|
|
11
|
+
<stop offset="0" stop-color="#b9a1ff"/>
|
|
12
|
+
<stop offset="0.5" stop-color="#6848bf"/>
|
|
13
|
+
<stop offset="1" stop-color="#35246e"/>
|
|
14
|
+
</linearGradient>
|
|
15
|
+
<linearGradient id="shirt" x1="0" y1="0" x2="1" y2="1">
|
|
16
|
+
<stop offset="0" stop-color="#f8f6ff"/>
|
|
17
|
+
<stop offset="1" stop-color="#b6c7ff"/>
|
|
18
|
+
</linearGradient>
|
|
19
|
+
<filter id="blur"><feGaussianBlur stdDeviation="28"/></filter>
|
|
20
|
+
<filter id="glow"><feGaussianBlur stdDeviation="7"/></filter>
|
|
21
|
+
</defs>
|
|
22
|
+
|
|
23
|
+
<rect width="800" height="1000" fill="url(#sky)"/>
|
|
24
|
+
<circle cx="110" cy="180" r="150" fill="#6ee7f9" opacity=".2" filter="url(#blur)"/>
|
|
25
|
+
<circle cx="690" cy="690" r="220" fill="#f9a8d4" opacity=".25" filter="url(#blur)"/>
|
|
26
|
+
<circle cx="650" cy="140" r="5" fill="#fff" opacity=".9"/>
|
|
27
|
+
<circle cx="140" cy="430" r="4" fill="#fff" opacity=".8"/>
|
|
28
|
+
<circle cx="710" cy="360" r="3" fill="#fff" opacity=".8"/>
|
|
29
|
+
<path d="M88 260l5 12 13 5-13 5-5 13-5-13-13-5 13-5zM670 230l4 10 11 4-11 4-4 11-4-11-11-4 11-4z" fill="#ffe4f0" opacity=".9"/>
|
|
30
|
+
|
|
31
|
+
<!-- soft halo -->
|
|
32
|
+
<ellipse cx="400" cy="390" rx="260" ry="280" fill="#d8c4ff" opacity=".28" filter="url(#glow)"/>
|
|
33
|
+
|
|
34
|
+
<!-- shoulders and sailor collar -->
|
|
35
|
+
<path d="M135 1000c12-160 85-245 190-275h150c105 30 178 115 190 275z" fill="url(#shirt)"/>
|
|
36
|
+
<path d="M320 736l80 112 80-112 75 38-74 127H319l-74-127z" fill="#5343a8" opacity=".9"/>
|
|
37
|
+
<path d="M328 742l72 103 72-103 23 12-95 140-95-140z" fill="#f7d6ff"/>
|
|
38
|
+
<path d="M355 835h90l-18 165h-54z" fill="#4d3b98" opacity=".8"/>
|
|
39
|
+
|
|
40
|
+
<!-- neck -->
|
|
41
|
+
<path d="M332 660h136v118c-25 45-111 45-136 0z" fill="#f3b39f"/>
|
|
42
|
+
<path d="M332 669c30 28 95 35 136 0v62c-37 38-101 34-136 0z" fill="#d88982" opacity=".35"/>
|
|
43
|
+
|
|
44
|
+
<!-- hair behind face -->
|
|
45
|
+
<path d="M190 390c-16-180 85-300 218-300 155 0 246 111 205 300l-25 280c-37 73-102 104-151 87l-42-95H334l-42 95c-52 18-120-20-151-91z" fill="url(#hair)" stroke="#2b1d5f" stroke-width="9"/>
|
|
46
|
+
<path d="M208 382c-21-128 61-257 197-257 130 0 215 92 203 226-35-102-102-149-187-159-63 77-133 134-213 190z" fill="#9b83ed" opacity=".5"/>
|
|
47
|
+
<path d="M202 448c-38 75-31 183 8 242 16-84 44-137 79-171l-22-111zM598 443c38 77 31 186-8 247-16-87-43-140-80-174l21-109z" fill="#48318d"/>
|
|
48
|
+
|
|
49
|
+
<!-- face -->
|
|
50
|
+
<path d="M273 337c0-105 57-171 127-171 82 0 129 68 129 171v166c-18 109-74 170-129 170s-111-61-127-170z" fill="#f8c2ae" stroke="#dc8f8b" stroke-width="5"/>
|
|
51
|
+
<path d="M274 438c18 88 59 133 126 133s108-45 128-133v69c-17 111-72 166-128 166s-111-55-126-166z" fill="#e89e96" opacity=".24"/>
|
|
52
|
+
|
|
53
|
+
<!-- bangs -->
|
|
54
|
+
<path d="M230 361c5-128 66-219 170-219 116 0 164 94 169 201-37-60-74-84-116-90-20 45-53 84-83 103l9-105c-48 59-92 91-149 110z" fill="url(#hair)" stroke="#2b1d5f" stroke-width="8" stroke-linejoin="round"/>
|
|
55
|
+
<path d="M287 276c36-69 77-94 117-105-25 35-40 70-45 108 52-36 91-70 109-108 25 31 37 66 42 106-67-31-141-23-223-1z" fill="#c5b5ff" opacity=".35"/>
|
|
56
|
+
|
|
57
|
+
<!-- ears and earrings -->
|
|
58
|
+
<ellipse cx="267" cy="472" rx="18" ry="36" fill="#f1af9f"/>
|
|
59
|
+
<ellipse cx="533" cy="472" rx="18" ry="36" fill="#f1af9f"/>
|
|
60
|
+
<circle cx="260" cy="509" r="8" fill="#6ee7f9"/>
|
|
61
|
+
<circle cx="540" cy="509" r="8" fill="#6ee7f9"/>
|
|
62
|
+
|
|
63
|
+
<!-- eyes -->
|
|
64
|
+
<path d="M302 444c24-25 60-22 82 2-20 35-63 40-82-2z" fill="#fff" stroke="#38276f" stroke-width="7"/>
|
|
65
|
+
<ellipse cx="348" cy="447" rx="17" ry="25" fill="#24c7c8"/>
|
|
66
|
+
<ellipse cx="350" cy="451" rx="8" ry="14" fill="#173c72"/>
|
|
67
|
+
<circle cx="356" cy="438" r="5" fill="#fff"/>
|
|
68
|
+
<path d="M416 446c23-24 59-27 82-2-19 42-62 37-82 2z" fill="#fff" stroke="#38276f" stroke-width="7"/>
|
|
69
|
+
<ellipse cx="452" cy="447" rx="17" ry="25" fill="#24c7c8"/>
|
|
70
|
+
<ellipse cx="450" cy="451" rx="8" ry="14" fill="#173c72"/>
|
|
71
|
+
<circle cx="456" cy="438" r="5" fill="#fff"/>
|
|
72
|
+
<path d="M300 416c26-22 60-24 86-3M414 413c28-23 61-20 87 4" fill="none" stroke="#3b2873" stroke-width="10" stroke-linecap="round"/>
|
|
73
|
+
|
|
74
|
+
<!-- nose and smile -->
|
|
75
|
+
<path d="M398 461l-12 48 17 5" fill="none" stroke="#ca7d7c" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
76
|
+
<path d="M365 554c22 19 49 19 71 0" fill="none" stroke="#ad596e" stroke-width="6" stroke-linecap="round"/>
|
|
77
|
+
<path d="M372 557c18 8 39 8 57 0-7 24-49 24-57 0z" fill="#e7829a" opacity=".8"/>
|
|
78
|
+
<ellipse cx="299" cy="529" rx="31" ry="13" fill="#f98f9f" opacity=".25"/>
|
|
79
|
+
<ellipse cx="501" cy="529" rx="31" ry="13" fill="#f98f9f" opacity=".25"/>
|
|
80
|
+
|
|
81
|
+
<!-- foreground sparkles -->
|
|
82
|
+
<path d="M128 730l8 20 20 8-20 8-8 20-8-20-20-8 20-8zM674 800l7 17 17 7-17 7-7 17-7-17-17-7 17-7z" fill="#fff" opacity=".82"/>
|
|
83
|
+
<path d="M595 710c22-20 45-20 67 0-22 20-45 20-67 0z" fill="#8be9f2" opacity=".7"/>
|
|
84
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
<svg
|
|
2
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
3
|
+
width="1920"
|
|
4
|
+
height="1024"
|
|
5
|
+
viewBox="0 0 1920 1024"
|
|
6
|
+
role="img"
|
|
7
|
+
aria-labelledby="title desc"
|
|
8
|
+
>
|
|
9
|
+
<title id="title">BhooAI Nexus</title>
|
|
10
|
+
<desc id="desc">BhooAI Nexus futuristic hexagonal logo and wordmark.</desc>
|
|
11
|
+
<defs>
|
|
12
|
+
<linearGradient
|
|
13
|
+
id="edge"
|
|
14
|
+
x1="140"
|
|
15
|
+
y1="120"
|
|
16
|
+
x2="820"
|
|
17
|
+
y2="900"
|
|
18
|
+
gradientUnits="userSpaceOnUse"
|
|
19
|
+
>
|
|
20
|
+
<stop stop-color="#67e8f9" />
|
|
21
|
+
<stop offset=".5" stop-color="#818cf8" />
|
|
22
|
+
<stop offset="1" stop-color="#d8b4fe" />
|
|
23
|
+
</linearGradient>
|
|
24
|
+
<linearGradient
|
|
25
|
+
id="word"
|
|
26
|
+
x1="900"
|
|
27
|
+
y1="360"
|
|
28
|
+
x2="1740"
|
|
29
|
+
y2="680"
|
|
30
|
+
gradientUnits="userSpaceOnUse"
|
|
31
|
+
>
|
|
32
|
+
<stop stop-color="#fff" />
|
|
33
|
+
<stop offset=".55" stop-color="#a5f3fc" />
|
|
34
|
+
<stop offset="1" stop-color="#c4b5fd" />
|
|
35
|
+
</linearGradient>
|
|
36
|
+
<radialGradient id="core" cx="50%" cy="42%" r="65%">
|
|
37
|
+
<stop stop-color="#172554" />
|
|
38
|
+
<stop offset=".72" stop-color="#081326" />
|
|
39
|
+
<stop offset="1" stop-color="#030712" />
|
|
40
|
+
</radialGradient>
|
|
41
|
+
<filter id="glow" x="-40%" y="-40%" width="180%" height="180%">
|
|
42
|
+
<feGaussianBlur stdDeviation="16" result="blur" />
|
|
43
|
+
<feMerge>
|
|
44
|
+
<feMergeNode in="blur" />
|
|
45
|
+
<feMergeNode in="SourceGraphic" />
|
|
46
|
+
</feMerge>
|
|
47
|
+
</filter>
|
|
48
|
+
</defs>
|
|
49
|
+
<g transform="translate(95 72)">
|
|
50
|
+
<path
|
|
51
|
+
d="M385 0 770 222v444L385 888 0 666V222z"
|
|
52
|
+
fill="url(#core)"
|
|
53
|
+
stroke="url(#edge)"
|
|
54
|
+
stroke-width="18"
|
|
55
|
+
stroke-linejoin="round"
|
|
56
|
+
/>
|
|
57
|
+
<path
|
|
58
|
+
d="M385 58 710 246v376L385 810 60 622V246z"
|
|
59
|
+
fill="none"
|
|
60
|
+
stroke="#67e8f9"
|
|
61
|
+
stroke-opacity=".22"
|
|
62
|
+
stroke-width="6"
|
|
63
|
+
/>
|
|
64
|
+
<path
|
|
65
|
+
d="M385 118 654 273v318L385 746 116 591V273z"
|
|
66
|
+
fill="none"
|
|
67
|
+
stroke="#a78bfa"
|
|
68
|
+
stroke-opacity=".16"
|
|
69
|
+
stroke-width="4"
|
|
70
|
+
/>
|
|
71
|
+
<path
|
|
72
|
+
d="M192 660V240l386 420V240"
|
|
73
|
+
fill="none"
|
|
74
|
+
stroke="url(#edge)"
|
|
75
|
+
stroke-linecap="round"
|
|
76
|
+
stroke-linejoin="round"
|
|
77
|
+
stroke-width="76"
|
|
78
|
+
filter="url(#glow)"
|
|
79
|
+
/>
|
|
80
|
+
<path
|
|
81
|
+
d="M192 660V240l386 420V240"
|
|
82
|
+
fill="none"
|
|
83
|
+
stroke="#071225"
|
|
84
|
+
stroke-linecap="round"
|
|
85
|
+
stroke-linejoin="round"
|
|
86
|
+
stroke-width="38"
|
|
87
|
+
/>
|
|
88
|
+
<circle cx="192" cy="240" r="30" fill="#67e8f9" filter="url(#glow)" />
|
|
89
|
+
<circle cx="578" cy="660" r="30" fill="#f0abfc" filter="url(#glow)" />
|
|
90
|
+
<circle cx="192" cy="240" r="12" fill="#fff" />
|
|
91
|
+
<circle cx="578" cy="660" r="12" fill="#fff" />
|
|
92
|
+
</g>
|
|
93
|
+
<g transform="translate(980 250)">
|
|
94
|
+
<text
|
|
95
|
+
x="0"
|
|
96
|
+
y="270"
|
|
97
|
+
fill="url(#word)"
|
|
98
|
+
font-family="Arial, Helvetica, sans-serif"
|
|
99
|
+
font-size="230"
|
|
100
|
+
font-weight="800"
|
|
101
|
+
letter-spacing="10"
|
|
102
|
+
>
|
|
103
|
+
BhooAI
|
|
104
|
+
</text>
|
|
105
|
+
<text
|
|
106
|
+
x="16"
|
|
107
|
+
y="465"
|
|
108
|
+
fill="url(#edge)"
|
|
109
|
+
font-family="Arial, Helvetica, sans-serif"
|
|
110
|
+
font-size="126"
|
|
111
|
+
font-weight="700"
|
|
112
|
+
letter-spacing="38"
|
|
113
|
+
>
|
|
114
|
+
NEXUS
|
|
115
|
+
</text>
|
|
116
|
+
<path
|
|
117
|
+
d="M18 550h840"
|
|
118
|
+
stroke="url(#edge)"
|
|
119
|
+
stroke-width="8"
|
|
120
|
+
stroke-linecap="round"
|
|
121
|
+
/>
|
|
122
|
+
<circle cx="890" cy="550" r="11" fill="#d8b4fe" />
|
|
123
|
+
<text
|
|
124
|
+
x="18"
|
|
125
|
+
y="620"
|
|
126
|
+
fill="#9ab0c9"
|
|
127
|
+
font-family="Arial, Helvetica, sans-serif"
|
|
128
|
+
font-size="27"
|
|
129
|
+
font-weight="500"
|
|
130
|
+
letter-spacing="8"
|
|
131
|
+
>
|
|
132
|
+
ONE RUNTIME. EVERY SIGNAL.
|
|
133
|
+
</text>
|
|
134
|
+
</g>
|
|
135
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { createRoot } from 'react-dom/client';
|
|
3
|
+
import { App } from '@bhooai/admin';
|
|
4
|
+
import '@bhooai/admin/style.css';
|
|
5
|
+
|
|
6
|
+
createRoot(document.getElementById('root')!).render(
|
|
7
|
+
<React.StrictMode>
|
|
8
|
+
<App />
|
|
9
|
+
</React.StrictMode>,
|
|
10
|
+
);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Ambient declarations for the admin host app. Self-contained: does not depend
|
|
2
|
+
// on `vite/client` types being resolvable from the host workspace, so `@bhooai/admin`
|
|
3
|
+
// imports (import.meta.env, *.svg) type-check consistently in every project.
|
|
4
|
+
interface ImportMetaEnv {
|
|
5
|
+
readonly VITE_SUPERVISOR_URL?: string;
|
|
6
|
+
readonly [key: string]: string | undefined;
|
|
7
|
+
}
|
|
8
|
+
interface ImportMeta {
|
|
9
|
+
readonly env: ImportMetaEnv;
|
|
10
|
+
}
|
|
11
|
+
declare module '*.svg' {
|
|
12
|
+
const src: string;
|
|
13
|
+
export default src;
|
|
14
|
+
}
|
|
15
|
+
declare module '*.png' {
|
|
16
|
+
const src: string;
|
|
17
|
+
export default src;
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "Bundler",
|
|
7
|
+
"jsx": "react-jsx",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"noEmit": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"allowImportingTsExtensions": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src"]
|
|
17
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import react from '@vitejs/plugin-react';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { dirname, join, resolve } from 'node:path';
|
|
5
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const PROJECT_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
8
|
+
|
|
9
|
+
// Read the merged host/port values from the project's single nexus config file
|
|
10
|
+
// (ts/js/mjs/cjs, discovery order matches the backend loader) plus NEXUS_*
|
|
11
|
+
// env overrides, so this Vite dev server and its proxy target stay in one
|
|
12
|
+
// source of truth: nexus.config.js.
|
|
13
|
+
async function loadConfig() {
|
|
14
|
+
const exts = ['ts', 'js', 'mjs', 'cjs'];
|
|
15
|
+
let user: Record<string, any> = {};
|
|
16
|
+
for (const ext of exts) {
|
|
17
|
+
const file = join(PROJECT_ROOT, `nexus.config.${ext}`);
|
|
18
|
+
if (existsSync(file)) {
|
|
19
|
+
const mod = (await import(pathToFileURL(file).href + `?v=${Date.now()}`)) as Record<string, any>;
|
|
20
|
+
user = mod.default ?? mod.config ?? {};
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const num = (v: string | undefined, fallback: number) => (v !== undefined && Number.isFinite(Number(v)) ? Number(v) : fallback);
|
|
25
|
+
const str = (v: string | undefined, fallback: string) => (v !== undefined && v !== '' ? v : fallback);
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
server: {
|
|
29
|
+
host: str(process.env.NEXUS_SERVER_HOST, user.server?.host ?? '0.0.0.0'),
|
|
30
|
+
port: num(process.env.NEXUS_SERVER_PORT, user.server?.port ?? 4000),
|
|
31
|
+
},
|
|
32
|
+
admin: {
|
|
33
|
+
host: str(process.env.NEXUS_ADMIN_HOST, user.admin?.host ?? 'localhost'),
|
|
34
|
+
port: num(process.env.NEXUS_ADMIN_PORT, user.admin?.port ?? 3300),
|
|
35
|
+
enabled: user.admin?.enabled ?? true,
|
|
36
|
+
},
|
|
37
|
+
frontend: {
|
|
38
|
+
host: str(process.env.NEXUS_FRONTEND_HOST, user.frontend?.host ?? 'localhost'),
|
|
39
|
+
port: num(process.env.NEXUS_FRONTEND_PORT, user.frontend?.port ?? 3000),
|
|
40
|
+
enabled: user.frontend?.enabled ?? true,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export default defineConfig(async () => {
|
|
46
|
+
const cfg = await loadConfig();
|
|
47
|
+
const backendHost = cfg.server.host === '0.0.0.0' || cfg.server.host === '::' ? '127.0.0.1' : cfg.server.host;
|
|
48
|
+
const target = `http://${backendHost}:${cfg.server.port}`;
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
plugins: [react()],
|
|
52
|
+
server: {
|
|
53
|
+
port: cfg.admin.port,
|
|
54
|
+
host: cfg.admin.host,
|
|
55
|
+
proxy: {
|
|
56
|
+
'/admin': { target, changeOrigin: true },
|
|
57
|
+
'/auth': { target, changeOrigin: true },
|
|
58
|
+
'/payments': { target, changeOrigin: true },
|
|
59
|
+
'/csrf-token': { target, changeOrigin: true },
|
|
60
|
+
'/ai': { target, changeOrigin: true },
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
preview: {
|
|
64
|
+
host: cfg.admin.host,
|
|
65
|
+
allowedHosts: ['bhooai.com', 'admin.bhooai.com', '.bhooai.com'],
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
});
|
package/bin/nexus.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* BhooAI Nexus CLI entry.
|
|
4
|
+
*
|
|
5
|
+
* Thin ESM shim: loads the compiled `@bhooai/nexus-cli` dist if present,
|
|
6
|
+
* otherwise runs the TypeScript source via tsx's programmatic API (which
|
|
7
|
+
* rewrites .js import specifiers to .ts). This keeps the framework usable
|
|
8
|
+
* with `node bin/nexus.js ...` and no build step.
|
|
9
|
+
*/
|
|
10
|
+
import { pathToFileURL } from 'node:url';
|
|
11
|
+
import { existsSync } from 'node:fs';
|
|
12
|
+
import { dirname, join } from 'node:path';
|
|
13
|
+
import { fileURLToPath } from 'node:url';
|
|
14
|
+
|
|
15
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
|
|
17
|
+
async function main() {
|
|
18
|
+
const distEntry = join(__dirname, '..', 'packages', 'nexus-cli', 'dist', 'index.js');
|
|
19
|
+
const srcEntry = join(__dirname, '..', 'packages', 'nexus-cli', 'src', 'index.ts');
|
|
20
|
+
const { tsImport } = await import('tsx/esm/api');
|
|
21
|
+
let mod;
|
|
22
|
+
if (existsSync(srcEntry)) {
|
|
23
|
+
// Prefer source in the monorepo and in the published package so the CLI
|
|
24
|
+
// does not depend on a stale or omitted build artifact.
|
|
25
|
+
mod = await tsImport(pathToFileURL(srcEntry).href, import.meta.url);
|
|
26
|
+
} else if (existsSync(distEntry)) {
|
|
27
|
+
// Workspace packages export TypeScript sources with `.js` specifiers.
|
|
28
|
+
// Keep tsx in the chain even when the CLI dist exists so Node can resolve
|
|
29
|
+
// those source imports during development and after partial builds.
|
|
30
|
+
mod = await tsImport(pathToFileURL(distEntry).href, import.meta.url);
|
|
31
|
+
} else {
|
|
32
|
+
mod = await tsImport(pathToFileURL(srcEntry).href, import.meta.url);
|
|
33
|
+
}
|
|
34
|
+
const cmd = process.argv[2] ?? 'help';
|
|
35
|
+
const rest = process.argv.slice(3);
|
|
36
|
+
await mod.run(cmd, rest);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** True when a rejected promise was the user pressing Ctrl+C during an
|
|
40
|
+
* interactive prompt (node:readline/promises rejects the open question with an
|
|
41
|
+
* AbortError). A cancelled wizard is not a failure — no error dump. */
|
|
42
|
+
function isUserCancel(err) {
|
|
43
|
+
if (!err) return false;
|
|
44
|
+
if (err.name === 'AbortError') return true;
|
|
45
|
+
return err instanceof Error && /aborted with ctrl\+c/i.test(err.message);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
main().catch((err) => {
|
|
49
|
+
if (isUserCancel(err)) process.exit(130);
|
|
50
|
+
console.error(err?.stack ?? err);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
});
|