@almadar/orb 16.9.0 → 17.0.0

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.
Files changed (98) hide show
  1. package/README.md +5 -0
  2. package/package.json +9 -6
  3. package/scripts/postinstall.js +38 -0
  4. package/shells/almadar-shell/LICENSE +72 -0
  5. package/shells/almadar-shell/README.md +25 -0
  6. package/shells/almadar-shell/locales/en.json +120 -0
  7. package/shells/almadar-shell/package.json +49 -0
  8. package/shells/almadar-shell/packages/client/eslint.config.cjs +56 -0
  9. package/shells/almadar-shell/packages/client/index.html +13 -0
  10. package/shells/almadar-shell/packages/client/package.json +63 -0
  11. package/shells/almadar-shell/packages/client/postcss.config.js +6 -0
  12. package/shells/almadar-shell/packages/client/src/App.tsx +102 -0
  13. package/shells/almadar-shell/packages/client/src/config/firebase.ts +58 -0
  14. package/shells/almadar-shell/packages/client/src/config/mockAuth.ts +257 -0
  15. package/shells/almadar-shell/packages/client/src/features/auth/AuthContext.tsx +152 -0
  16. package/shells/almadar-shell/packages/client/src/features/auth/authService.ts +104 -0
  17. package/shells/almadar-shell/packages/client/src/features/auth/components/Login.tsx +218 -0
  18. package/shells/almadar-shell/packages/client/src/features/auth/components/PersonaSwitcher.tsx +50 -0
  19. package/shells/almadar-shell/packages/client/src/features/auth/components/ProtectedRoute.tsx +36 -0
  20. package/shells/almadar-shell/packages/client/src/features/auth/components/UserProfile.tsx +68 -0
  21. package/shells/almadar-shell/packages/client/src/features/auth/components/index.ts +3 -0
  22. package/shells/almadar-shell/packages/client/src/features/auth/index.ts +14 -0
  23. package/shells/almadar-shell/packages/client/src/features/auth/types.ts +40 -0
  24. package/shells/almadar-shell/packages/client/src/index.css +19 -0
  25. package/shells/almadar-shell/packages/client/src/main.tsx +8 -0
  26. package/shells/almadar-shell/packages/client/src/navigation/index.ts +55 -0
  27. package/shells/almadar-shell/packages/client/src/pages/index.ts +12 -0
  28. package/shells/almadar-shell/packages/client/tailwind-preset.cjs +259 -0
  29. package/shells/almadar-shell/packages/client/tailwind.config.js +31 -0
  30. package/shells/almadar-shell/packages/client/tsconfig.json +33 -0
  31. package/shells/almadar-shell/packages/client/vite.config.ts +50 -0
  32. package/shells/almadar-shell/packages/server/eslint.config.cjs +23 -0
  33. package/shells/almadar-shell/packages/server/package.json +42 -0
  34. package/shells/almadar-shell/packages/server/pnpm-lock.yaml +4723 -0
  35. package/shells/almadar-shell/packages/server/src/app.ts +91 -0
  36. package/shells/almadar-shell/packages/server/src/hooks-providers.ts +11 -0
  37. package/shells/almadar-shell/packages/server/src/index.ts +69 -0
  38. package/shells/almadar-shell/packages/server/src/routes.ts +11 -0
  39. package/shells/almadar-shell/packages/server/src/services/clients.ts +17 -0
  40. package/shells/almadar-shell/packages/server/src/sse.ts +20 -0
  41. package/shells/almadar-shell/packages/server/src/types/express.d.ts +11 -0
  42. package/shells/almadar-shell/packages/server/tsconfig.json +22 -0
  43. package/shells/almadar-shell/packages/shared/package.json +11 -0
  44. package/shells/almadar-shell/packages/shared/pnpm-lock.yaml +22 -0
  45. package/shells/almadar-shell/packages/shared/src/index.ts +2 -0
  46. package/shells/almadar-shell/pnpm-lock.yaml +11699 -0
  47. package/shells/almadar-shell/pnpm-workspace.yaml +2 -0
  48. package/shells/almadar-shell/tsup.config.ts +13 -0
  49. package/shells/almadar-shell/turbo.json +17 -0
  50. package/shells/almadar-shell/vitest.config.ts +8 -0
  51. package/shells/almadar-shell-hono/LICENSE +72 -0
  52. package/shells/almadar-shell-hono/README.md +25 -0
  53. package/shells/almadar-shell-hono/locales/en.json +120 -0
  54. package/shells/almadar-shell-hono/package.json +37 -0
  55. package/shells/almadar-shell-hono/packages/client/eslint.config.cjs +23 -0
  56. package/shells/almadar-shell-hono/packages/client/index.html +13 -0
  57. package/shells/almadar-shell-hono/packages/client/package-lock.json +9750 -0
  58. package/shells/almadar-shell-hono/packages/client/package.json +61 -0
  59. package/shells/almadar-shell-hono/packages/client/postcss.config.js +6 -0
  60. package/shells/almadar-shell-hono/packages/client/src/App.tsx +80 -0
  61. package/shells/almadar-shell-hono/packages/client/src/config/firebase.ts +58 -0
  62. package/shells/almadar-shell-hono/packages/client/src/features/auth/AuthContext.tsx +144 -0
  63. package/shells/almadar-shell-hono/packages/client/src/features/auth/authService.ts +86 -0
  64. package/shells/almadar-shell-hono/packages/client/src/features/auth/components/Login.tsx +218 -0
  65. package/shells/almadar-shell-hono/packages/client/src/features/auth/components/ProtectedRoute.tsx +36 -0
  66. package/shells/almadar-shell-hono/packages/client/src/features/auth/components/UserProfile.tsx +68 -0
  67. package/shells/almadar-shell-hono/packages/client/src/features/auth/components/index.ts +3 -0
  68. package/shells/almadar-shell-hono/packages/client/src/features/auth/index.ts +13 -0
  69. package/shells/almadar-shell-hono/packages/client/src/features/auth/types.ts +24 -0
  70. package/shells/almadar-shell-hono/packages/client/src/index.css +35 -0
  71. package/shells/almadar-shell-hono/packages/client/src/main.tsx +8 -0
  72. package/shells/almadar-shell-hono/packages/client/src/navigation/index.ts +55 -0
  73. package/shells/almadar-shell-hono/packages/client/src/pages/index.ts +12 -0
  74. package/shells/almadar-shell-hono/packages/client/tailwind-preset.cjs +259 -0
  75. package/shells/almadar-shell-hono/packages/client/tailwind.config.js +24 -0
  76. package/shells/almadar-shell-hono/packages/client/tsconfig.json +33 -0
  77. package/shells/almadar-shell-hono/packages/client/vite.config.ts +50 -0
  78. package/shells/almadar-shell-hono/packages/server/eslint.config.cjs +19 -0
  79. package/shells/almadar-shell-hono/packages/server/package.json +38 -0
  80. package/shells/almadar-shell-hono/packages/server/pnpm-lock.yaml +4665 -0
  81. package/shells/almadar-shell-hono/packages/server/src/app.ts +70 -0
  82. package/shells/almadar-shell-hono/packages/server/src/hooks-providers.ts +11 -0
  83. package/shells/almadar-shell-hono/packages/server/src/index.ts +70 -0
  84. package/shells/almadar-shell-hono/packages/server/src/routes.ts +12 -0
  85. package/shells/almadar-shell-hono/packages/server/src/serve.ts +47 -0
  86. package/shells/almadar-shell-hono/packages/server/src/services/clients.ts +17 -0
  87. package/shells/almadar-shell-hono/packages/server/src/sse.ts +20 -0
  88. package/shells/almadar-shell-hono/packages/server/tsconfig.json +22 -0
  89. package/shells/almadar-shell-hono/packages/shared/package.json +25 -0
  90. package/shells/almadar-shell-hono/packages/shared/pnpm-lock.yaml +919 -0
  91. package/shells/almadar-shell-hono/packages/shared/src/index.ts +2 -0
  92. package/shells/almadar-shell-hono/packages/shared/tsconfig.json +17 -0
  93. package/shells/almadar-shell-hono/packages/shared/tsup.config.ts +10 -0
  94. package/shells/almadar-shell-hono/pnpm-lock.yaml +12573 -0
  95. package/shells/almadar-shell-hono/pnpm-workspace.yaml +2 -0
  96. package/shells/almadar-shell-hono/tsup.config.ts +13 -0
  97. package/shells/almadar-shell-hono/turbo.json +17 -0
  98. package/shells/almadar-shell-hono/vitest.config.ts +8 -0
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Hono Application Setup
3
+ */
4
+
5
+ import { Hono } from 'hono';
6
+ import { cors } from 'hono/cors';
7
+ import {
8
+ errorHandler,
9
+ notFoundHandler,
10
+ debugEventsRouter,
11
+ pushRouter,
12
+ pushServiceWorkerHandler,
13
+ PUSH_SERVICE_WORKER_PATH,
14
+ reportsRouter,
15
+ createHooksRouter,
16
+ type AppEnv,
17
+ } from '@almadar/server-hono';
18
+ import { hookProviders } from './hooks-providers.js';
19
+ import { broadcastBusEvent } from './sse.js';
20
+ import { registerRoutes } from './routes.js';
21
+
22
+ export const app = new Hono<AppEnv>();
23
+
24
+ // Middleware
25
+ app.use('*', cors({ origin: (origin) => origin, credentials: true }));
26
+
27
+ // Health check
28
+ app.get('/health', (c) => c.json({ status: 'ok' }));
29
+
30
+ // Debug event bus endpoints (dev-only, no-op in production)
31
+ app.route('/api/debug', debugEventsRouter());
32
+
33
+ // Web Push surface (browser/push-subscribe): public VAPID key + the shared
34
+ // service worker (root-scoped — a SW's max scope is its own directory).
35
+ app.route('/api/push', pushRouter);
36
+ app.get(PUSH_SERVICE_WORKER_PATH, pushServiceWorkerHandler);
37
+
38
+ // Inbound webhook ingress (I-19 decision): mounted BEFORE the authenticated
39
+ // /api routes — hook senders (Google Calendar watch channels, e-sign status,
40
+ // banking callbacks) cannot present a Firebase token, so each provider
41
+ // VERIFIES its own signature/channel token and unverified requests get 400.
42
+ // Dispatch = SSE bus broadcast to every connected client, so client circuits'
43
+ // `listens` fire; the cron pull cycle stays the no-client backstop.
44
+ app.route(
45
+ '/api/hooks',
46
+ createHooksRouter({
47
+ // Derived from this app's invoked services (generated hooks-providers.ts, I-26).
48
+ providers: hookProviders(),
49
+ dispatch: (event, payload) => {
50
+ broadcastBusEvent(undefined, {
51
+ type: 'bus',
52
+ event,
53
+ payload,
54
+ source: { orbital: 'webhook', trait: 'ingress' },
55
+ timestamp: Date.now(),
56
+ });
57
+ },
58
+ }),
59
+ );
60
+
61
+ // Register generated routes
62
+ registerRoutes(app);
63
+
64
+ // Server-side report export (Excel/PDF/CSV). Mounted AFTER registerRoutes so
65
+ // the /api/* auth middleware it registers covers this route too.
66
+ app.route('/api/reports', reportsRouter);
67
+
68
+ // Error handling
69
+ app.notFound(notFoundHandler);
70
+ app.onError(errorHandler);
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Hook Providers
3
+ *
4
+ * Checked-in stub so the template builds standalone in CI; the compiler
5
+ * overwrites it with the provider map derived from the app's invoked
6
+ * services × the registry's hook declarations (I-26).
7
+ */
8
+
9
+ export function hookProviders() {
10
+ return {};
11
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Server Entry Point
3
+ */
4
+
5
+ import { initializeFirebase, env, logger } from '@almadar/server-hono';
6
+
7
+ // Initialize Firebase before anything else uses it. When no credentials
8
+ // are configured (local dev without FIREBASE_*/FIRESTORE_EMULATOR_HOST),
9
+ // boot anyway — a purely client-side app must still serve.
10
+ try {
11
+ initializeFirebase();
12
+ } catch (e) {
13
+ const message = e instanceof Error ? e.message : String(e);
14
+ // In production the real data source IS Firebase (env.ts refuses to boot with
15
+ // USE_MOCK_DATA=true there), so swallowing this leaves a server that starts
16
+ // cleanly and then throws on the first request. Fail at boot instead.
17
+ if (env.NODE_ENV === 'production') {
18
+ logger.error(`Firebase is required when NODE_ENV=production — refusing to start: ${message}`);
19
+ throw e;
20
+ }
21
+ logger.warn(`Firebase not configured — auth/db routes disabled: ${message}`);
22
+ }
23
+
24
+ import { serve } from '@hono/node-server';
25
+ import { validateIntegrationEnv, FirestoreCredentialPersistence } from '@almadar/server-hono';
26
+ import { app } from './app.js';
27
+ import { invokedServices, installTenantCredentialStore } from './services/clients.js';
28
+
29
+ // Fail fast in production when a required integration credential is missing
30
+ // (see SECRETS.md); registers the invoked services for /health reporting.
31
+ validateIntegrationEnv(invokedServices);
32
+
33
+ const PORT = env.PORT || 3030;
34
+
35
+ async function start(): Promise<void> {
36
+ // W4 tenant credential store: with a master key configured, stored
37
+ // credentials (Firestore rows, AES-256-GCM) layer over the env —
38
+ // store → env → unconfigured — and go live on change without restart.
39
+ if (process.env.ALMADAR_CREDENTIAL_MASTER_KEY) {
40
+ try {
41
+ await installTenantCredentialStore(new FirestoreCredentialPersistence());
42
+ logger.info('Tenant credential store installed');
43
+ } catch (e) {
44
+ const message = e instanceof Error ? e.message : String(e);
45
+ // A configured master key IS the deployment's statement that the store
46
+ // is in use — failing to serve it in production is a boot failure.
47
+ if (env.NODE_ENV === 'production') {
48
+ logger.error(`Tenant credential store failed to initialize — refusing to start: ${message}`);
49
+ throw e;
50
+ }
51
+ logger.warn(`Tenant credential store unavailable — falling back to env credentials: ${message}`);
52
+ }
53
+ }
54
+
55
+ // Seed mock data when USE_MOCK_DATA is enabled
56
+ if (env.USE_MOCK_DATA) {
57
+ try {
58
+ const { initializeMockData } = await import(/* @vite-ignore */ './seedMockData.js' as string);
59
+ await initializeMockData();
60
+ } catch {
61
+ logger.warn('seedMockData.ts not found - skipping mock data seeding');
62
+ }
63
+ }
64
+
65
+ serve({ fetch: app.fetch, port: PORT }, () => {
66
+ logger.info(`Server running on port ${PORT}`);
67
+ });
68
+ }
69
+
70
+ start();
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Route Registration
3
+ *
4
+ * Compiler generates route registration code here.
5
+ */
6
+
7
+ import type { Hono } from 'hono';
8
+ import type { AppEnv } from '@almadar/server-hono';
9
+
10
+ export function registerRoutes(_app: Hono<AppEnv>): void {
11
+ // {{GENERATED_ROUTE_REGISTRATION}}
12
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Bun-native server entry point for `orb serve`
3
+ *
4
+ * Serves both the Hono API and the built client static files.
5
+ * No @hono/node-server needed: Bun serves Hono natively.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+
10
+ import { env, logger } from '@almadar/server-hono';
11
+ import { app } from './app.js';
12
+ import { serveStatic } from 'hono/bun';
13
+ import { join } from 'path';
14
+
15
+ const PORT = Number(env.PORT) || 3030;
16
+ const clientDist = join(import.meta.dir, '../../client/dist');
17
+
18
+ // Seed mock data. Gated on USE_MOCK_DATA alone, matching the three other server
19
+ // entry points — "not production" is a different question from "is the data
20
+ // source mock", and conflating them seeds a store nothing reads.
21
+ if (env.USE_MOCK_DATA) {
22
+ try {
23
+ const { initializeMockData } = await import(/* @vite-ignore */ './seedMockData.js' as string);
24
+ await initializeMockData();
25
+ } catch {
26
+ logger.warn('seedMockData.ts not found - skipping mock data seeding');
27
+ }
28
+ }
29
+
30
+ // Serve built client static files
31
+ app.use('/*', serveStatic({ root: clientDist }));
32
+
33
+ // SPA fallback: serve index.html for client-side routes
34
+ app.get('*', async (c) => {
35
+ const file = Bun.file(join(clientDist, 'index.html'));
36
+ if (await file.exists()) {
37
+ return c.html(await file.text());
38
+ }
39
+ return c.json({ error: 'Client not built' }, 404);
40
+ });
41
+
42
+ logger.info(`Server running on http://localhost:${PORT}`);
43
+
44
+ export default {
45
+ fetch: app.fetch,
46
+ port: PORT,
47
+ };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Service Clients — placeholder
3
+ *
4
+ * Compiler generates the real service clients here (delegating to
5
+ * @almadar/integrations; see orbital-shell-typescript codegen/service.rs).
6
+ * This stub only lets the template build standalone; an emitted app
7
+ * overwrites it wholesale.
8
+ */
9
+
10
+ export const declaredServices = [] as const;
11
+
12
+ export const invokedServices = [] as const;
13
+
14
+ /** Overwritten at emit time with the RuntimeIntegrationManager-backed store install. */
15
+ export async function installTenantCredentialStore(_adapter: object): Promise<void> {
16
+ // {{GENERATED_SERVICE_CLIENTS}}
17
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Live-push SSE channel — placeholder
3
+ *
4
+ * Compiler generates the real SSE module here (connection registry +
5
+ * cross-client broadcast; see orbital-shell-typescript backend/server/sse.rs).
6
+ * This stub only lets the template build standalone; an emitted app
7
+ * overwrites it wholesale.
8
+ */
9
+
10
+ export interface BusBroadcastItem {
11
+ type: 'bus';
12
+ event: string;
13
+ payload?: object;
14
+ source: { orbital: string; trait: string };
15
+ timestamp: number;
16
+ }
17
+
18
+ export function broadcastBusEvent(_originClientId: string | undefined, _item: BusBroadcastItem): void {
19
+ // {{GENERATED_SSE_BROADCAST}}
20
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "outDir": "./dist",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "declaration": true,
12
+ "declarationMap": true,
13
+ "baseUrl": ".",
14
+ "paths": {
15
+ "@/*": ["./src/*"],
16
+ "@app/shared": ["../shared/src/index.ts"],
17
+ "@app/shared/*": ["../shared/src/*"]
18
+ }
19
+ },
20
+ "include": ["src"],
21
+ "exclude": ["node_modules", "dist", "src/**/__tests__/**", "src/**/*.test.ts", "src/**/*.spec.ts"]
22
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@almadar/shell-hono-shared",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "tsup",
16
+ "dev": "tsup --watch"
17
+ },
18
+ "dependencies": {
19
+ "zod": "^3.22.0"
20
+ },
21
+ "devDependencies": {
22
+ "tsup": "^8.0.0",
23
+ "typescript": "^5.7.0"
24
+ }
25
+ }