@bardioc/create-bardioc-app 0.5.2 → 0.5.4
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 +8 -11
- package/package.json +1 -1
- package/templates/angular/.env.example +6 -4
- package/templates/angular/scripts/dev-auth-proxy.mjs +6 -7
- package/templates/angular/scripts/sync-runtime-env.mjs +2 -24
- package/templates/angular/src/app/app.component.ts +4 -31
- package/templates/angular/src/app/bardioc-bridge.ts +3 -3
- package/templates/angular/src/main.ts +9 -43
- package/templates/angular/src/vite-env.d.ts +1 -3
- package/templates/nextjs/.env.example +5 -6
- package/templates/nextjs/app/page.tsx +15 -75
- package/templates/nextjs/next.config.ts +22 -11
- package/templates/nextjs/package.json +2 -2
- package/templates/preact/.env.example +5 -9
- package/templates/preact/package.json +2 -2
- package/templates/preact/src/App.tsx +1 -1
- package/templates/preact/src/main.tsx +13 -29
- package/templates/preact/src/vite-env.d.ts +0 -2
- package/templates/solid/.env.example +5 -9
- package/templates/solid/package.json +2 -2
- package/templates/solid/src/App.tsx +1 -1
- package/templates/solid/src/main.tsx +17 -33
- package/templates/solid/src/vite-env.d.ts +0 -2
- package/templates/svelte/.env.example +8 -4
- package/templates/svelte/package.json +2 -2
- package/templates/svelte/src/App.svelte +1 -1
- package/templates/svelte/src/main.ts +9 -25
- package/templates/svelte/src/vite-env.d.ts +0 -2
- package/templates/vite/.env.example +5 -10
- package/templates/vite/CLAUDE.md +3 -3
- package/templates/vite/package.json +1 -1
- package/templates/vite/src/App.tsx +1 -2
- package/templates/vite/src/auth/onboarding.tsx +5 -7
- package/templates/vite/src/locales/de.json +2 -3
- package/templates/vite/src/locales/en.json +2 -3
- package/templates/vite/src/main.tsx +4 -17
- package/templates/vite/src/vite-env.d.ts +0 -2
- package/templates/vue/.env.example +8 -4
- package/templates/vue/package.json +2 -2
- package/templates/vue/src/App.vue +1 -1
- package/templates/vue/src/main.ts +8 -24
- package/templates/vue/src/vite-env.d.ts +0 -2
- package/templates/nextjs/app/proxy/route.ts +0 -85
package/README.md
CHANGED
|
@@ -28,10 +28,10 @@ npm exec --yes @bardioc/create-bardioc-app my-app -- --port 3005
|
|
|
28
28
|
create-bardioc-app my-app --port 3005
|
|
29
29
|
cd my-app
|
|
30
30
|
npm install
|
|
31
|
-
bardioc login
|
|
32
|
-
npm run dev
|
|
33
31
|
```
|
|
34
32
|
|
|
33
|
+
Copy `.env.example` to `.env` and fill in `VITE_APP_NAME`, `DEV_SECRET`, and `API_BASE_URL`. Then run `npm run dev`.
|
|
34
|
+
|
|
35
35
|
## Generated app
|
|
36
36
|
|
|
37
37
|
The generated app includes:
|
|
@@ -39,7 +39,7 @@ The generated app includes:
|
|
|
39
39
|
- React + Vite project structure (or your chosen `--template`)
|
|
40
40
|
- `@bardioc/app-sdk` dependency
|
|
41
41
|
- `AppSdkProvider` wiring
|
|
42
|
-
- optional
|
|
42
|
+
- optional standalone dev-auth wiring via `.env` (`DEV_SECRET` proxy)
|
|
43
43
|
- a compact SDK demo with notification and transport examples
|
|
44
44
|
- `public/app-manifest.json`
|
|
45
45
|
|
|
@@ -64,18 +64,15 @@ Heavier, environment-specific tooling is **off by default** — pass a flag to i
|
|
|
64
64
|
- **`--with-link`** — the **`link:source` / `unlink:source`** dev flow (`scripts/link-source.mjs` +
|
|
65
65
|
`pnpm-workspace.yaml` + `.npmrc`) for developing against an in-tree `@bardioc/*` source checkout.
|
|
66
66
|
|
|
67
|
-
## Standalone dev
|
|
67
|
+
## Standalone dev auth
|
|
68
68
|
|
|
69
|
-
Generated apps can
|
|
69
|
+
Generated apps can run standalone with the `DEV_SECRET` dev-auth proxy.
|
|
70
70
|
|
|
71
71
|
1. Copy `.env.example` to `.env`
|
|
72
|
-
2. Fill in `VITE_APP_NAME`, `
|
|
73
|
-
3. Run `
|
|
74
|
-
4. Set `VITE_ENABLE_DEV_AUTH=true`
|
|
75
|
-
|
|
76
|
-
Important: standalone login will not start unless `VITE_ENABLE_DEV_AUTH=true` is present in `.env`. Running `npm run dev` with only `VITE_APP_NAME` and `VITE_APP_ID` is not enough.
|
|
72
|
+
2. Fill in `VITE_APP_NAME`, `DEV_SECRET`, and `API_BASE_URL`
|
|
73
|
+
3. Run `npm run dev`
|
|
77
74
|
|
|
78
|
-
When
|
|
75
|
+
When running outside the host iframe, the Vite plugin proxies `/rest/*` to `API_BASE_URL` with the `X-Dev-Secret` header and `installDevBridge()` handles SDK messages.
|
|
79
76
|
|
|
80
77
|
For public testing, run `npm run dev:live` and use the emitted tunnel URL as the app's live URL in the host App Store configuration.
|
|
81
78
|
|
package/package.json
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
VITE_APP_NAME={{APP_NAME}}
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
|
|
3
|
+
# Dev auth proxy secret for local standalone development.
|
|
4
|
+
DEV_SECRET=
|
|
5
|
+
|
|
6
|
+
# Base URL of the Bardioc API the dev auth proxy should forward to.
|
|
7
|
+
API_BASE_URL=
|
|
@@ -12,15 +12,14 @@ const appPort = readAppPort();
|
|
|
12
12
|
const proxyPort = appPort + 100;
|
|
13
13
|
const env = loadEnv(projectRoot);
|
|
14
14
|
|
|
15
|
-
if (!env.
|
|
16
|
-
process.stderr.write('[bardioc-dev-auth-proxy] missing
|
|
15
|
+
if (!env.DEV_SECRET || !env.API_BASE_URL) {
|
|
16
|
+
process.stderr.write('[bardioc-dev-auth-proxy] missing DEV_SECRET or API_BASE_URL, proxy disabled\n');
|
|
17
17
|
await new Promise(() => {});
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
const handler = createDevAuthProxyHandler({
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
devSessionKey: env.DEV_SESSION_KEY,
|
|
21
|
+
apiBaseUrl: env.API_BASE_URL,
|
|
22
|
+
devSecret: env.DEV_SECRET,
|
|
24
23
|
allowOrigin: '*',
|
|
25
24
|
});
|
|
26
25
|
|
|
@@ -29,7 +28,7 @@ const server = createServer((req, res) => {
|
|
|
29
28
|
});
|
|
30
29
|
|
|
31
30
|
server.listen(proxyPort, '127.0.0.1', () => {
|
|
32
|
-
process.stdout.write(`[bardioc-dev-auth-proxy] listening on http://127.0.0.1:${proxyPort}/
|
|
31
|
+
process.stdout.write(`[bardioc-dev-auth-proxy] listening on http://127.0.0.1:${proxyPort}/rest\n`);
|
|
33
32
|
});
|
|
34
33
|
|
|
35
34
|
for (const signal of ['SIGINT', 'SIGTERM']) {
|
|
@@ -89,4 +88,4 @@ function parseEnv(source) {
|
|
|
89
88
|
}
|
|
90
89
|
|
|
91
90
|
return result;
|
|
92
|
-
}
|
|
91
|
+
}
|
|
@@ -7,41 +7,19 @@ import { fileURLToPath } from 'node:url';
|
|
|
7
7
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
const projectRoot = resolve(__dirname, '..');
|
|
9
9
|
const env = loadEnv(projectRoot);
|
|
10
|
-
const appPort = readAppPort();
|
|
11
|
-
const proxyPort = appPort + 100;
|
|
12
10
|
|
|
13
11
|
const runtimeEnv = {
|
|
14
12
|
VITE_APP_NAME: env.VITE_APP_NAME,
|
|
15
|
-
VITE_APP_ID: env.VITE_APP_ID,
|
|
16
|
-
VITE_ENABLE_DEV_AUTH: env.VITE_ENABLE_DEV_AUTH,
|
|
17
|
-
DEV_AUTH_HOST_URL: env.DEV_AUTH_HOST_URL,
|
|
18
|
-
DEV_SESSION_KEY: env.DEV_SESSION_KEY,
|
|
19
13
|
};
|
|
20
14
|
|
|
21
|
-
const injectedDevAuth =
|
|
22
|
-
env.DEV_AUTH_HOST_URL && env.DEV_SESSION_KEY
|
|
23
|
-
? {
|
|
24
|
-
hostUrl: env.DEV_AUTH_HOST_URL,
|
|
25
|
-
sessionKey: env.DEV_SESSION_KEY,
|
|
26
|
-
proxyUrl: `http://127.0.0.1:${proxyPort}/proxy`,
|
|
27
|
-
}
|
|
28
|
-
: null;
|
|
29
|
-
|
|
30
15
|
const outputPath = join(projectRoot, 'public', 'runtime-env.js');
|
|
31
16
|
mkdirSync(dirname(outputPath), { recursive: true });
|
|
32
17
|
writeFileSync(
|
|
33
18
|
outputPath,
|
|
34
|
-
`window.__BARDIOC_RUNTIME_ENV__ = ${JSON.stringify(runtimeEnv, null, 2)};\
|
|
19
|
+
`window.__BARDIOC_RUNTIME_ENV__ = ${JSON.stringify(runtimeEnv, null, 2)};\n`,
|
|
35
20
|
'utf8'
|
|
36
21
|
);
|
|
37
22
|
|
|
38
|
-
function readAppPort() {
|
|
39
|
-
const flagIndex = process.argv.indexOf('--app-port');
|
|
40
|
-
const raw = flagIndex >= 0 ? process.argv[flagIndex + 1] : undefined;
|
|
41
|
-
const parsed = Number.parseInt(raw ?? '{{PORT}}', 10);
|
|
42
|
-
return Number.isFinite(parsed) ? parsed : {{PORT}};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
23
|
function loadEnv(projectDir) {
|
|
46
24
|
const result = {};
|
|
47
25
|
|
|
@@ -86,4 +64,4 @@ function parseEnv(source) {
|
|
|
86
64
|
}
|
|
87
65
|
|
|
88
66
|
return result;
|
|
89
|
-
}
|
|
67
|
+
}
|
|
@@ -3,27 +3,6 @@ import { JsonPipe } from '@angular/common';
|
|
|
3
3
|
import { Component, inject, signal } from '@angular/core';
|
|
4
4
|
import { BARDIOC_BRIDGE } from './bardioc.token';
|
|
5
5
|
import type { HostBridge } from '@bardioc/app-sdk';
|
|
6
|
-
import { readRuntimeEnv } from '../runtime-env';
|
|
7
|
-
|
|
8
|
-
type InjectedDevAuthConfig = {
|
|
9
|
-
hostUrl?: string;
|
|
10
|
-
sessionKey?: string;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
function readInjectedDevAuthConfig(): InjectedDevAuthConfig | null {
|
|
14
|
-
const config = (globalThis as typeof globalThis & {
|
|
15
|
-
__BARDIOC_DEV_AUTH__?: InjectedDevAuthConfig;
|
|
16
|
-
}).__BARDIOC_DEV_AUTH__;
|
|
17
|
-
|
|
18
|
-
if (!config?.hostUrl || !config?.sessionKey) {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return {
|
|
23
|
-
hostUrl: config.hostUrl,
|
|
24
|
-
sessionKey: config.sessionKey,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
6
|
|
|
28
7
|
type ResultState =
|
|
29
8
|
| { status: 'idle' }
|
|
@@ -115,14 +94,8 @@ type ResultState =
|
|
|
115
94
|
})
|
|
116
95
|
export class AppComponent {
|
|
117
96
|
private bridge = inject(BARDIOC_BRIDGE, { optional: true }) as HostBridge | null;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
showSdkDemo =
|
|
121
|
-
isInsideIframe() ||
|
|
122
|
-
(readRuntimeEnv('VITE_ENABLE_DEV_AUTH') === 'true' &&
|
|
123
|
-
!!this.injectedDevAuth?.hostUrl &&
|
|
124
|
-
!!this.injectedDevAuth?.sessionKey &&
|
|
125
|
-
isDevStandalone());
|
|
97
|
+
|
|
98
|
+
showSdkDemo = isInsideIframe() || isDevStandalone();
|
|
126
99
|
result = signal<ResultState>({ status: 'idle' });
|
|
127
100
|
running = signal(false);
|
|
128
101
|
|
|
@@ -135,11 +108,11 @@ export class AppComponent {
|
|
|
135
108
|
|
|
136
109
|
const startTime = Date.now();
|
|
137
110
|
this.bridge.notify('Getting user profile', 'info');
|
|
138
|
-
|
|
111
|
+
|
|
139
112
|
try {
|
|
140
113
|
const data = await this.bridge.transport.os.profile.get();
|
|
141
114
|
const duration = Date.now() - startTime;
|
|
142
|
-
this.bridge.notify(`Profile loaded (${duration}ms)`, 'success
|
|
115
|
+
this.bridge.notify(`Profile loaded (${duration}ms)`, 'success`);
|
|
143
116
|
this.result.set({ status: 'success', request, data });
|
|
144
117
|
} catch (err) {
|
|
145
118
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHostBridge, type HostBridge } from '@bardioc/app-sdk';
|
|
2
2
|
|
|
3
|
-
export function createBardiocBridge(
|
|
4
|
-
return createHostBridge({
|
|
5
|
-
}
|
|
3
|
+
export function createBardiocBridge(): HostBridge {
|
|
4
|
+
return createHostBridge({});
|
|
5
|
+
}
|
|
@@ -1,65 +1,31 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ensureDevAuthSession,
|
|
3
2
|
installDevBridge,
|
|
4
3
|
isDevStandalone,
|
|
5
4
|
isInsideIframe,
|
|
6
5
|
} from '@bardioc/app-sdk/dev';
|
|
7
6
|
import { bootstrapApplication } from '@angular/platform-browser';
|
|
8
7
|
import { provideHttpClient } from '@angular/common/http';
|
|
9
|
-
import {
|
|
8
|
+
import { type EnvironmentProviders, type Provider } from '@angular/core';
|
|
10
9
|
import { AppComponent } from './app/app.component';
|
|
11
10
|
import { createBardiocBridge } from './app/bardioc-bridge';
|
|
12
11
|
import { BARDIOC_BRIDGE } from './app/bardioc.token';
|
|
13
|
-
import { readRuntimeEnv } from './runtime-env';
|
|
14
12
|
import './styles.css';
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
proxyUrl?: string;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
function readInjectedDevAuthConfig(): InjectedDevAuthConfig | null {
|
|
23
|
-
const config = (globalThis as typeof globalThis & {
|
|
24
|
-
__BARDIOC_DEV_AUTH__?: InjectedDevAuthConfig;
|
|
25
|
-
}).__BARDIOC_DEV_AUTH__;
|
|
26
|
-
|
|
27
|
-
if (!config?.hostUrl || !config?.sessionKey) {
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return {
|
|
32
|
-
hostUrl: config.hostUrl,
|
|
33
|
-
sessionKey: config.sessionKey,
|
|
34
|
-
proxyUrl: typeof config.proxyUrl === 'string' ? config.proxyUrl : undefined,
|
|
35
|
-
};
|
|
14
|
+
function readAppPort(): number {
|
|
15
|
+
const parsed = Number.parseInt(window.location.port, 10);
|
|
16
|
+
return Number.isFinite(parsed) ? parsed : {{PORT}};
|
|
36
17
|
}
|
|
37
18
|
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
const injectedDevAuth = readInjectedDevAuthConfig();
|
|
41
|
-
const standaloneDevAuthEnabled =
|
|
42
|
-
isDevMode() &&
|
|
43
|
-
readRuntimeEnv('VITE_ENABLE_DEV_AUTH') === 'true' &&
|
|
44
|
-
!!injectedDevAuth?.hostUrl &&
|
|
45
|
-
!!injectedDevAuth?.sessionKey;
|
|
46
|
-
|
|
19
|
+
const appPort = readAppPort();
|
|
20
|
+
const proxyPort = appPort + 100;
|
|
47
21
|
const insideIframe = isInsideIframe();
|
|
48
|
-
const devStandalone =
|
|
22
|
+
const devStandalone = isDevStandalone();
|
|
49
23
|
const useSdkProvider = insideIframe || devStandalone;
|
|
50
24
|
|
|
51
|
-
if (useSdkProvider && !APP_ID) {
|
|
52
|
-
throw new Error('Missing VITE_APP_ID for SDK runtime');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
25
|
async function bootstrap() {
|
|
56
26
|
if (devStandalone) {
|
|
57
|
-
await ensureDevAuthSession({ appId: APP_ID!, appName: APP_NAME });
|
|
58
27
|
installDevBridge({
|
|
59
|
-
|
|
60
|
-
appName: APP_NAME,
|
|
61
|
-
debug: false,
|
|
62
|
-
proxyPath: injectedDevAuth?.proxyUrl,
|
|
28
|
+
apiBaseUrl: `http://127.0.0.1:${proxyPort}/rest`,
|
|
63
29
|
});
|
|
64
30
|
}
|
|
65
31
|
|
|
@@ -70,7 +36,7 @@ async function bootstrap() {
|
|
|
70
36
|
if (useSdkProvider) {
|
|
71
37
|
providers.push({
|
|
72
38
|
provide: BARDIOC_BRIDGE,
|
|
73
|
-
useValue: createBardiocBridge(
|
|
39
|
+
useValue: createBardiocBridge(),
|
|
74
40
|
});
|
|
75
41
|
}
|
|
76
42
|
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
NEXT_PUBLIC_APP_NAME={{APP_NAME}}
|
|
2
|
-
NEXT_PUBLIC_APP_ID=your-app-client-id-here
|
|
3
|
-
NEXT_PUBLIC_ENABLE_DEV_AUTH=false
|
|
4
2
|
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
# Shared secret used for dev auth when proxying API requests through /rest.
|
|
4
|
+
DEV_SECRET=
|
|
5
|
+
|
|
6
|
+
# Base URL of the Bardioc API backend to proxy /rest requests to.
|
|
7
|
+
API_BASE_URL=
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { isInsideIframe, isDevStandalone, installDevBridge } from '@bardioc/app-sdk/dev';
|
|
4
4
|
import { AppSdkProvider, useNotify, useSdk } from '@bardioc/app-sdk/react';
|
|
5
|
-
import { useEffect, useState
|
|
5
|
+
import { useEffect, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
type ResultState =
|
|
8
8
|
| { status: 'idle' }
|
|
@@ -10,33 +10,7 @@ type ResultState =
|
|
|
10
10
|
| { status: 'success'; request: string; data: unknown }
|
|
11
11
|
| { status: 'error'; request: string; message: string };
|
|
12
12
|
|
|
13
|
-
type InjectedDevAuthConfig = {
|
|
14
|
-
hostUrl?: string;
|
|
15
|
-
sessionKey?: string;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
13
|
const APP_NAME = process.env.NEXT_PUBLIC_APP_NAME?.trim();
|
|
19
|
-
const APP_ID = process.env.NEXT_PUBLIC_APP_ID?.trim();
|
|
20
|
-
const standaloneDevAuthEnabled =
|
|
21
|
-
process.env.NODE_ENV === 'development' && process.env.NEXT_PUBLIC_ENABLE_DEV_AUTH === 'true';
|
|
22
|
-
const DEV_AUTH_HOST_URL = process.env.NEXT_PUBLIC_DEV_AUTH_HOST_URL?.trim();
|
|
23
|
-
const DEV_SESSION_KEY = process.env.NEXT_PUBLIC_DEV_SESSION_KEY?.trim();
|
|
24
|
-
|
|
25
|
-
function installInjectedDevAuthConfig() {
|
|
26
|
-
if (!DEV_AUTH_HOST_URL || !DEV_SESSION_KEY) {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
(
|
|
31
|
-
window as Window &
|
|
32
|
-
typeof globalThis & {
|
|
33
|
-
__BARDIOC_DEV_AUTH__?: InjectedDevAuthConfig;
|
|
34
|
-
}
|
|
35
|
-
).__BARDIOC_DEV_AUTH__ = {
|
|
36
|
-
hostUrl: DEV_AUTH_HOST_URL,
|
|
37
|
-
sessionKey: DEV_SESSION_KEY,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
14
|
|
|
41
15
|
function SdkDemo() {
|
|
42
16
|
const bridge = useSdk();
|
|
@@ -161,62 +135,28 @@ function PreviewShell() {
|
|
|
161
135
|
);
|
|
162
136
|
}
|
|
163
137
|
|
|
164
|
-
function DevAuthProvider({ children, enabled }: { children: ReactNode; enabled: boolean }) {
|
|
165
|
-
const requiresStandaloneDevAuth = enabled && standaloneDevAuthEnabled && !!APP_ID && !!APP_NAME;
|
|
166
|
-
const [ready, setReady] = useState(!requiresStandaloneDevAuth);
|
|
167
|
-
|
|
168
|
-
useEffect(() => {
|
|
169
|
-
if (!requiresStandaloneDevAuth) {
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
installInjectedDevAuthConfig();
|
|
174
|
-
|
|
175
|
-
ensureDevAuthSession({ appId: APP_ID, appName: APP_NAME })
|
|
176
|
-
.then(() => {
|
|
177
|
-
installDevBridge({ appId: APP_ID, appName: APP_NAME, debug: false });
|
|
178
|
-
setReady(true);
|
|
179
|
-
})
|
|
180
|
-
.catch(error => {
|
|
181
|
-
console.error('[template-smoke-nextjs] failed to initialize dev bridge', error);
|
|
182
|
-
setReady(true);
|
|
183
|
-
});
|
|
184
|
-
}, [requiresStandaloneDevAuth]);
|
|
185
|
-
|
|
186
|
-
if (!ready) {
|
|
187
|
-
return (
|
|
188
|
-
<div className="flex min-h-screen items-center justify-center">
|
|
189
|
-
<div className="text-muted-foreground text-xs">Initializing dev bridge...</div>
|
|
190
|
-
</div>
|
|
191
|
-
);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
return <>{children}</>;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
138
|
export default function Page() {
|
|
198
|
-
const useSdkProvider =
|
|
199
|
-
standaloneDevAuthEnabled || (typeof window !== 'undefined' && window.parent !== window);
|
|
139
|
+
const useSdkProvider = isInsideIframe() || isDevStandalone();
|
|
200
140
|
|
|
201
141
|
if (!APP_NAME) {
|
|
202
142
|
throw new Error('Missing NEXT_PUBLIC_APP_NAME for runtime');
|
|
203
143
|
}
|
|
204
144
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
if (isDevStandalone()) {
|
|
147
|
+
installDevBridge();
|
|
148
|
+
}
|
|
149
|
+
}, []);
|
|
208
150
|
|
|
209
151
|
return (
|
|
210
152
|
<div className="bg-background text-foreground min-h-screen">
|
|
211
|
-
|
|
212
|
-
{
|
|
213
|
-
<
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
)}
|
|
219
|
-
</DevAuthProvider>
|
|
153
|
+
{useSdkProvider ? (
|
|
154
|
+
<AppSdkProvider appId={APP_NAME}>
|
|
155
|
+
<SdkDemo />
|
|
156
|
+
</AppSdkProvider>
|
|
157
|
+
) : (
|
|
158
|
+
<PreviewShell />
|
|
159
|
+
)}
|
|
220
160
|
</div>
|
|
221
161
|
);
|
|
222
162
|
}
|
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
import type { NextConfig } from 'next';
|
|
2
2
|
|
|
3
|
+
const apiBaseUrl = process.env.API_BASE_URL?.replace(/\/$/, '');
|
|
4
|
+
const devSecret = process.env.DEV_SECRET;
|
|
5
|
+
|
|
3
6
|
const nextConfig: NextConfig = {
|
|
4
7
|
output: 'export',
|
|
5
|
-
env: {
|
|
6
|
-
NEXT_PUBLIC_APP_NAME: process.env.NEXT_PUBLIC_APP_NAME ?? process.env.VITE_APP_NAME,
|
|
7
|
-
NEXT_PUBLIC_APP_ID: process.env.NEXT_PUBLIC_APP_ID ?? process.env.VITE_APP_ID,
|
|
8
|
-
NEXT_PUBLIC_ENABLE_DEV_AUTH:
|
|
9
|
-
process.env.NEXT_PUBLIC_ENABLE_DEV_AUTH ?? process.env.VITE_ENABLE_DEV_AUTH,
|
|
10
|
-
NEXT_PUBLIC_DEV_AUTH_HOST_URL:
|
|
11
|
-
process.env.NEXT_PUBLIC_DEV_AUTH_HOST_URL ?? process.env.DEV_AUTH_HOST_URL,
|
|
12
|
-
NEXT_PUBLIC_DEV_SESSION_KEY:
|
|
13
|
-
process.env.NEXT_PUBLIC_DEV_SESSION_KEY ?? process.env.DEV_SESSION_KEY,
|
|
14
|
-
},
|
|
15
8
|
images: {
|
|
16
9
|
unoptimized: true,
|
|
17
10
|
},
|
|
18
11
|
trailingSlash: true,
|
|
12
|
+
async headers() {
|
|
13
|
+
if (!devSecret) return [];
|
|
14
|
+
return [
|
|
15
|
+
{
|
|
16
|
+
source: '/rest/:path*',
|
|
17
|
+
headers: [{ key: 'X-Dev-Secret', value: devSecret }],
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
},
|
|
21
|
+
async rewrites() {
|
|
22
|
+
if (!apiBaseUrl) return [];
|
|
23
|
+
return [
|
|
24
|
+
{
|
|
25
|
+
source: '/rest/:path*',
|
|
26
|
+
destination: `${apiBaseUrl}/:path*`,
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
},
|
|
19
30
|
};
|
|
20
31
|
|
|
21
|
-
export default nextConfig;
|
|
32
|
+
export default nextConfig;
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
"version": "0.0.1",
|
|
4
4
|
"private": true,
|
|
5
5
|
"scripts": {
|
|
6
|
-
"dev": "
|
|
7
|
-
"dev:live": "BARDIOC_TUNNEL=1
|
|
6
|
+
"dev": "next dev --port {{PORT}}",
|
|
7
|
+
"dev:live": "BARDIOC_TUNNEL=1 next dev --port {{PORT}}",
|
|
8
8
|
"build": "next build && node scripts/stamp-manifest.mjs out",
|
|
9
9
|
"bundle": "next build && node scripts/stamp-manifest.mjs out && cd out && zip -r ../{{APP_NAME}}.zip .",
|
|
10
10
|
"start": "next start",
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
# Hosted app slug used by local runtime/dev-auth wiring.
|
|
2
2
|
VITE_APP_NAME={{APP_NAME}}
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
|
|
4
|
+
# Paste the dev secret from the BardiocOS AppStore after registering your app.
|
|
5
|
+
# Used by the Vite dev-auth proxy to sign requests to the BFF.
|
|
6
|
+
DEV_SECRET=
|
|
7
7
|
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# Copy these from the host App Store app details via "Copy Dev Session".
|
|
12
|
-
DEV_AUTH_HOST_URL=
|
|
13
|
-
DEV_SESSION_KEY=
|
|
8
|
+
# Base URL of the Bardioc BFF / backend-for-frontend (e.g. https://your-host).
|
|
9
|
+
API_BASE_URL=
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"dev": "
|
|
8
|
-
"dev:live": "BARDIOC_TUNNEL=1
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"dev:live": "BARDIOC_TUNNEL=1 vite",
|
|
9
9
|
"build": "tsc && vite build && node scripts/stamp-manifest.mjs dist",
|
|
10
10
|
"bundle": "tsc && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
11
11
|
"preview": "vite preview",
|
|
@@ -117,7 +117,7 @@ function SdkDemo() {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
export function App() {
|
|
120
|
-
const showSdkDemo = isInsideIframe() ||
|
|
120
|
+
const showSdkDemo = isInsideIframe() || isDevStandalone();
|
|
121
121
|
|
|
122
122
|
return (
|
|
123
123
|
<div className="bg-background text-foreground min-h-screen">
|
|
@@ -1,46 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ensureDevAuthSession,
|
|
3
|
-
installDevBridge,
|
|
4
|
-
isDevStandalone,
|
|
5
|
-
isInsideIframe,
|
|
6
|
-
} from '@bardioc/app-sdk/dev';
|
|
1
|
+
import { installDevBridge, isDevStandalone, isInsideIframe } from '@bardioc/app-sdk/dev';
|
|
7
2
|
import { AppSdkProvider } from '@bardioc/app-sdk/react';
|
|
8
3
|
import { render } from 'preact';
|
|
9
4
|
import { App } from './App';
|
|
10
5
|
import './index.css';
|
|
11
6
|
|
|
12
7
|
const APP_NAME = import.meta.env.VITE_APP_NAME?.trim();
|
|
13
|
-
const APP_ID = import.meta.env.VITE_APP_ID?.trim();
|
|
14
|
-
const standaloneDevAuthEnabled = import.meta.env.DEV && import.meta.env.VITE_ENABLE_DEV_AUTH === 'true';
|
|
15
8
|
|
|
16
9
|
if (!APP_NAME) {
|
|
17
10
|
throw new Error('Missing VITE_APP_NAME for runtime');
|
|
18
11
|
}
|
|
19
12
|
|
|
20
13
|
const insideIframe = isInsideIframe();
|
|
21
|
-
const devStandalone =
|
|
14
|
+
const devStandalone = isDevStandalone();
|
|
22
15
|
const useSdkProvider = insideIframe || devStandalone;
|
|
23
16
|
|
|
24
|
-
if (
|
|
25
|
-
|
|
17
|
+
if (devStandalone) {
|
|
18
|
+
installDevBridge({ debug: false });
|
|
26
19
|
}
|
|
27
20
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
installDevBridge({ appId: APP_ID, appName: APP_NAME, debug: false });
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
render(
|
|
35
|
-
useSdkProvider ? (
|
|
36
|
-
<AppSdkProvider appId={APP_ID!}>
|
|
37
|
-
<App />
|
|
38
|
-
</AppSdkProvider>
|
|
39
|
-
) : (
|
|
21
|
+
render(
|
|
22
|
+
useSdkProvider ? (
|
|
23
|
+
<AppSdkProvider appId={APP_NAME}>
|
|
40
24
|
<App />
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
25
|
+
</AppSdkProvider>
|
|
26
|
+
) : (
|
|
27
|
+
<App />
|
|
28
|
+
),
|
|
29
|
+
document.getElementById('root')!
|
|
30
|
+
);
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
# Hosted app slug used by local runtime/dev-auth wiring.
|
|
2
2
|
VITE_APP_NAME={{APP_NAME}}
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
|
|
4
|
+
# Paste the dev secret from the BardiocOS AppStore after registering your app.
|
|
5
|
+
# Used by the Vite dev-auth proxy to sign requests to the BFF.
|
|
6
|
+
DEV_SECRET=
|
|
7
7
|
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# Copy these from the host App Store app details via "Copy Dev Session".
|
|
12
|
-
DEV_AUTH_HOST_URL=
|
|
13
|
-
DEV_SESSION_KEY=
|
|
8
|
+
# Base URL of the Bardioc BFF / backend-for-frontend (e.g. https://your-host).
|
|
9
|
+
API_BASE_URL=
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"dev": "
|
|
8
|
-
"dev:live": "BARDIOC_TUNNEL=1
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"dev:live": "BARDIOC_TUNNEL=1 vite",
|
|
9
9
|
"build": "tsc && vite build && node scripts/stamp-manifest.mjs dist",
|
|
10
10
|
"bundle": "tsc && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
11
11
|
"preview": "vite preview",
|
|
@@ -128,7 +128,7 @@ function SdkDemo() {
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
export function App() {
|
|
131
|
-
const showSdkDemo = isInsideIframe() ||
|
|
131
|
+
const showSdkDemo = isInsideIframe() || isDevStandalone();
|
|
132
132
|
|
|
133
133
|
return (
|
|
134
134
|
<div class="bg-background text-foreground min-h-screen">
|
|
@@ -1,50 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ensureDevAuthSession,
|
|
3
|
-
installDevBridge,
|
|
4
|
-
isDevStandalone,
|
|
5
|
-
isInsideIframe,
|
|
6
|
-
} from '@bardioc/app-sdk/dev';
|
|
1
|
+
import { installDevBridge, isDevStandalone, isInsideIframe } from '@bardioc/app-sdk/dev';
|
|
7
2
|
import { render } from 'solid-js/web';
|
|
8
3
|
import { App } from './App';
|
|
9
4
|
import { AppSdkProvider } from './bardioc-sdk';
|
|
10
5
|
import './index.css';
|
|
11
6
|
|
|
12
7
|
const APP_NAME = import.meta.env.VITE_APP_NAME?.trim();
|
|
13
|
-
const APP_ID = import.meta.env.VITE_APP_ID?.trim();
|
|
14
|
-
const standaloneDevAuthEnabled = import.meta.env.DEV && import.meta.env.VITE_ENABLE_DEV_AUTH === 'true';
|
|
15
8
|
|
|
16
9
|
if (!APP_NAME) {
|
|
17
10
|
throw new Error('Missing VITE_APP_NAME for runtime');
|
|
18
11
|
}
|
|
19
12
|
|
|
20
13
|
const insideIframe = isInsideIframe();
|
|
21
|
-
const devStandalone =
|
|
14
|
+
const devStandalone = isDevStandalone();
|
|
22
15
|
const useSdkProvider = insideIframe || devStandalone;
|
|
23
16
|
|
|
24
|
-
if (
|
|
25
|
-
|
|
17
|
+
if (devStandalone) {
|
|
18
|
+
installDevBridge({ debug: false });
|
|
26
19
|
}
|
|
27
20
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
</AppSdkProvider>
|
|
42
|
-
),
|
|
43
|
-
root
|
|
44
|
-
);
|
|
45
|
-
} else {
|
|
46
|
-
render(() => <App />, root);
|
|
47
|
-
}
|
|
21
|
+
const root = document.getElementById('root')!;
|
|
22
|
+
|
|
23
|
+
if (useSdkProvider) {
|
|
24
|
+
render(
|
|
25
|
+
() => (
|
|
26
|
+
<AppSdkProvider appId={APP_NAME}>
|
|
27
|
+
<App />
|
|
28
|
+
</AppSdkProvider>
|
|
29
|
+
),
|
|
30
|
+
root
|
|
31
|
+
);
|
|
32
|
+
} else {
|
|
33
|
+
render(() => <App />, root);
|
|
48
34
|
}
|
|
49
|
-
|
|
50
|
-
bootstrap();
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
# Hosted app slug used by local runtime/dev-auth wiring.
|
|
1
2
|
VITE_APP_NAME={{APP_NAME}}
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
|
|
4
|
+
# Paste the dev secret from the BardiocOS AppStore after registering your app.
|
|
5
|
+
# Used by the Vite dev-auth proxy to sign requests to the BFF.
|
|
6
|
+
DEV_SECRET=
|
|
7
|
+
|
|
8
|
+
# Base URL of the Bardioc BFF / backend-for-frontend (e.g. https://your-host).
|
|
9
|
+
API_BASE_URL=
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"dev": "
|
|
8
|
-
"dev:live": "BARDIOC_TUNNEL=1
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"dev:live": "BARDIOC_TUNNEL=1 vite",
|
|
9
9
|
"build": "svelte-check && vite build && node scripts/stamp-manifest.mjs dist",
|
|
10
10
|
"bundle": "svelte-check && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
11
11
|
"preview": "vite preview",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
let { bridge = null, children }: { bridge?: HostBridge | null; children?: Snippet } = $props();
|
|
14
14
|
|
|
15
|
-
const showSdkDemo = isInsideIframe() ||
|
|
15
|
+
const showSdkDemo = isInsideIframe() || isDevStandalone();
|
|
16
16
|
|
|
17
17
|
let result = $state<ResultState>({ status: 'idle' });
|
|
18
18
|
let running = $state(false);
|
|
@@ -1,42 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ensureDevAuthSession,
|
|
3
|
-
installDevBridge,
|
|
4
|
-
isDevStandalone,
|
|
5
|
-
isInsideIframe,
|
|
6
|
-
} from '@bardioc/app-sdk/dev';
|
|
1
|
+
import { installDevBridge, isDevStandalone, isInsideIframe } from '@bardioc/app-sdk/dev';
|
|
7
2
|
import { createHostBridge } from '@bardioc/app-sdk';
|
|
8
3
|
import { mount } from 'svelte';
|
|
9
4
|
import App from './App.svelte';
|
|
10
5
|
import './index.css';
|
|
11
6
|
|
|
12
7
|
const APP_NAME = import.meta.env.VITE_APP_NAME?.trim();
|
|
13
|
-
const APP_ID = import.meta.env.VITE_APP_ID?.trim();
|
|
14
|
-
const standaloneDevAuthEnabled = import.meta.env.DEV && import.meta.env.VITE_ENABLE_DEV_AUTH === 'true';
|
|
15
8
|
|
|
16
9
|
if (!APP_NAME) {
|
|
17
10
|
throw new Error('Missing VITE_APP_NAME for runtime');
|
|
18
11
|
}
|
|
19
12
|
|
|
20
13
|
const insideIframe = isInsideIframe();
|
|
21
|
-
const devStandalone =
|
|
14
|
+
const devStandalone = isDevStandalone();
|
|
22
15
|
const useSdkProvider = insideIframe || devStandalone;
|
|
23
16
|
|
|
24
|
-
if (
|
|
25
|
-
|
|
17
|
+
if (devStandalone) {
|
|
18
|
+
installDevBridge({ debug: false });
|
|
26
19
|
}
|
|
27
20
|
|
|
28
|
-
|
|
29
|
-
if (devStandalone) {
|
|
30
|
-
await ensureDevAuthSession({ appId: APP_ID, appName: APP_NAME });
|
|
31
|
-
installDevBridge({ appId: APP_ID, appName: APP_NAME, debug: false });
|
|
32
|
-
}
|
|
21
|
+
const bridge = useSdkProvider ? createHostBridge({ appId: APP_NAME }) : null;
|
|
33
22
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
props: { bridge },
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
bootstrap();
|
|
23
|
+
mount(App, {
|
|
24
|
+
target: document.getElementById('app')!,
|
|
25
|
+
props: { bridge },
|
|
26
|
+
});
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
# Hosted app slug used by local runtime/dev-auth wiring.
|
|
2
2
|
VITE_APP_NAME={{APP_NAME}}
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
|
|
4
|
+
# Paste the dev secret from the BardiocOS AppStore after registering your app.
|
|
5
|
+
# Used by the Vite dev-auth proxy to sign requests to the BFF.
|
|
6
|
+
DEV_SECRET=
|
|
7
7
|
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# Required host URL for standalone dev auth. Run `bardioc login` once, then
|
|
12
|
-
# `npm run dev` will refresh DEV_SESSION_KEY automatically before Vite starts.
|
|
13
|
-
DEV_AUTH_HOST_URL=
|
|
14
|
-
DEV_SESSION_KEY=
|
|
8
|
+
# Base URL of the Bardioc BFF / backend-for-frontend (e.g. https://your-host).
|
|
9
|
+
API_BASE_URL=
|
package/templates/vite/CLAUDE.md
CHANGED
|
@@ -33,7 +33,7 @@ src/
|
|
|
33
33
|
dashboard-provider.tsx # context: climate state + profile, via useDashboard()
|
|
34
34
|
use-app-notify.ts # OS host notification (useNotify) mirrored to a local toast
|
|
35
35
|
auth/
|
|
36
|
-
onboarding.tsx # Empty full-page screen with the
|
|
36
|
+
onboarding.tsx # Empty full-page screen with the DEV_SECRET dev-auth steps
|
|
37
37
|
shell/
|
|
38
38
|
app-shell.tsx # Sidebar + view routing + Toaster + OS top-menu integration (useCommandMenu)
|
|
39
39
|
about-dialog.tsx # "About" Dialog — reads public/app-manifest.json at runtime (manifest example)
|
|
@@ -75,8 +75,8 @@ pnpm bundle # → {{APP_NAME}}.zip
|
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
`npm run dev` runs plain Vite — a local preview shell (no transport): the dashboard renders, but
|
|
78
|
-
live SDK data comes only when the app is opened inside the host
|
|
79
|
-
`
|
|
78
|
+
live SDK data comes only when the app is opened inside the host, or when `DEV_SECRET` and
|
|
79
|
+
`API_BASE_URL` are set for standalone dev auth (see `.env.example`).
|
|
80
80
|
|
|
81
81
|
---
|
|
82
82
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"dev": "vite",
|
|
8
8
|
"dev:live": "BARDIOC_TUNNEL=1 vite",
|
|
9
9
|
"build": "tsc && vite build && node scripts/stamp-manifest.mjs dist",
|
|
10
|
-
"bundle": "tsc && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
10
|
+
"bundle": "rm -f {{APP_NAME}}.zip && tsc && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
11
11
|
"preview": "vite preview",
|
|
12
12
|
"check-types": "tsc --noEmit",
|
|
13
13
|
"changeset": "changeset",
|
|
@@ -4,8 +4,7 @@ import { DashboardProvider } from './dashboard-provider';
|
|
|
4
4
|
import { AppShell } from './shell/app-shell';
|
|
5
5
|
|
|
6
6
|
export function App() {
|
|
7
|
-
const authorized =
|
|
8
|
-
isInsideIframe() || (import.meta.env.VITE_ENABLE_DEV_AUTH === 'true' && isDevStandalone());
|
|
7
|
+
const authorized = isInsideIframe() || isDevStandalone();
|
|
9
8
|
|
|
10
9
|
if (!authorized) {
|
|
11
10
|
return <Onboarding />;
|
|
@@ -18,7 +18,6 @@ function DetectedRow({ label, ok }: Readonly<{ label: string; ok: boolean }>) {
|
|
|
18
18
|
export function Onboarding() {
|
|
19
19
|
const { t } = useTranslation();
|
|
20
20
|
const insideHost = isInsideIframe();
|
|
21
|
-
const devAuth = import.meta.env.VITE_ENABLE_DEV_AUTH === 'true';
|
|
22
21
|
|
|
23
22
|
return (
|
|
24
23
|
<Empty
|
|
@@ -38,16 +37,16 @@ export function Onboarding() {
|
|
|
38
37
|
>
|
|
39
38
|
<div className="border-border bg-card mt-4 w-full max-w-md rounded-lg border p-4 text-left text-xs leading-6">
|
|
40
39
|
<p className="text-foreground mb-2 font-medium">
|
|
41
|
-
{t('auth.stepsTitle', { fallback: 'Run standalone with
|
|
40
|
+
{t('auth.stepsTitle', { fallback: 'Run standalone with dev auth:' })}
|
|
42
41
|
</p>
|
|
43
42
|
<ol className="text-muted-foreground list-decimal space-y-2 pl-4">
|
|
44
|
-
<li>{t('auth.step1', { fallback: 'Set VITE_ENABLE_DEV_AUTH=true in .env' })}</li>
|
|
45
43
|
<li>
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
{t('auth.step1', {
|
|
45
|
+
fallback: 'Set DEV_SECRET=<your-secret> and API_BASE_URL=<your-host> in .env',
|
|
46
|
+
})}
|
|
48
47
|
</li>
|
|
49
48
|
<li>
|
|
50
|
-
<div>{t('auth.
|
|
49
|
+
<div>{t('auth.step2', { fallback: 'Start the dev server:' })}</div>
|
|
51
50
|
<Kbd>pnpm dev</Kbd>
|
|
52
51
|
</li>
|
|
53
52
|
</ol>
|
|
@@ -59,7 +58,6 @@ export function Onboarding() {
|
|
|
59
58
|
label={t('auth.insideHost', { fallback: 'Inside host iframe' })}
|
|
60
59
|
ok={insideHost}
|
|
61
60
|
/>
|
|
62
|
-
<DetectedRow label={t('auth.devAuth', { fallback: 'Dev auth enabled' })} ok={devAuth} />
|
|
63
61
|
</div>
|
|
64
62
|
</div>
|
|
65
63
|
</Empty>
|
|
@@ -42,9 +42,8 @@
|
|
|
42
42
|
"title": "Mit Bardioc OS verbinden",
|
|
43
43
|
"description": "Dieses Dashboard liest Live-Daten über den Bardioc-SDK-Transport. Es läuft in Bardioc OS oder eigenständig mit einer CLI-Dev-Session.",
|
|
44
44
|
"stepsTitle": "Eigenständig mit Dev-Session ausführen:",
|
|
45
|
-
"step1": "Setze
|
|
46
|
-
"step2": "
|
|
47
|
-
"step3": "Dev-Server starten — der Session-Key wird automatisch erzeugt und erneuert:",
|
|
45
|
+
"step1": "Setze DEV_SECRET=<dein-secret> und API_BASE_URL=<dein-host> in .env",
|
|
46
|
+
"step2": "Dev-Server starten:",
|
|
48
47
|
"detectedTitle": "Erkannte Umgebung",
|
|
49
48
|
"insideHost": "Im Host-Iframe",
|
|
50
49
|
"devAuth": "Dev-Auth aktiviert",
|
|
@@ -42,9 +42,8 @@
|
|
|
42
42
|
"title": "Connect to Bardioc OS",
|
|
43
43
|
"description": "This dashboard reads live data through the Bardioc SDK transport. It runs when opened inside Bardioc OS, or standalone with a CLI dev session.",
|
|
44
44
|
"stepsTitle": "Run standalone with a dev session:",
|
|
45
|
-
"step1": "Set
|
|
46
|
-
"step2": "
|
|
47
|
-
"step3": "Start the dev server — the session key is minted and refreshed automatically:",
|
|
45
|
+
"step1": "Set DEV_SECRET=<your-secret> and API_BASE_URL=<your-host> in .env",
|
|
46
|
+
"step2": "Start the dev server:",
|
|
48
47
|
"detectedTitle": "Detected environment",
|
|
49
48
|
"insideHost": "Inside host iframe",
|
|
50
49
|
"devAuth": "Dev auth enabled",
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ensureDevAuthSession,
|
|
3
|
-
installDevBridge,
|
|
4
|
-
isDevStandalone,
|
|
5
|
-
isInsideIframe,
|
|
6
|
-
} from '@bardioc/app-sdk/dev';
|
|
1
|
+
import { installDevBridge, isDevStandalone, isInsideIframe } from '@bardioc/app-sdk/dev';
|
|
7
2
|
import { AppSdkProvider } from '@bardioc/app-sdk/react';
|
|
8
3
|
import { StrictMode } from 'react';
|
|
9
4
|
import { createRoot } from 'react-dom/client';
|
|
@@ -12,31 +7,23 @@ import { AppI18nProvider } from './i18n';
|
|
|
12
7
|
import './index.css';
|
|
13
8
|
|
|
14
9
|
const APP_NAME = import.meta.env.VITE_APP_NAME?.trim();
|
|
15
|
-
const APP_ID = import.meta.env.VITE_APP_ID?.trim();
|
|
16
|
-
const standaloneDevAuthEnabled =
|
|
17
|
-
import.meta.env.DEV && import.meta.env.VITE_ENABLE_DEV_AUTH === 'true';
|
|
18
10
|
|
|
19
11
|
if (!APP_NAME) {
|
|
20
12
|
throw new Error('Missing VITE_APP_NAME for runtime');
|
|
21
13
|
}
|
|
22
14
|
|
|
23
15
|
const insideIframe = isInsideIframe();
|
|
24
|
-
const devStandalone =
|
|
16
|
+
const devStandalone = isDevStandalone();
|
|
25
17
|
const useSdkProvider = insideIframe || devStandalone;
|
|
26
18
|
|
|
27
|
-
if (useSdkProvider && !APP_ID) {
|
|
28
|
-
throw new Error('Missing VITE_APP_ID for SDK runtime');
|
|
29
|
-
}
|
|
30
|
-
|
|
31
19
|
if (devStandalone) {
|
|
32
|
-
|
|
33
|
-
installDevBridge({ appId: APP_ID, appName: APP_NAME, debug: false });
|
|
20
|
+
installDevBridge({ debug: false });
|
|
34
21
|
}
|
|
35
22
|
|
|
36
23
|
createRoot(document.getElementById('root')!).render(
|
|
37
24
|
<StrictMode>
|
|
38
25
|
{useSdkProvider ? (
|
|
39
|
-
<AppSdkProvider appId={
|
|
26
|
+
<AppSdkProvider appId={APP_NAME}>
|
|
40
27
|
<AppI18nProvider syncWithOs>
|
|
41
28
|
<App />
|
|
42
29
|
</AppI18nProvider>
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
# Hosted app slug used by local runtime/dev-auth wiring.
|
|
1
2
|
VITE_APP_NAME={{APP_NAME}}
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
|
|
4
|
+
# Paste the dev secret from the BardiocOS AppStore after registering your app.
|
|
5
|
+
# Used by the Vite dev-auth proxy to sign requests to the BFF.
|
|
6
|
+
DEV_SECRET=
|
|
7
|
+
|
|
8
|
+
# Base URL of the Bardioc BFF / backend-for-frontend (e.g. https://your-host).
|
|
9
|
+
API_BASE_URL=
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"dev": "
|
|
8
|
-
"dev:live": "BARDIOC_TUNNEL=1
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"dev:live": "BARDIOC_TUNNEL=1 vite",
|
|
9
9
|
"build": "vue-tsc -b && vite build && node scripts/stamp-manifest.mjs dist",
|
|
10
10
|
"bundle": "vue-tsc -b && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
11
11
|
"preview": "vite preview",
|
|
@@ -9,7 +9,7 @@ type ResultState =
|
|
|
9
9
|
| { status: 'success'; request: string; data: unknown }
|
|
10
10
|
| { status: 'error'; request: string; message: string };
|
|
11
11
|
|
|
12
|
-
const showSdkDemo = isInsideIframe() ||
|
|
12
|
+
const showSdkDemo = isInsideIframe() || isDevStandalone();
|
|
13
13
|
const bridge = useBardiocBridge();
|
|
14
14
|
const notify = useNotify();
|
|
15
15
|
const result = ref<ResultState>({ status: 'idle' });
|
|
@@ -1,43 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ensureDevAuthSession,
|
|
3
|
-
installDevBridge,
|
|
4
|
-
isDevStandalone,
|
|
5
|
-
isInsideIframe,
|
|
6
|
-
} from '@bardioc/app-sdk/dev';
|
|
1
|
+
import { installDevBridge, isDevStandalone, isInsideIframe } from '@bardioc/app-sdk/dev';
|
|
7
2
|
import { createApp } from 'vue';
|
|
8
3
|
import App from './App.vue';
|
|
9
4
|
import { BARDIOC_BRIDGE_KEY, createAppSdkBridge } from './bardioc-sdk';
|
|
10
5
|
import './index.css';
|
|
11
6
|
|
|
12
7
|
const APP_NAME = import.meta.env.VITE_APP_NAME?.trim();
|
|
13
|
-
const APP_ID = import.meta.env.VITE_APP_ID?.trim();
|
|
14
|
-
const standaloneDevAuthEnabled = import.meta.env.DEV && import.meta.env.VITE_ENABLE_DEV_AUTH === 'true';
|
|
15
8
|
|
|
16
9
|
if (!APP_NAME) {
|
|
17
10
|
throw new Error('Missing VITE_APP_NAME for runtime');
|
|
18
11
|
}
|
|
19
12
|
|
|
20
13
|
const insideIframe = isInsideIframe();
|
|
21
|
-
const devStandalone =
|
|
14
|
+
const devStandalone = isDevStandalone();
|
|
22
15
|
const useSdkProvider = insideIframe || devStandalone;
|
|
23
16
|
|
|
24
|
-
if (
|
|
25
|
-
|
|
17
|
+
if (devStandalone) {
|
|
18
|
+
installDevBridge({ debug: false });
|
|
26
19
|
}
|
|
27
20
|
|
|
28
|
-
|
|
29
|
-
if (devStandalone) {
|
|
30
|
-
await ensureDevAuthSession({ appId: APP_ID, appName: APP_NAME });
|
|
31
|
-
installDevBridge({ appId: APP_ID, appName: APP_NAME, debug: false });
|
|
32
|
-
}
|
|
21
|
+
const app = createApp(App);
|
|
33
22
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (useSdkProvider) {
|
|
37
|
-
app.provide(BARDIOC_BRIDGE_KEY, createAppSdkBridge(APP_ID!));
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
app.mount('#app');
|
|
23
|
+
if (useSdkProvider) {
|
|
24
|
+
app.provide(BARDIOC_BRIDGE_KEY, createAppSdkBridge(APP_NAME));
|
|
41
25
|
}
|
|
42
26
|
|
|
43
|
-
|
|
27
|
+
app.mount('#app');
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
-
|
|
3
|
-
type ProxyPayload = {
|
|
4
|
-
path?: string;
|
|
5
|
-
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
6
|
-
body?: unknown;
|
|
7
|
-
contentType?: string;
|
|
8
|
-
scopeId?: string | null;
|
|
9
|
-
scopePolicy?: 'none' | 'optional' | 'required';
|
|
10
|
-
sessionKey?: string;
|
|
11
|
-
hostUrl?: string;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const APP_ID = process.env.NEXT_PUBLIC_APP_ID?.trim();
|
|
15
|
-
const DEV_AUTH_HOST_URL =
|
|
16
|
-
process.env.NEXT_PUBLIC_DEV_AUTH_HOST_URL?.trim() ?? process.env.DEV_AUTH_HOST_URL?.trim();
|
|
17
|
-
const DEV_SESSION_KEY =
|
|
18
|
-
process.env.NEXT_PUBLIC_DEV_SESSION_KEY?.trim() ?? process.env.DEV_SESSION_KEY?.trim();
|
|
19
|
-
|
|
20
|
-
export async function POST(request: NextRequest) {
|
|
21
|
-
const payload = (await request.json().catch(() => null)) as ProxyPayload | null;
|
|
22
|
-
|
|
23
|
-
if (!payload?.path) {
|
|
24
|
-
return NextResponse.json(
|
|
25
|
-
{ error: 'invalid_payload' },
|
|
26
|
-
{ status: 400, headers: noStoreHeaders() }
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const hostUrl = payload.hostUrl ?? DEV_AUTH_HOST_URL;
|
|
31
|
-
const sessionKey = payload.sessionKey ?? DEV_SESSION_KEY;
|
|
32
|
-
|
|
33
|
-
if (!hostUrl || !sessionKey) {
|
|
34
|
-
return NextResponse.json(
|
|
35
|
-
{ error: 'missing_dev_session' },
|
|
36
|
-
{ status: 400, headers: noStoreHeaders() }
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (!APP_ID) {
|
|
41
|
-
return NextResponse.json(
|
|
42
|
-
{ error: 'missing_app_id' },
|
|
43
|
-
{ status: 500, headers: noStoreHeaders() }
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
try {
|
|
48
|
-
const transportResponse = await fetch(`${hostUrl.replace(/\/$/, '')}/api/transport`, {
|
|
49
|
-
method: 'POST',
|
|
50
|
-
headers: {
|
|
51
|
-
'Content-Type': 'application/json',
|
|
52
|
-
'X-Dev-Session-Key': sessionKey,
|
|
53
|
-
},
|
|
54
|
-
body: JSON.stringify({
|
|
55
|
-
appId: APP_ID,
|
|
56
|
-
path: payload.path,
|
|
57
|
-
method: payload.method ?? 'GET',
|
|
58
|
-
body: payload.body,
|
|
59
|
-
contentType: payload.contentType,
|
|
60
|
-
scopePolicy: payload.scopePolicy,
|
|
61
|
-
scopeId: payload.scopeId ?? null,
|
|
62
|
-
}),
|
|
63
|
-
cache: 'no-store',
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
const responseText = await transportResponse.text();
|
|
67
|
-
|
|
68
|
-
return new NextResponse(responseText, {
|
|
69
|
-
status: transportResponse.status,
|
|
70
|
-
headers: {
|
|
71
|
-
'Cache-Control': 'no-store',
|
|
72
|
-
'Content-Type': transportResponse.headers.get('content-type') ?? 'application/json',
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
} catch {
|
|
76
|
-
return NextResponse.json(
|
|
77
|
-
{ error: 'host_transport_failed' },
|
|
78
|
-
{ status: 502, headers: noStoreHeaders() }
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function noStoreHeaders(): HeadersInit {
|
|
84
|
-
return { 'Cache-Control': 'no-store' };
|
|
85
|
-
}
|