@terreno/admin-spa 0.17.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.
- package/README.md +126 -0
- package/dist/+not-found.html +379 -0
- package/dist/[model]/[id].html +379 -0
- package/dist/[model]/create.html +379 -0
- package/dist/[model]/index.html +379 -0
- package/dist/_expo/.routes.json +3 -0
- package/dist/_expo/static/js/web/Network-82d6794c98dd57beba4b4d4194920615.js +3 -0
- package/dist/_expo/static/js/web/WebBrowser-2978d66bdcd697bd0674799d5632200e.js +3 -0
- package/dist/_expo/static/js/web/entry-3eef2fa53d8f313ffe3d67b2558bcd2e.js +2924 -0
- package/dist/_expo/static/js/web/html2canvas-48f60c6cd7f071d9da7afb4a3e3bb25f.js +19 -0
- package/dist/_expo/static/js/web/index-17a373993dbc1bc9652c56afe8f9e07f.js +3 -0
- package/dist/_expo/static/js/web/index-26cf19216324aff83301469227d92200.js +224 -0
- package/dist/_expo/static/js/web/purify-313c75802810ff4a40e9cb64a5fb15a2.js +3 -0
- package/dist/_sitemap.html +379 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/AntDesign.3f78af31cca60105799838a1a7a59fbd.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/Entypo.31b5ffea3daddc69dd01a1f3d6cf63c5.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/EvilIcons.140c53a7643ea949007aa9a282153849.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/Feather.ca4b48e04dc1ce10bfbddb262c8b835f.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/FontAwesome.b06871f281fee6b241d60582ae9369b9.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/FontAwesome5_Brands.3b89dd103490708d19a95adcae52210e.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/FontAwesome5_Regular.1f77739ca9ff2188b539c36f30ffa2be.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/FontAwesome5_Solid.605ed7926cf39a2ad5ec2d1f9d391d3d.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/FontAwesome6_Brands.56c8d80832e37783f12c05db7c8849e2.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/FontAwesome6_Regular.370dd5af19f8364907b6e2c41f45dbbf.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/FontAwesome6_Solid.adec7d6f310bc577f05e8fe06a5daccf.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/Fontisto.b49ae8ab2dbccb02c4d11caaacf09eab.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/Foundation.e20945d7c929279ef7a6f1db184a4470.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/Ionicons.b4eb097d35f44ed943676fd56f6bdc51.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/MaterialCommunityIcons.6e435534bd35da5fef04168860a9b8fa.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/MaterialIcons.4e85bc9ebe07e0340c9c4fc2f6c38908.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/Octicons.871378c6eab492a3e689a9385dc45a12.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/SimpleLineIcons.d2285965fe34b05465047401b8595dd0.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo+vector-icons@15.1.1+620f57bf72bd39b3/node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/Zocial.1681f34aaca71b8dfb70756bca331eb2.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/200ExtraLight/Nunito_200ExtraLight.e3195ab4d111cebd50de96951ef3bbb5.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/200ExtraLight_Italic/Nunito_200ExtraLight_Italic.0f44842abdc321a4e8ef5f2d6eba013d.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/300Light/Nunito_300Light.cc4216a006ff27ad663b12c8d74708ef.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/300Light_Italic/Nunito_300Light_Italic.48b8e1e1d609d04a229cb167ba18ea4d.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/400Regular/Nunito_400Regular.f04f0e9ff969fd52a75deade3a9761cd.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/400Regular_Italic/Nunito_400Regular_Italic.0967d8e924905d0a4a70f38830288891.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/500Medium/Nunito_500Medium.04058d9f3583d30ece037e060c5b9721.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/500Medium_Italic/Nunito_500Medium_Italic.cabcea7d7b9c755ec132e2fe3efe4138.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/600SemiBold/Nunito_600SemiBold.b1364260246b29fd9393a1a071f3af61.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/600SemiBold_Italic/Nunito_600SemiBold_Italic.d3964a4faac6f9f959c6495f7e8bb1cc.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/700Bold/Nunito_700Bold.c133c0b8cd169e7798d0cd239477cf32.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/700Bold_Italic/Nunito_700Bold_Italic.c9d7af177a1a205c866662164104d9f0.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/800ExtraBold/Nunito_800ExtraBold.2b1bb82750274fc2d1043bf3891cb531.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/800ExtraBold_Italic/Nunito_800ExtraBold_Italic.eb8fe8521b6a7c128572d90528b415d6.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/900Black/Nunito_900Black.3ffae19d12dc67269f5cdd8d7a0aaeaf.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+nunito@0.4.2/node_modules/@expo-google-fonts/nunito/900Black_Italic/Nunito_900Black_Italic.2c030d352cb022edf2f941cadc8367f7.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+titillium-web@0.4.1/node_modules/@expo-google-fonts/titillium-web/200ExtraLight/TitilliumWeb_200ExtraLight.6a9cdf9fdee47c63bc9c6c9ac284b32f.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+titillium-web@0.4.1/node_modules/@expo-google-fonts/titillium-web/200ExtraLight_Italic/TitilliumWeb_200ExtraLight_Italic.347c2449963064a73858ca1e0dd3a4da.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+titillium-web@0.4.1/node_modules/@expo-google-fonts/titillium-web/300Light/TitilliumWeb_300Light.71d53d9506f88f09a25f326f29de4201.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+titillium-web@0.4.1/node_modules/@expo-google-fonts/titillium-web/300Light_Italic/TitilliumWeb_300Light_Italic.f47afb7520f8f909a457ed2d0fc5997c.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+titillium-web@0.4.1/node_modules/@expo-google-fonts/titillium-web/400Regular/TitilliumWeb_400Regular.57e937e4eef39e324bd4f26745053687.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+titillium-web@0.4.1/node_modules/@expo-google-fonts/titillium-web/400Regular_Italic/TitilliumWeb_400Regular_Italic.b7e4f5f7e443acc7c6340e8ae40926de.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+titillium-web@0.4.1/node_modules/@expo-google-fonts/titillium-web/600SemiBold/TitilliumWeb_600SemiBold.c21564022e51245ca150237eeb23a2bb.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+titillium-web@0.4.1/node_modules/@expo-google-fonts/titillium-web/600SemiBold_Italic/TitilliumWeb_600SemiBold_Italic.20d8982e3d57983b66ae8dfcdcf48501.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+titillium-web@0.4.1/node_modules/@expo-google-fonts/titillium-web/700Bold/TitilliumWeb_700Bold.d49a8ee8f1baee082909ab2e7c4062d1.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+titillium-web@0.4.1/node_modules/@expo-google-fonts/titillium-web/700Bold_Italic/TitilliumWeb_700Bold_Italic.cffdbe92e1d7e1c0e730b89aabc4ee11.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@expo-google-fonts+titillium-web@0.4.1/node_modules/@expo-google-fonts/titillium-web/900Black/TitilliumWeb_900Black.8d8d73518f2f1d36654af1b92fbfba99.ttf +0 -0
- package/dist/assets/_node_modules/.bun/@react-navigation+elements@2.9.10+f6f8a251dd0a43c9/node_modules/@react-navigation/elements/lib/module/assets/back-icon-mask.0a328cd9c1afd0afe8e3b1ec5165b1b4.png +0 -0
- package/dist/assets/_node_modules/.bun/@react-navigation+elements@2.9.10+f6f8a251dd0a43c9/node_modules/@react-navigation/elements/lib/module/assets/back-icon.35ba0eaec5a4f5ed12ca16fabeae451d.png +0 -0
- package/dist/assets/_node_modules/.bun/@react-navigation+elements@2.9.10+f6f8a251dd0a43c9/node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55.png +0 -0
- package/dist/assets/_node_modules/.bun/@react-navigation+elements@2.9.10+f6f8a251dd0a43c9/node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@2x.png +0 -0
- package/dist/assets/_node_modules/.bun/@react-navigation+elements@2.9.10+f6f8a251dd0a43c9/node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@3x.png +0 -0
- package/dist/assets/_node_modules/.bun/@react-navigation+elements@2.9.10+f6f8a251dd0a43c9/node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@4x.png +0 -0
- package/dist/assets/_node_modules/.bun/@react-navigation+elements@2.9.10+f6f8a251dd0a43c9/node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7.png +0 -0
- package/dist/assets/_node_modules/.bun/@react-navigation+elements@2.9.10+f6f8a251dd0a43c9/node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@2x.png +0 -0
- package/dist/assets/_node_modules/.bun/@react-navigation+elements@2.9.10+f6f8a251dd0a43c9/node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@3x.png +0 -0
- package/dist/assets/_node_modules/.bun/@react-navigation+elements@2.9.10+f6f8a251dd0a43c9/node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@4x.png +0 -0
- package/dist/assets/_node_modules/.bun/@react-navigation+elements@2.9.10+f6f8a251dd0a43c9/node_modules/@react-navigation/elements/lib/module/assets/search-icon.286d67d3f74808a60a78d3ebf1a5fb57.png +0 -0
- package/dist/assets/_node_modules/.bun/expo-router@6.0.23+c40509659f96c1e0/node_modules/expo-router/assets/arrow_down.017bc6ba3fc25503e5eb5e53826d48a8.png +0 -0
- package/dist/assets/_node_modules/.bun/expo-router@6.0.23+c40509659f96c1e0/node_modules/expo-router/assets/error.d1ea1496f9057eb392d5bbf3732a61b7.png +0 -0
- package/dist/assets/_node_modules/.bun/expo-router@6.0.23+c40509659f96c1e0/node_modules/expo-router/assets/file.19eeb73b9593a38f8e9f418337fc7d10.png +0 -0
- package/dist/assets/_node_modules/.bun/expo-router@6.0.23+c40509659f96c1e0/node_modules/expo-router/assets/forward.d8b800c443b8972542883e0b9de2bdc6.png +0 -0
- package/dist/assets/_node_modules/.bun/expo-router@6.0.23+c40509659f96c1e0/node_modules/expo-router/assets/pkg.ab19f4cbc543357183a20571f68380a3.png +0 -0
- package/dist/assets/_node_modules/.bun/expo-router@6.0.23+c40509659f96c1e0/node_modules/expo-router/assets/sitemap.412dd9275b6b48ad28f5e3d81bb1f626.png +0 -0
- package/dist/assets/_node_modules/.bun/expo-router@6.0.23+c40509659f96c1e0/node_modules/expo-router/assets/unmatched.20e71bdf79e3a97bf55fd9e164041578.png +0 -0
- package/dist/assets/_node_modules/.bun/react-native-calendars@1.1314.0+395f71ae3c4cac51/node_modules/react-native-calendars/src/calendar/img/next.5cd69239c26b01e3a70a5b852b034f8e.png +0 -0
- package/dist/assets/_node_modules/.bun/react-native-calendars@1.1314.0+395f71ae3c4cac51/node_modules/react-native-calendars/src/calendar/img/previous.87e5b6811f7ec9c6b4991b334b565992.png +0 -0
- package/dist/assets/_node_modules/.bun/react-native-calendars@1.1314.0+395f71ae3c4cac51/node_modules/react-native-calendars/src/img/down.5d3a5c3005bed13682ef9f27207b2019.png +0 -0
- package/dist/assets/_node_modules/.bun/react-native-calendars@1.1314.0+395f71ae3c4cac51/node_modules/react-native-calendars/src/img/down.5d3a5c3005bed13682ef9f27207b2019@1.5x.png +0 -0
- package/dist/assets/_node_modules/.bun/react-native-calendars@1.1314.0+395f71ae3c4cac51/node_modules/react-native-calendars/src/img/down.5d3a5c3005bed13682ef9f27207b2019@2x.png +0 -0
- package/dist/assets/_node_modules/.bun/react-native-calendars@1.1314.0+395f71ae3c4cac51/node_modules/react-native-calendars/src/img/down.5d3a5c3005bed13682ef9f27207b2019@3x.png +0 -0
- package/dist/assets/_node_modules/.bun/react-native-calendars@1.1314.0+395f71ae3c4cac51/node_modules/react-native-calendars/src/img/down.5d3a5c3005bed13682ef9f27207b2019@4x.png +0 -0
- package/dist/assets/_node_modules/.bun/react-native-calendars@1.1314.0+395f71ae3c4cac51/node_modules/react-native-calendars/src/img/up.09f8dc4c9ffd6c59e9884027c5008080.png +0 -0
- package/dist/assets/_node_modules/.bun/react-native-calendars@1.1314.0+395f71ae3c4cac51/node_modules/react-native-calendars/src/img/up.09f8dc4c9ffd6c59e9884027c5008080@1.5x.png +0 -0
- package/dist/assets/_node_modules/.bun/react-native-calendars@1.1314.0+395f71ae3c4cac51/node_modules/react-native-calendars/src/img/up.09f8dc4c9ffd6c59e9884027c5008080@2x.png +0 -0
- package/dist/assets/_node_modules/.bun/react-native-calendars@1.1314.0+395f71ae3c4cac51/node_modules/react-native-calendars/src/img/up.09f8dc4c9ffd6c59e9884027c5008080@3x.png +0 -0
- package/dist/assets/_node_modules/.bun/react-native-calendars@1.1314.0+395f71ae3c4cac51/node_modules/react-native-calendars/src/img/up.09f8dc4c9ffd6c59e9884027c5008080@4x.png +0 -0
- package/dist/assets/_node_modules/.bun/react-native-google-places-autocomplete@2.6.4+395f71ae3c4cac51/node_modules/react-native-google-places-autocomplete/images/powered_by_google_on_white.06b47ae2ab5bae40bd3a93e05142cc28.png +0 -0
- package/dist/assets/_node_modules/.bun/react-native-google-places-autocomplete@2.6.4+395f71ae3c4cac51/node_modules/react-native-google-places-autocomplete/images/powered_by_google_on_white.06b47ae2ab5bae40bd3a93e05142cc28@2x.png +0 -0
- package/dist/assets/_node_modules/.bun/react-native-google-places-autocomplete@2.6.4+395f71ae3c4cac51/node_modules/react-native-google-places-autocomplete/images/powered_by_google_on_white.06b47ae2ab5bae40bd3a93e05142cc28@3x.png +0 -0
- package/dist/configuration.html +379 -0
- package/dist/forbidden.html +379 -0
- package/dist/index.html +379 -0
- package/dist/login.html +379 -0
- package/dist/scripts.html +379 -0
- package/dist/version-config.html +379 -0
- package/package.json +104 -0
- package/src/dist/appConfig.d.ts +28 -0
- package/src/dist/appConfig.js +19 -0
- package/src/dist/index.d.ts +2 -0
- package/src/dist/index.js +10 -0
- package/src/dist/serve.d.ts +45 -0
- package/src/dist/serve.js +109 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.AdminSpaServeApp = exports.injectBaseGlobal = exports.rewriteIndexHtml = void 0;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const api_1 = require("@terreno/api");
|
|
10
|
+
const express_1 = __importDefault(require("express"));
|
|
11
|
+
const appConfig_1 = require("./appConfig");
|
|
12
|
+
// Compiled (CommonJS) file lives at src/dist/serve.js; the pre-built bundle lives at
|
|
13
|
+
// admin-spa/dist. `__dirname` is the CommonJS module-directory global.
|
|
14
|
+
const DIST_DIR = node_path_1.default.resolve(__dirname, "../../dist");
|
|
15
|
+
const NO_STORE = "no-store";
|
|
16
|
+
/**
|
|
17
|
+
* Rewrite the absolute `/_expo/` and `/assets/` references emitted by Expo's static
|
|
18
|
+
* web export so a single pre-built bundle works when mounted at any `basePath`.
|
|
19
|
+
*/
|
|
20
|
+
const rewriteIndexHtml = (rawIndex, basePath) => {
|
|
21
|
+
return rawIndex
|
|
22
|
+
.replaceAll('href="/_expo/', `href="${basePath}/_expo/`)
|
|
23
|
+
.replaceAll('src="/_expo/', `src="${basePath}/_expo/`)
|
|
24
|
+
.replaceAll('href="/assets/', `href="${basePath}/assets/`)
|
|
25
|
+
.replaceAll('src="/assets/', `src="${basePath}/assets/`);
|
|
26
|
+
};
|
|
27
|
+
exports.rewriteIndexHtml = rewriteIndexHtml;
|
|
28
|
+
/**
|
|
29
|
+
* Inject `window.__ADMIN_SPA_BASE__` so the SPA can build absolute URLs (e.g.
|
|
30
|
+
* `${base}/app-config.json`) regardless of the current deep route. Inserted before
|
|
31
|
+
* `</head>` so it runs before the bundle.
|
|
32
|
+
*/
|
|
33
|
+
const injectBaseGlobal = (html, basePath) => {
|
|
34
|
+
const script = `<script>window.__ADMIN_SPA_BASE__=${JSON.stringify(basePath)};</script>`;
|
|
35
|
+
if (html.includes("</head>")) {
|
|
36
|
+
return html.replace("</head>", `${script}</head>`);
|
|
37
|
+
}
|
|
38
|
+
return script + html;
|
|
39
|
+
};
|
|
40
|
+
exports.injectBaseGlobal = injectBaseGlobal;
|
|
41
|
+
/**
|
|
42
|
+
* Opt-in Express plugin that serves a pre-built admin SPA (Expo Router static export)
|
|
43
|
+
* from the same Node process as a Terreno backend. Mounts at `/console` by default.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* new TerrenoApp({userModel: User})
|
|
48
|
+
* .register(new BetterAuthApp({config, userModel: User}))
|
|
49
|
+
* .register(new AdminApp({models: [...]}))
|
|
50
|
+
* .register(new AdminSpaServeApp({basePath: "/console", appConfig: {brandName: "Acme"}}))
|
|
51
|
+
* .start();
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
class AdminSpaServeApp {
|
|
55
|
+
opts;
|
|
56
|
+
constructor(opts = {}) {
|
|
57
|
+
this.opts = opts;
|
|
58
|
+
}
|
|
59
|
+
register(app) {
|
|
60
|
+
const basePath = this.opts.basePath ?? "/console";
|
|
61
|
+
const distDir = this.opts.distDir ?? DIST_DIR;
|
|
62
|
+
const appConfig = (0, appConfig_1.resolveAppConfig)(this.opts.appConfig);
|
|
63
|
+
// Dev proxy: forward SPA assets to `expo start --web`, but keep app-config on the plugin.
|
|
64
|
+
if (this.opts.devProxyTarget) {
|
|
65
|
+
// Register before the catch-all proxy so Express matches this route first.
|
|
66
|
+
app.get(`${basePath}/app-config.json`, (_req, res) => {
|
|
67
|
+
res.set("Cache-Control", NO_STORE).json(appConfig);
|
|
68
|
+
});
|
|
69
|
+
// Lazy require so production deploys without the dev dependency don't break.
|
|
70
|
+
// biome-ignore lint/suspicious/noExplicitAny: dynamic require of optional dev dependency
|
|
71
|
+
const { createProxyMiddleware } = require("http-proxy-middleware");
|
|
72
|
+
app.use(basePath, createProxyMiddleware({
|
|
73
|
+
changeOrigin: true,
|
|
74
|
+
pathRewrite: { [`^${basePath}`]: "" },
|
|
75
|
+
target: this.opts.devProxyTarget,
|
|
76
|
+
ws: true,
|
|
77
|
+
}));
|
|
78
|
+
api_1.logger.info(`Admin SPA dev-proxied to ${this.opts.devProxyTarget} at ${basePath}/`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// Read index.html once and rewrite absolute asset refs to the mounted basePath.
|
|
82
|
+
const indexHtmlPath = node_path_1.default.join(distDir, "index.html");
|
|
83
|
+
let indexHtml = "";
|
|
84
|
+
try {
|
|
85
|
+
indexHtml = (0, exports.injectBaseGlobal)((0, exports.rewriteIndexHtml)(node_fs_1.default.readFileSync(indexHtmlPath, "utf-8"), basePath), basePath);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
api_1.logger.warn(`Admin SPA: no pre-built bundle found at ${indexHtmlPath}. ` +
|
|
89
|
+
"Run `bun run --filter '@terreno/admin-spa' build:web` or set devProxyTarget.");
|
|
90
|
+
}
|
|
91
|
+
// 1. Hashed asset directories — long cache, immutable.
|
|
92
|
+
const staticOpts = { immutable: true, maxAge: "365d" };
|
|
93
|
+
app.use(`${basePath}/_expo`, express_1.default.static(node_path_1.default.join(distDir, "_expo"), staticOpts));
|
|
94
|
+
app.use(`${basePath}/assets`, express_1.default.static(node_path_1.default.join(distDir, "assets"), staticOpts));
|
|
95
|
+
// 2. Runtime config — never cached.
|
|
96
|
+
app.get(`${basePath}/app-config.json`, (_req, res) => {
|
|
97
|
+
res.set("Cache-Control", NO_STORE).json(appConfig);
|
|
98
|
+
});
|
|
99
|
+
// 3. SPA fallback. Two registrations: bare basePath (no trailing slash) AND splat,
|
|
100
|
+
// matching the `/*name` Express 5 convention used elsewhere in the repo.
|
|
101
|
+
const serveSpa = (_req, res) => {
|
|
102
|
+
res.set("Cache-Control", NO_STORE).type("html").send(indexHtml);
|
|
103
|
+
};
|
|
104
|
+
app.get(basePath, serveSpa);
|
|
105
|
+
app.get(`${basePath}/*splat`, serveSpa);
|
|
106
|
+
api_1.logger.info(`Admin SPA mounted at ${basePath}/`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.AdminSpaServeApp = AdminSpaServeApp;
|