@playcademy/vite-plugin 1.1.3-beta.3 → 1.1.3-beta.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.
@@ -9,4 +9,4 @@ export interface ProxyConfig {
9
9
  /**
10
10
  * Create proxy configuration for backend API and reserved runtime routes.
11
11
  */
12
- export declare function createProxyConfig(existingProxy: Record<string, string | ProxyOptions>, backendPort: number): Record<string, string | ProxyOptions>;
12
+ export declare function createProxyConfig(existingProxy: Record<string, string | ProxyOptions>, gameBackendPort: number): Record<string, string | ProxyOptions>;
@@ -5,4 +5,4 @@ import type { UserConfig } from 'vite';
5
5
  /**
6
6
  * Create Vite configuration with Playcademy-specific settings
7
7
  */
8
- export declare function createViteConfig(userConfig: UserConfig, backendPort: number): UserConfig;
8
+ export declare function createViteConfig(userConfig: UserConfig, gameBackendPort: number): UserConfig;
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Local dashboard proxies
3
+ *
4
+ * Dashboard mode runs the REAL composed dashboard worker (platform auth
5
+ * layer + the app's own api/ routes) under Miniflare, and this middleware
6
+ * proxies `/api/*` to it with a synthetic session cookie attached. The
7
+ * session gate, same-origin check, and role policy all execute exactly as
8
+ * deployed; the browser just never sees a login page.
9
+ *
10
+ * The one exception is `GET /api/dash/game`: deployed, the worker fetches
11
+ * the game from the platform — locally there is no platform, so the plugin
12
+ * serves it from playcademy.config.
13
+ *
14
+ * The sealed-page proxy is the inverse: it forwards navigations WITHOUT a
15
+ * session, so the worker serves its login/invite/reset pages on this
16
+ * origin — see createSealedPageProxy.
17
+ */
18
+ import type { IncomingMessage, ServerResponse } from 'node:http';
19
+ import type { PlaycademyDashboardLocalGameInfo } from 'playcademy/utils';
20
+ import type { DashboardUserRole } from '@playcademy/constants';
21
+ export declare function json(res: ServerResponse, status: number, body: unknown): void;
22
+ export interface DashboardProxyOptions {
23
+ /** Base URL of the local dashboard worker */
24
+ workerUrl: string;
25
+ /** Mint a session cookie for the current role */
26
+ mintCookie: (role: DashboardUserRole) => Promise<string>;
27
+ /** Read the current role (toggled at runtime via hotkey) */
28
+ currentRole: () => DashboardUserRole;
29
+ /**
30
+ * Local stand-in for the platform-backed /api/dash/game endpoint —
31
+ * a getter so config reloads serve fresh data.
32
+ */
33
+ localGame: () => PlaycademyDashboardLocalGameInfo;
34
+ /** Injectable for tests */
35
+ fetchImpl?: typeof fetch;
36
+ }
37
+ /**
38
+ * Connect handler proxying `/api/*` to the local dashboard worker with the
39
+ * synthetic session attached. Mount at '/api'; uses `originalUrl` so the
40
+ * full path reaches the worker regardless of Connect's prefix stripping.
41
+ */
42
+ export declare function createDashboardApiProxy(options: DashboardProxyOptions): (req: IncomingMessage & {
43
+ originalUrl?: string;
44
+ }, res: ServerResponse) => Promise<void>;
45
+ /**
46
+ * Dev-only door to the login screen. Deployed, the login page appears at
47
+ * any path when signed out — locally the API proxy keeps the browser
48
+ * permanently signed in, so the login state needs one explicit path. The
49
+ * `__` prefix keeps it out of any SPA route space.
50
+ */
51
+ export declare const DASHBOARD_LOGIN_PREVIEW_PATH = "/__login";
52
+ export interface SealedPageProxyOptions {
53
+ /** Base URL of the local dashboard worker */
54
+ workerUrl: string;
55
+ /** Injectable for tests */
56
+ fetchImpl?: typeof fetch;
57
+ }
58
+ /**
59
+ * Connect handler serving the worker's sealed pages on the dev origin.
60
+ *
61
+ * Deployed, `/invite/<token>` and `/reset/<token>` are runtime-reserved:
62
+ * the worker intercepts them before any SPA byte is served. Mounting this
63
+ * on the same paths gives local dev that exact behavior — a pasted invite
64
+ * link renders the real themed credential page instead of falling through
65
+ * to the SPA. Requests are forwarded WITHOUT a session cookie, which is
66
+ * precisely what makes the worker serve the sealed page.
67
+ *
68
+ * Navigations only: non-GET/HEAD falls through to the next middleware.
69
+ */
70
+ export declare function createSealedPageProxy(options: SealedPageProxyOptions): (req: IncomingMessage & {
71
+ originalUrl?: string;
72
+ }, res: ServerResponse, next: (err?: unknown) => void) => Promise<void>;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Dashboard plugin variant
3
+ *
4
+ * A dashboard app is a plain SPA the platform serves behind its auth
5
+ * layer. In dev, this variant runs the real composed dashboard worker
6
+ * (auth layer + the app's api/ routes) under Miniflare with the game's
7
+ * local data, and proxies `/api/*` to it holding a synthetic session —
8
+ * see middleware.ts. Builds pass through Vite untouched, exactly what
9
+ * `dashboard deploy` expects to zip.
10
+ */
11
+ import type { Plugin } from 'vite';
12
+ import type { PlaycademyPluginOptions } from '../types/options';
13
+ export declare function createDashboardPlugin(options: PlaycademyPluginOptions): Plugin;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Shared harness for dashboard middleware tests: a Connect-style mount
3
+ * stack plus fake request/response objects shaped like Node's.
4
+ */
5
+ export interface FakeRequest {
6
+ method: string;
7
+ url: string;
8
+ originalUrl?: string;
9
+ headers: Record<string, string>;
10
+ [Symbol.asyncIterator](): AsyncIterator<Buffer>;
11
+ }
12
+ export declare function makeRequest(method: string, url: string, headers?: Record<string, string>, body?: string): FakeRequest;
13
+ export declare function makeResponse(): {
14
+ statusCode: number;
15
+ headers: Record<string, string | string[]>;
16
+ body: string;
17
+ ended: Promise<void>;
18
+ setHeader(name: string, value: string | string[]): void;
19
+ end(chunk?: unknown): void;
20
+ };
21
+ /**
22
+ * Connect-style middleware stack: layers match by mount-path prefix
23
+ * (segment-aware) in registration order, and the mount prefix is stripped
24
+ * from `url` while `originalUrl` keeps the full path — the behavior the
25
+ * real `server.middlewares` has, so tests exercise mounting for real
26
+ * instead of capturing a single handler.
27
+ */
28
+ export declare function makeStack(): {
29
+ use(path: string, handler: (req: unknown, res: unknown) => unknown): void;
30
+ dispatch(req: FakeRequest, res: ReturnType<typeof makeResponse>): Promise<boolean>;
31
+ };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * Playcademy Vite Plugin
3
3
  *
4
- * Entry point - exports plugin and types
4
+ * Entry point exports the plugin and its public options types.
5
+ * Internal manager/context types stay behind ./types for in-package use.
5
6
  */
6
7
  export { playcademy } from './plugin';
7
- export type * from './types';
8
+ export type * from './types/options';