@almadar/shell 2.16.1 → 2.16.3

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 (67) hide show
  1. package/.env.example +17 -0
  2. package/.gitignore +31 -0
  3. package/locales/en.json +120 -0
  4. package/package.json +8 -2
  5. package/packages/client/dist/assets/index-B-wG_C4q.js +4157 -0
  6. package/packages/client/dist/assets/index-B-wG_C4q.js.map +1 -0
  7. package/packages/client/dist/assets/index-Ce2d2Q6W.js +7842 -0
  8. package/packages/client/dist/assets/index-Ce2d2Q6W.js.map +1 -0
  9. package/packages/client/dist/assets/index-DlMuyBNE.css +1 -0
  10. package/packages/client/dist/assets/index-x4KY6jHP.js +2 -0
  11. package/packages/client/dist/assets/index-x4KY6jHP.js.map +1 -0
  12. package/packages/client/dist/assets/leaflet-Dgihpmma.css +1 -0
  13. package/packages/client/dist/assets/leaflet-src-C9rI6ulw.js +5 -0
  14. package/packages/client/dist/assets/leaflet-src-C9rI6ulw.js.map +1 -0
  15. package/packages/client/dist/index.html +14 -0
  16. package/packages/client/eslint.config.cjs +56 -0
  17. package/packages/client/index.html +13 -0
  18. package/packages/client/node_modules/.bin/autoprefixer +21 -0
  19. package/packages/client/node_modules/.bin/eslint +21 -0
  20. package/packages/client/node_modules/.bin/tailwind +21 -0
  21. package/packages/client/node_modules/.bin/tailwindcss +21 -0
  22. package/packages/client/node_modules/.bin/tsc +21 -0
  23. package/packages/client/node_modules/.bin/tsserver +21 -0
  24. package/packages/client/node_modules/.bin/vite +21 -0
  25. package/packages/client/node_modules/.bin/vitest +21 -0
  26. package/packages/client/package.json +63 -0
  27. package/packages/client/postcss.config.js +6 -0
  28. package/packages/client/src/App.tsx +81 -0
  29. package/packages/client/src/config/firebase.ts +37 -0
  30. package/packages/client/src/features/auth/AuthContext.tsx +139 -0
  31. package/packages/client/src/features/auth/authService.ts +83 -0
  32. package/packages/client/src/features/auth/components/Login.tsx +218 -0
  33. package/packages/client/src/features/auth/components/ProtectedRoute.tsx +27 -0
  34. package/packages/client/src/features/auth/components/UserProfile.tsx +68 -0
  35. package/packages/client/src/features/auth/components/index.ts +3 -0
  36. package/packages/client/src/features/auth/index.ts +13 -0
  37. package/packages/client/src/features/auth/types.ts +24 -0
  38. package/packages/client/src/generated/index.ts +13 -0
  39. package/packages/client/src/index.css +19 -0
  40. package/packages/client/src/main.tsx +8 -0
  41. package/packages/client/src/navigation/index.ts +55 -0
  42. package/packages/client/src/pages/index.ts +12 -0
  43. package/packages/client/tailwind-preset.cjs +259 -0
  44. package/packages/client/tailwind.config.js +31 -0
  45. package/packages/client/tsconfig.json +33 -0
  46. package/packages/client/vite.config.ts +50 -0
  47. package/packages/server/dist/index.js +54 -0
  48. package/packages/server/eslint.config.cjs +23 -0
  49. package/packages/server/node_modules/.bin/esbuild +21 -0
  50. package/packages/server/node_modules/.bin/eslint +21 -0
  51. package/packages/server/node_modules/.bin/tsc +21 -0
  52. package/packages/server/node_modules/.bin/tsserver +21 -0
  53. package/packages/server/node_modules/.bin/tsx +21 -0
  54. package/packages/server/node_modules/.bin/vitest +21 -0
  55. package/packages/server/package.json +42 -0
  56. package/packages/server/pnpm-lock.yaml +4723 -0
  57. package/packages/server/src/app.ts +41 -0
  58. package/packages/server/src/index.ts +30 -0
  59. package/packages/server/src/routes.ts +11 -0
  60. package/packages/server/src/types/express.d.ts +17 -0
  61. package/packages/server/tsconfig.json +23 -0
  62. package/packages/shared/package.json +11 -0
  63. package/packages/shared/pnpm-lock.yaml +22 -0
  64. package/packages/shared/src/index.ts +2 -0
  65. package/pnpm-lock.yaml +8937 -0
  66. package/pnpm-workspace.yaml +2 -0
  67. package/turbo.json +17 -0
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Almadar App</title>
8
+ <script type="module" crossorigin src="/assets/index-Ce2d2Q6W.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-DlMuyBNE.css">
10
+ </head>
11
+ <body>
12
+ <div id="root"></div>
13
+ </body>
14
+ </html>
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ const tsParser = require("@typescript-eslint/parser");
3
+ const almadarPlugin = require("@almadar/eslint-plugin");
4
+ // react-hooks plugin registered so the codegen-emitted
5
+ // `// eslint-disable-next-line react-hooks/exhaustive-deps` comments are
6
+ // well-formed (eslint errors on disable directives that reference
7
+ // unknown rules). The actual rules are left off — enabling them would
8
+ // surface a backlog of dep-array warnings the codegen knows are
9
+ // intentional. Tightening is a separate codegen-fix pass.
10
+ let reactHooksPlugin;
11
+ try {
12
+ reactHooksPlugin = require("eslint-plugin-react-hooks");
13
+ } catch (_) {
14
+ reactHooksPlugin = { rules: { "exhaustive-deps": { meta: {}, create: () => ({}) }, "rules-of-hooks": { meta: {}, create: () => ({}) } } };
15
+ }
16
+
17
+ module.exports = [
18
+ { ignores: ["dist/**", "node_modules/**", "**/*.test.ts", "**/*.test.tsx"] },
19
+ {
20
+ files: ["src/**/*.ts", "src/**/*.tsx"],
21
+ // The codegen emits `// eslint-disable-next-line react-hooks/exhaustive-deps`
22
+ // ahead of every mount-only effect's `[]` dep array. Until the real
23
+ // `eslint-plugin-react-hooks` is wired (it would fire the rule and
24
+ // make these directives meaningful), the shim's no-op create() means
25
+ // the rule never reports — so ESLint flags the directives as
26
+ // "Unused eslint-disable directive". That's a false alarm at this
27
+ // stage; suppress it so the strict-error rule set still hard-fails.
28
+ linterOptions: { reportUnusedDisableDirectives: "off" },
29
+ languageOptions: {
30
+ parser: tsParser,
31
+ parserOptions: {
32
+ ecmaFeatures: { jsx: true },
33
+ ecmaVersion: "latest",
34
+ sourceType: "module",
35
+ },
36
+ },
37
+ plugins: { almadar: almadarPlugin, "react-hooks": reactHooksPlugin },
38
+ rules: {
39
+ // Zero escape hatches in emitted shell code. Each rule pairs with a
40
+ // codegen-template fix in orbital-rust (see docs/Almadar_Compiler_Gaps.md):
41
+ // - no-as-any: catches `as any` casts.
42
+ // - no-unknown-type: catches `: unknown` annotations.
43
+ // Service results are typed via the integrations
44
+ // contract; every other "unknown" is a typed
45
+ // shape the codegen knows.
46
+ // - no-record-string-unknown: catches `as Record<string, unknown>` casts
47
+ // the codegen used to index into entity rows by
48
+ // string key. The entity has a typed interface
49
+ // — emit against that.
50
+ "almadar/no-as-any": "error",
51
+ "almadar/no-unknown-type": "error",
52
+ "almadar/no-record-string-unknown": "error",
53
+ "almadar/no-import-generated": "error",
54
+ },
55
+ },
56
+ ];
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Almadar App</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/src/main.tsx"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/autoprefixer@10.4.27_postcss@8.5.8/node_modules/autoprefixer/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/autoprefixer@10.4.27_postcss@8.5.8/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/autoprefixer@10.4.27_postcss@8.5.8/node_modules/autoprefixer/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/autoprefixer@10.4.27_postcss@8.5.8/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../autoprefixer/bin/autoprefixer" "$@"
19
+ else
20
+ exec node "$basedir/../autoprefixer/bin/autoprefixer" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/eslint@10.0.0_jiti@1.21.7/node_modules/eslint/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/eslint@10.0.0_jiti@1.21.7/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/eslint@10.0.0_jiti@1.21.7/node_modules/eslint/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/eslint@10.0.0_jiti@1.21.7/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../eslint/bin/eslint.js" "$@"
19
+ else
20
+ exec node "$basedir/../eslint/bin/eslint.js" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/tailwindcss@3.4.19_tsx@4.21.0/node_modules/tailwindcss/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/tailwindcss@3.4.19_tsx@4.21.0/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/tailwindcss@3.4.19_tsx@4.21.0/node_modules/tailwindcss/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/tailwindcss@3.4.19_tsx@4.21.0/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../tailwindcss/lib/cli.js" "$@"
19
+ else
20
+ exec node "$basedir/../tailwindcss/lib/cli.js" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/tailwindcss@3.4.19_tsx@4.21.0/node_modules/tailwindcss/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/tailwindcss@3.4.19_tsx@4.21.0/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/tailwindcss@3.4.19_tsx@4.21.0/node_modules/tailwindcss/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/tailwindcss@3.4.19_tsx@4.21.0/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../tailwindcss/lib/cli.js" "$@"
19
+ else
20
+ exec node "$basedir/../tailwindcss/lib/cli.js" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
19
+ else
20
+ exec node "$basedir/../typescript/bin/tsc" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@"
19
+ else
20
+ exec node "$basedir/../typescript/bin/tsserver" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/vite@6.4.1_@types+node@22.19.15_jiti@1.21.7_tsx@4.21.0/node_modules/vite/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/vite@6.4.1_@types+node@22.19.15_jiti@1.21.7_tsx@4.21.0/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/vite@6.4.1_@types+node@22.19.15_jiti@1.21.7_tsx@4.21.0/node_modules/vite/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/vite@6.4.1_@types+node@22.19.15_jiti@1.21.7_tsx@4.21.0/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../vite/bin/vite.js" "$@"
19
+ else
20
+ exec node "$basedir/../vite/bin/vite.js" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/vitest@2.1.9_@types+node@22.19.15_jsdom@25.0.1/node_modules/vitest/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/vitest@2.1.9_@types+node@22.19.15_jsdom@25.0.1/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/vitest@2.1.9_@types+node@22.19.15_jsdom@25.0.1/node_modules/vitest/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/vitest@2.1.9_@types+node@22.19.15_jsdom@25.0.1/node_modules:/home/runner/work/almadar-shell/almadar-shell/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../vitest/vitest.mjs" "$@"
19
+ else
20
+ exec node "$basedir/../vitest/vitest.mjs" "$@"
21
+ fi
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@almadar/shell-client",
3
+ "version": "2.13.15",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "tsc && vite build",
9
+ "typecheck": "tsc --noEmit",
10
+ "lint": "eslint --max-warnings 0 src/",
11
+ "preview": "vite preview",
12
+ "test": "vitest run --passWithNoTests",
13
+ "test:watch": "vitest"
14
+ },
15
+ "dependencies": {
16
+ "@almadar/core": "^7.14.3",
17
+ "@almadar/evaluator": "^2.11.2",
18
+ "@almadar/logger": "^1.3.0",
19
+ "@almadar/patterns": "^2.30.2",
20
+ "@almadar/syntax": "^1.4.0",
21
+ "@almadar/ui": "^4.55.0",
22
+ "@monaco-editor/react": "^4.7.0",
23
+ "@react-three/drei": "^9.92.0",
24
+ "@react-three/fiber": "^9.0.0",
25
+ "@react-three/postprocessing": "^3.0.0",
26
+ "@tanstack/react-query": "^5.67.3",
27
+ "firebase": "^11.4.0",
28
+ "leaflet": "^1.9.4",
29
+ "lucide-react": "^0.344.0",
30
+ "monaco-editor": "^0.52.2",
31
+ "postprocessing": "^6.39.0",
32
+ "react": "^19.0.0",
33
+ "react-dom": "^19.0.0",
34
+ "react-force-graph-2d": "^1.25.5",
35
+ "react-leaflet": "^4.2.1",
36
+ "react-markdown": "^9.0.1",
37
+ "react-router-dom": "^7.3.0",
38
+ "rehype-katex": "^7.0.1",
39
+ "rehype-raw": "^7.0.0",
40
+ "remark-gfm": "^4.0.1",
41
+ "remark-math": "^6.0.0",
42
+ "three": "^0.160.0",
43
+ "zustand": "^5.0.3"
44
+ },
45
+ "devDependencies": {
46
+ "@almadar/eslint-plugin": "^2.8.1",
47
+ "@testing-library/jest-dom": "^6.6.3",
48
+ "@testing-library/react": "^16.1.0",
49
+ "@types/react": "^19.0.0",
50
+ "@types/react-dom": "^19.0.0",
51
+ "@typescript-eslint/parser": "8.56.0",
52
+ "@vitejs/plugin-react": "^4.3.4",
53
+ "autoprefixer": "^10.4.20",
54
+ "eslint": "10.0.0",
55
+ "jsdom": "^25.0.1",
56
+ "postcss": "^8.5.3",
57
+ "tailwindcss": "^3.4.17",
58
+ "@tailwindcss/container-queries": "^0.1.1",
59
+ "typescript": "^5.7.3",
60
+ "vite": "^6.2.1",
61
+ "vitest": "^2.1.9"
62
+ }
63
+ }
@@ -0,0 +1,6 @@
1
+ export default {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * App Entry Point
3
+ *
4
+ * Main application component with compiler-generated content placeholders.
5
+ * The Rust compiler replaces {{PLACEHOLDERS}} with generated code.
6
+ *
7
+ * Navigation works via schema-driven NavigationProvider:
8
+ * - NavigationProvider holds active page state
9
+ * - navigateTo() switches pages and fires INIT with payload
10
+ * - No dependency on react-router for internal navigation
11
+ * - react-router is optional for URL bookmarkability
12
+ */
13
+
14
+ import { BrowserRouter, Routes, Route } from 'react-router-dom';
15
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
16
+ import { ThemeProvider, UISlotProvider } from '@almadar/ui/context';
17
+ import { UISlotComponent, NotifyListener } from '@almadar/ui/components';
18
+ import {
19
+ EventBusProvider,
20
+ VerificationProvider,
21
+ } from '@almadar/ui/providers';
22
+ import { NavigationProvider } from '@almadar/ui/renderer';
23
+ import { I18nProvider, createTranslate } from '@almadar/ui/hooks';
24
+ import defaultLocale from '@almadar/ui/locales/en.json';
25
+
26
+ // {{GENERATED_I18N_IMPORT}}
27
+ // {{GENERATED_IMPORTS}}
28
+
29
+ // Generated schema import (compiler fills this in)
30
+ // {{GENERATED_SCHEMA_IMPORT}}
31
+ const schema = { name: 'app', orbitals: [] }; // Placeholder - replaced by compiler
32
+
33
+ // {{GENERATED_I18N_VALUE}}
34
+ const { $meta: defaultMeta, ...defaultMessages } = defaultLocale;
35
+ const i18nValue = { locale: defaultMeta?.locale ?? 'en', direction: (defaultMeta?.direction ?? 'ltr') as 'ltr' | 'rtl', t: createTranslate(defaultMessages) };
36
+
37
+ const queryClient = new QueryClient({
38
+ defaultOptions: {
39
+ queries: {
40
+ staleTime: 1000 * 60,
41
+ refetchOnWindowFocus: false,
42
+ },
43
+ },
44
+ });
45
+
46
+ function App() {
47
+ return (
48
+ <I18nProvider value={i18nValue}>
49
+ <QueryClientProvider client={queryClient}>
50
+ <ThemeProvider defaultTheme="minimalist">
51
+ <EventBusProvider>
52
+ <VerificationProvider>
53
+ <UISlotProvider>
54
+ <NavigationProvider
55
+ schema={schema}
56
+ updateUrl={true}
57
+ onNavigate={(pageName, path, payload) => {
58
+ console.log('[App] Navigation:', { pageName, path, payload });
59
+ }}
60
+ >
61
+ <BrowserRouter>
62
+ <Routes>
63
+ {/* {{GENERATED_ROUTES}} */}
64
+ <Route path="/" element={<div>Welcome to Almadar</div>} />
65
+ </Routes>
66
+ {/* Portal slots rendered by compiled trait views via CompiledPortal */}
67
+ {/* Toast notifications (non-overlapping, always safe to render here) */}
68
+ <UISlotComponent slot="toast" portal />
69
+ <NotifyListener />
70
+ </BrowserRouter>
71
+ </NavigationProvider>
72
+ </UISlotProvider>
73
+ </VerificationProvider>
74
+ </EventBusProvider>
75
+ </ThemeProvider>
76
+ </QueryClientProvider>
77
+ </I18nProvider>
78
+ );
79
+ }
80
+
81
+ export default App;
@@ -0,0 +1,37 @@
1
+ import { initializeApp, getApps, getApp, FirebaseApp } from 'firebase/app';
2
+ import { getAuth, Auth } from 'firebase/auth';
3
+
4
+ let app: FirebaseApp;
5
+ let auth: Auth;
6
+
7
+ export async function initializeFirebase(): Promise<void> {
8
+ if (getApps().length > 0) {
9
+ app = getApp();
10
+ auth = getAuth(app);
11
+ return;
12
+ }
13
+
14
+ let config;
15
+ try {
16
+ // On Firebase Hosting, fetch auto-config from reserved URL
17
+ const res = await fetch('/__/firebase/init.json');
18
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
19
+ config = await res.json();
20
+ } catch {
21
+ // Fall back to env vars for local development
22
+ config = {
23
+ apiKey: import.meta.env.VITE_APP_FIREBASE_API_KEY,
24
+ authDomain: import.meta.env.VITE_APP_FIREBASE_AUTH_DOMAIN,
25
+ projectId: import.meta.env.VITE_APP_FIREBASE_PROJECT_ID,
26
+ storageBucket: import.meta.env.VITE_APP_FIREBASE_STORAGE_BUCKET,
27
+ messagingSenderId: import.meta.env.VITE_APP_FIREBASE_MESSAGING_SENDER_ID,
28
+ appId: import.meta.env.VITE_APP_FIREBASE_APP_ID,
29
+ measurementId: import.meta.env.VITE_APP_FIREBASE_MEASUREMENT_ID,
30
+ };
31
+ }
32
+
33
+ app = initializeApp(config);
34
+ auth = getAuth(app);
35
+ }
36
+
37
+ export { auth, app };
@@ -0,0 +1,139 @@
1
+ import React, { createContext, useContext, useEffect, useState } from 'react';
2
+ import { User } from 'firebase/auth';
3
+ import { auth, initializeFirebase } from '../../config/firebase';
4
+ import { authService } from './authService';
5
+ import { AuthContextType } from './types';
6
+
7
+ const AuthContext = createContext<AuthContextType | undefined>(undefined);
8
+
9
+ export const useAuthContext = () => {
10
+ const context = useContext(AuthContext);
11
+ if (context === undefined) {
12
+ throw new Error('useAuthContext must be used within an AuthProvider');
13
+ }
14
+ return context;
15
+ };
16
+
17
+ interface AuthProviderProps {
18
+ children: React.ReactNode;
19
+ }
20
+
21
+ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
22
+ const [user, setUser] = useState<User | null>(null);
23
+ const [loading, setLoading] = useState(true);
24
+ const [error, setError] = useState<string | null>(null);
25
+
26
+ useEffect(() => {
27
+ let unsubscribe: (() => void) | undefined;
28
+
29
+ initializeFirebase().then(() => {
30
+ unsubscribe = auth.onAuthStateChanged((firebaseUser) => {
31
+ setUser(firebaseUser);
32
+ setLoading(false);
33
+ });
34
+ });
35
+
36
+ return () => unsubscribe?.();
37
+ }, []);
38
+
39
+ const clearError = () => setError(null);
40
+
41
+ const signInWithGoogle = async () => {
42
+ try {
43
+ setLoading(true);
44
+ clearError();
45
+ await authService.signInWithGoogle();
46
+ } catch (err: unknown) {
47
+ setLoading(false);
48
+ const firebaseErr = err as { code?: string; message?: string };
49
+ const isCancel =
50
+ firebaseErr.code === 'auth/popup-closed-by-user' ||
51
+ firebaseErr.code === 'auth/cancelled-popup-request' ||
52
+ firebaseErr.code === 'auth/popup-blocked';
53
+ if (!isCancel) {
54
+ setError(firebaseErr.message ?? 'Google sign-in failed');
55
+ }
56
+ }
57
+ };
58
+
59
+ const signInWithEmail = async (email: string, password: string) => {
60
+ try {
61
+ setLoading(true);
62
+ clearError();
63
+ await authService.signInWithEmail(email, password);
64
+ } catch (err: unknown) {
65
+ setLoading(false);
66
+ setError((err as { message?: string }).message ?? 'Sign-in failed');
67
+ }
68
+ };
69
+
70
+ const signUpWithEmail = async (email: string, password: string, displayName?: string) => {
71
+ try {
72
+ setLoading(true);
73
+ clearError();
74
+ await authService.signUpWithEmail(email, password, displayName);
75
+ } catch (err: unknown) {
76
+ setLoading(false);
77
+ setError((err as { message?: string }).message ?? 'Sign-up failed');
78
+ }
79
+ };
80
+
81
+ const sendSignInLinkToEmail = async (email: string) => {
82
+ try {
83
+ setLoading(true);
84
+ clearError();
85
+ const actionCodeSettings = {
86
+ url: `${window.location.origin}/login`,
87
+ handleCodeInApp: true,
88
+ };
89
+ await authService.sendSignInLinkToEmail(email, actionCodeSettings);
90
+ setLoading(false);
91
+ } catch (err: unknown) {
92
+ setLoading(false);
93
+ setError((err as { message?: string }).message ?? 'Failed to send sign-in link');
94
+ }
95
+ };
96
+
97
+ const signInWithEmailLink = async (email: string, emailLink: string) => {
98
+ try {
99
+ setLoading(true);
100
+ clearError();
101
+ await authService.signInWithEmailLink(email, emailLink);
102
+ } catch (err: unknown) {
103
+ setLoading(false);
104
+ setError((err as { message?: string }).message ?? 'Email link sign-in failed');
105
+ }
106
+ };
107
+
108
+ const isSignInWithEmailLink = (emailLink: string): boolean => {
109
+ return authService.isSignInWithEmailLink(emailLink);
110
+ };
111
+
112
+ const signOut = async () => {
113
+ try {
114
+ setLoading(true);
115
+ await authService.signOut();
116
+ setUser(null);
117
+ setLoading(false);
118
+ } catch (err: unknown) {
119
+ setLoading(false);
120
+ setError((err as { message?: string }).message ?? 'Sign-out failed');
121
+ }
122
+ };
123
+
124
+ const value: AuthContextType = {
125
+ user,
126
+ loading,
127
+ error,
128
+ signInWithGoogle,
129
+ signOut,
130
+ signInWithEmail,
131
+ signUpWithEmail,
132
+ sendSignInLinkToEmail,
133
+ signInWithEmailLink,
134
+ isSignInWithEmailLink,
135
+ clearError,
136
+ };
137
+
138
+ return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
139
+ };