@immediately-run/sdk 0.1.2 → 0.1.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 CHANGED
@@ -22,6 +22,16 @@ also reachable via subpaths (`@immediately-run/sdk/boot`, `@immediately-run/sdk/
22
22
  - `Include` (`components/Include`) — render another file's exported component inline.
23
23
  - `MDXComponents` (`Link`, …) — MDX component overrides.
24
24
  - `useMetadataQuery`, `useFileMetadata` (`hooks`) — query files by frontmatter metadata.
25
+ - `getAuthState`, `onAuthChange`, `useAuth` (`auth`) — read or subscribe to the user's
26
+ login / account state (`{ status, user: { login } }`). Poll with `getAuthState()`,
27
+ subscribe with `onAuthChange(listener)` (the listener is called immediately with the
28
+ current state), or use the `useAuth()` React hook.
29
+ - `getMounts`, `findMount`, `onMountsChange`, `useMounts`, `waitForMount` (`mounts`) —
30
+ read or subscribe to the filesystem mounts available to the sandbox (e.g. a
31
+ Firestore-backed store mounted at `/firestore` after sign-in). Poll with
32
+ `getMounts()` / `findMount({ type })`, subscribe with `onMountsChange(listener)` or
33
+ the `useMounts()` hook, or `await waitForMount({ type: 'firestore' })` before using a
34
+ mount. Access the files via the `fs` module at the mount's `path`.
25
35
  - routing helpers (`Router`, `SandboxRouter`, …).
26
36
  - `MDXProvider` — the MDX context provider used by transformed `.mdx` files.
27
37
  - `sandboxTypes` — shared TypeScript types for the sandbox runtime.
package/dist/auth.cjs ADDED
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var auth_exports = {};
20
+ __export(auth_exports, {
21
+ getAuthState: () => getAuthState,
22
+ onAuthChange: () => onAuthChange,
23
+ useAuth: () => useAuth
24
+ });
25
+ module.exports = __toCommonJS(auth_exports);
26
+ var import_react = require("react");
27
+ const authService = () => {
28
+ return module.evaluation.module.bundler.auth;
29
+ };
30
+ const getAuthState = () => authService().getState();
31
+ const onAuthChange = (listener) => {
32
+ const disposable = authService().onChange(listener);
33
+ return () => disposable.dispose();
34
+ };
35
+ const useAuth = () => {
36
+ const [state, setState] = (0, import_react.useState)(getAuthState);
37
+ (0, import_react.useEffect)(() => onAuthChange(setState), []);
38
+ return state;
39
+ };
40
+ // Annotate the CommonJS export names for ESM import in node:
41
+ 0 && (module.exports = {
42
+ getAuthState,
43
+ onAuthChange,
44
+ useAuth
45
+ });
46
+ //# sourceMappingURL=auth.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/auth.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\n/**\n * Login / account state of the immediately.run user, mirrored from the host\n * window into the sandbox.\n *\n * `status` is `'unknown'` until the host has reported a value (use it to\n * distinguish \"still loading\" from a confirmed signed-out session).\n */\nexport type AuthStatus = 'unknown' | 'signed-in' | 'signed-out';\n\nexport interface SandboxUser {\n /** GitHub login (handle) of the signed-in user. */\n login: string;\n}\n\nexport interface AuthState {\n status: AuthStatus;\n user: SandboxUser | null;\n}\n\ninterface AuthService {\n getState(): AuthState;\n onChange(listener: (state: AuthState) => void): { dispose(): void };\n}\n\n// `module.evaluation.module.bundler` is the sandbox bundler injected into the\n// evaluation context (same path the other SDK helpers reach for `messageBus`).\nconst authService = (): AuthService => {\n // @ts-ignore - injected by the sandbox runtime\n return module.evaluation.module.bundler.auth;\n};\n\n/**\n * Returns the current login / account state. Poll this whenever you need a\n * one-off read; use {@link onAuthChange} or {@link useAuth} to react to changes.\n */\nexport const getAuthState = (): AuthState => authService().getState();\n\n/**\n * Subscribe to login / logout changes. The listener is invoked immediately with\n * the current state, then again on every change. Returns an unsubscribe fn.\n */\nexport const onAuthChange = (listener: (state: AuthState) => void): (() => void) => {\n const disposable = authService().onChange(listener);\n return () => disposable.dispose();\n};\n\n/**\n * React hook returning the current login / account state, re-rendering on\n * login / logout.\n */\nexport const useAuth = (): AuthState => {\n const [state, setState] = useState<AuthState>(getAuthState);\n useEffect(() => onAuthChange(setState), []);\n return state;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAoC;AA4BpC,MAAM,cAAc,MAAmB;AAErC,SAAO,OAAO,WAAW,OAAO,QAAQ;AAC1C;AAMO,MAAM,eAAe,MAAiB,YAAY,EAAE,SAAS;AAM7D,MAAM,eAAe,CAAC,aAAuD;AAClF,QAAM,aAAa,YAAY,EAAE,SAAS,QAAQ;AAClD,SAAO,MAAM,WAAW,QAAQ;AAClC;AAMO,MAAM,UAAU,MAAiB;AACtC,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAoB,YAAY;AAC1D,8BAAU,MAAM,aAAa,QAAQ,GAAG,CAAC,CAAC;AAC1C,SAAO;AACT;","names":[]}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Login / account state of the immediately.run user, mirrored from the host
3
+ * window into the sandbox.
4
+ *
5
+ * `status` is `'unknown'` until the host has reported a value (use it to
6
+ * distinguish "still loading" from a confirmed signed-out session).
7
+ */
8
+ type AuthStatus = 'unknown' | 'signed-in' | 'signed-out';
9
+ interface SandboxUser {
10
+ /** GitHub login (handle) of the signed-in user. */
11
+ login: string;
12
+ }
13
+ interface AuthState {
14
+ status: AuthStatus;
15
+ user: SandboxUser | null;
16
+ }
17
+ /**
18
+ * Returns the current login / account state. Poll this whenever you need a
19
+ * one-off read; use {@link onAuthChange} or {@link useAuth} to react to changes.
20
+ */
21
+ declare const getAuthState: () => AuthState;
22
+ /**
23
+ * Subscribe to login / logout changes. The listener is invoked immediately with
24
+ * the current state, then again on every change. Returns an unsubscribe fn.
25
+ */
26
+ declare const onAuthChange: (listener: (state: AuthState) => void) => (() => void);
27
+ /**
28
+ * React hook returning the current login / account state, re-rendering on
29
+ * login / logout.
30
+ */
31
+ declare const useAuth: () => AuthState;
32
+
33
+ export { type AuthState, type AuthStatus, type SandboxUser, getAuthState, onAuthChange, useAuth };
package/dist/auth.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Login / account state of the immediately.run user, mirrored from the host
3
+ * window into the sandbox.
4
+ *
5
+ * `status` is `'unknown'` until the host has reported a value (use it to
6
+ * distinguish "still loading" from a confirmed signed-out session).
7
+ */
8
+ type AuthStatus = 'unknown' | 'signed-in' | 'signed-out';
9
+ interface SandboxUser {
10
+ /** GitHub login (handle) of the signed-in user. */
11
+ login: string;
12
+ }
13
+ interface AuthState {
14
+ status: AuthStatus;
15
+ user: SandboxUser | null;
16
+ }
17
+ /**
18
+ * Returns the current login / account state. Poll this whenever you need a
19
+ * one-off read; use {@link onAuthChange} or {@link useAuth} to react to changes.
20
+ */
21
+ declare const getAuthState: () => AuthState;
22
+ /**
23
+ * Subscribe to login / logout changes. The listener is invoked immediately with
24
+ * the current state, then again on every change. Returns an unsubscribe fn.
25
+ */
26
+ declare const onAuthChange: (listener: (state: AuthState) => void) => (() => void);
27
+ /**
28
+ * React hook returning the current login / account state, re-rendering on
29
+ * login / logout.
30
+ */
31
+ declare const useAuth: () => AuthState;
32
+
33
+ export { type AuthState, type AuthStatus, type SandboxUser, getAuthState, onAuthChange, useAuth };
package/dist/auth.js ADDED
@@ -0,0 +1,20 @@
1
+ import { useEffect, useState } from "react";
2
+ const authService = () => {
3
+ return module.evaluation.module.bundler.auth;
4
+ };
5
+ const getAuthState = () => authService().getState();
6
+ const onAuthChange = (listener) => {
7
+ const disposable = authService().onChange(listener);
8
+ return () => disposable.dispose();
9
+ };
10
+ const useAuth = () => {
11
+ const [state, setState] = useState(getAuthState);
12
+ useEffect(() => onAuthChange(setState), []);
13
+ return state;
14
+ };
15
+ export {
16
+ getAuthState,
17
+ onAuthChange,
18
+ useAuth
19
+ };
20
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/auth.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\n/**\n * Login / account state of the immediately.run user, mirrored from the host\n * window into the sandbox.\n *\n * `status` is `'unknown'` until the host has reported a value (use it to\n * distinguish \"still loading\" from a confirmed signed-out session).\n */\nexport type AuthStatus = 'unknown' | 'signed-in' | 'signed-out';\n\nexport interface SandboxUser {\n /** GitHub login (handle) of the signed-in user. */\n login: string;\n}\n\nexport interface AuthState {\n status: AuthStatus;\n user: SandboxUser | null;\n}\n\ninterface AuthService {\n getState(): AuthState;\n onChange(listener: (state: AuthState) => void): { dispose(): void };\n}\n\n// `module.evaluation.module.bundler` is the sandbox bundler injected into the\n// evaluation context (same path the other SDK helpers reach for `messageBus`).\nconst authService = (): AuthService => {\n // @ts-ignore - injected by the sandbox runtime\n return module.evaluation.module.bundler.auth;\n};\n\n/**\n * Returns the current login / account state. Poll this whenever you need a\n * one-off read; use {@link onAuthChange} or {@link useAuth} to react to changes.\n */\nexport const getAuthState = (): AuthState => authService().getState();\n\n/**\n * Subscribe to login / logout changes. The listener is invoked immediately with\n * the current state, then again on every change. Returns an unsubscribe fn.\n */\nexport const onAuthChange = (listener: (state: AuthState) => void): (() => void) => {\n const disposable = authService().onChange(listener);\n return () => disposable.dispose();\n};\n\n/**\n * React hook returning the current login / account state, re-rendering on\n * login / logout.\n */\nexport const useAuth = (): AuthState => {\n const [state, setState] = useState<AuthState>(getAuthState);\n useEffect(() => onAuthChange(setState), []);\n return state;\n};\n"],"mappings":"AAAA,SAAS,WAAW,gBAAgB;AA4BpC,MAAM,cAAc,MAAmB;AAErC,SAAO,OAAO,WAAW,OAAO,QAAQ;AAC1C;AAMO,MAAM,eAAe,MAAiB,YAAY,EAAE,SAAS;AAM7D,MAAM,eAAe,CAAC,aAAuD;AAClF,QAAM,aAAa,YAAY,EAAE,SAAS,QAAQ;AAClD,SAAO,MAAM,WAAW,QAAQ;AAClC;AAMO,MAAM,UAAU,MAAiB;AACtC,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAoB,YAAY;AAC1D,YAAU,MAAM,aAAa,QAAQ,GAAG,CAAC,CAAC;AAC1C,SAAO;AACT;","names":[]}
@@ -24,6 +24,7 @@ module.exports = __toCommonJS(FileRouter_exports);
24
24
  var import_jsx_runtime = require("react/jsx-runtime");
25
25
  var import_react = require("react");
26
26
  var import_TinkerableContext = require("../TinkerableContext");
27
+ var import_urlUtils = require("../urlUtils");
27
28
  var import_defaults = require("./defaults");
28
29
  var import_Include = require("./Include");
29
30
  const FileRouter = ({
@@ -39,7 +40,7 @@ const FileRouter = ({
39
40
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
40
41
  import_Include.Include,
41
42
  {
42
- filename,
43
+ filename: (0, import_urlUtils.underAppRoot)(filename),
43
44
  LoadingComponent,
44
45
  ErrorComponent,
45
46
  baseModule: module
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/FileRouter.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useContext } from 'react';\n\nimport { TinkerableContext } from '../TinkerableContext';\nimport { defaultErrorComponent, defaultLoadingComponent } from './defaults';\nimport { Include } from './Include';\n\nexport const FileRouter: FC = ({\n LoadingComponent = defaultLoadingComponent,\n ErrorComponent = defaultErrorComponent,\n}: {\n LoadingComponent?: typeof defaultLoadingComponent;\n ErrorComponent?: typeof defaultErrorComponent;\n} = {}) => {\n const { navigationState: { pathParameters, sandboxPath } } = useContext(TinkerableContext);\n const filename = pathParameters?.filename;\n if (!filename) {\n return <ErrorComponent error={new Error(`No filename could be extracted from ${sandboxPath}`)} resetErrorBoundary={() => {}}/>;\n }\n return <Include\n filename={filename}\n LoadingComponent={LoadingComponent}\n ErrorComponent={ErrorComponent}\n // @ts-ignore\n baseModule={module}\n />\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBW;AAhBX,mBAA2B;AAE3B,+BAAkC;AAClC,sBAA+D;AAC/D,qBAAwB;AAEjB,MAAM,aAAiB,CAAC;AAAA,EAC7B,mBAAmB;AAAA,EACnB,iBAAiB;AACnB,IAGI,CAAC,MAAM;AACT,QAAM,EAAE,iBAAiB,EAAE,gBAAgB,YAAY,EAAE,QAAI,yBAAW,0CAAiB;AACzF,QAAM,WAAW,gBAAgB;AACjC,MAAI,CAAC,UAAU;AACb,WAAO,4CAAC,kBAAe,OAAO,IAAI,MAAM,uCAAuC,WAAW,EAAE,GAAG,oBAAoB,MAAM;AAAA,IAAC,GAAE;AAAA,EAC9H;AACA,SAAO;AAAA,IAAC;AAAA;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MAEA,YAAY;AAAA;AAAA,EACd;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/components/FileRouter.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useContext } from 'react';\n\nimport { TinkerableContext } from '../TinkerableContext';\nimport { underAppRoot } from '../urlUtils';\nimport { defaultErrorComponent, defaultLoadingComponent } from './defaults';\nimport { Include } from './Include';\n\nexport const FileRouter: FC = ({\n LoadingComponent = defaultLoadingComponent,\n ErrorComponent = defaultErrorComponent,\n}: {\n LoadingComponent?: typeof defaultLoadingComponent;\n ErrorComponent?: typeof defaultErrorComponent;\n} = {}) => {\n const { navigationState: { pathParameters, sandboxPath } } = useContext(TinkerableContext);\n const filename = pathParameters?.filename;\n if (!filename) {\n return <ErrorComponent error={new Error(`No filename could be extracted from ${sandboxPath}`)} resetErrorBoundary={() => {}}/>;\n }\n // URL subpaths are repo-relative; the sandbox fs is rooted at `/` with the\n // repo mounted at `APP_ROOT`, so anchor the file path there before resolving.\n return <Include\n filename={underAppRoot(filename)}\n LoadingComponent={LoadingComponent}\n ErrorComponent={ErrorComponent}\n // @ts-ignore\n baseModule={module}\n />\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBW;AAjBX,mBAA2B;AAE3B,+BAAkC;AAClC,sBAA6B;AAC7B,sBAA+D;AAC/D,qBAAwB;AAEjB,MAAM,aAAiB,CAAC;AAAA,EAC7B,mBAAmB;AAAA,EACnB,iBAAiB;AACnB,IAGI,CAAC,MAAM;AACT,QAAM,EAAE,iBAAiB,EAAE,gBAAgB,YAAY,EAAE,QAAI,yBAAW,0CAAiB;AACzF,QAAM,WAAW,gBAAgB;AACjC,MAAI,CAAC,UAAU;AACb,WAAO,4CAAC,kBAAe,OAAO,IAAI,MAAM,uCAAuC,WAAW,EAAE,GAAG,oBAAoB,MAAM;AAAA,IAAC,GAAE;AAAA,EAC9H;AAGA,SAAO;AAAA,IAAC;AAAA;AAAA,MACN,cAAU,8BAAa,QAAQ;AAAA,MAC/B;AAAA,MACA;AAAA,MAEA,YAAY;AAAA;AAAA,EACd;AACF;","names":[]}
@@ -1,6 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { useContext } from "react";
3
3
  import { TinkerableContext } from "../TinkerableContext";
4
+ import { underAppRoot } from "../urlUtils";
4
5
  import { defaultErrorComponent, defaultLoadingComponent } from "./defaults";
5
6
  import { Include } from "./Include";
6
7
  const FileRouter = ({
@@ -16,7 +17,7 @@ const FileRouter = ({
16
17
  return /* @__PURE__ */ jsx(
17
18
  Include,
18
19
  {
19
- filename,
20
+ filename: underAppRoot(filename),
20
21
  LoadingComponent,
21
22
  ErrorComponent,
22
23
  baseModule: module
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/FileRouter.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useContext } from 'react';\n\nimport { TinkerableContext } from '../TinkerableContext';\nimport { defaultErrorComponent, defaultLoadingComponent } from './defaults';\nimport { Include } from './Include';\n\nexport const FileRouter: FC = ({\n LoadingComponent = defaultLoadingComponent,\n ErrorComponent = defaultErrorComponent,\n}: {\n LoadingComponent?: typeof defaultLoadingComponent;\n ErrorComponent?: typeof defaultErrorComponent;\n} = {}) => {\n const { navigationState: { pathParameters, sandboxPath } } = useContext(TinkerableContext);\n const filename = pathParameters?.filename;\n if (!filename) {\n return <ErrorComponent error={new Error(`No filename could be extracted from ${sandboxPath}`)} resetErrorBoundary={() => {}}/>;\n }\n return <Include\n filename={filename}\n LoadingComponent={LoadingComponent}\n ErrorComponent={ErrorComponent}\n // @ts-ignore\n baseModule={module}\n />\n};\n"],"mappings":"AAiBW;AAhBX,SAAS,kBAAkB;AAE3B,SAAS,yBAAyB;AAClC,SAAS,uBAAuB,+BAA+B;AAC/D,SAAS,eAAe;AAEjB,MAAM,aAAiB,CAAC;AAAA,EAC7B,mBAAmB;AAAA,EACnB,iBAAiB;AACnB,IAGI,CAAC,MAAM;AACT,QAAM,EAAE,iBAAiB,EAAE,gBAAgB,YAAY,EAAE,IAAI,WAAW,iBAAiB;AACzF,QAAM,WAAW,gBAAgB;AACjC,MAAI,CAAC,UAAU;AACb,WAAO,oBAAC,kBAAe,OAAO,IAAI,MAAM,uCAAuC,WAAW,EAAE,GAAG,oBAAoB,MAAM;AAAA,IAAC,GAAE;AAAA,EAC9H;AACA,SAAO;AAAA,IAAC;AAAA;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MAEA,YAAY;AAAA;AAAA,EACd;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/components/FileRouter.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useContext } from 'react';\n\nimport { TinkerableContext } from '../TinkerableContext';\nimport { underAppRoot } from '../urlUtils';\nimport { defaultErrorComponent, defaultLoadingComponent } from './defaults';\nimport { Include } from './Include';\n\nexport const FileRouter: FC = ({\n LoadingComponent = defaultLoadingComponent,\n ErrorComponent = defaultErrorComponent,\n}: {\n LoadingComponent?: typeof defaultLoadingComponent;\n ErrorComponent?: typeof defaultErrorComponent;\n} = {}) => {\n const { navigationState: { pathParameters, sandboxPath } } = useContext(TinkerableContext);\n const filename = pathParameters?.filename;\n if (!filename) {\n return <ErrorComponent error={new Error(`No filename could be extracted from ${sandboxPath}`)} resetErrorBoundary={() => {}}/>;\n }\n // URL subpaths are repo-relative; the sandbox fs is rooted at `/` with the\n // repo mounted at `APP_ROOT`, so anchor the file path there before resolving.\n return <Include\n filename={underAppRoot(filename)}\n LoadingComponent={LoadingComponent}\n ErrorComponent={ErrorComponent}\n // @ts-ignore\n baseModule={module}\n />\n};\n"],"mappings":"AAkBW;AAjBX,SAAS,kBAAkB;AAE3B,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB,+BAA+B;AAC/D,SAAS,eAAe;AAEjB,MAAM,aAAiB,CAAC;AAAA,EAC7B,mBAAmB;AAAA,EACnB,iBAAiB;AACnB,IAGI,CAAC,MAAM;AACT,QAAM,EAAE,iBAAiB,EAAE,gBAAgB,YAAY,EAAE,IAAI,WAAW,iBAAiB;AACzF,QAAM,WAAW,gBAAgB;AACjC,MAAI,CAAC,UAAU;AACb,WAAO,oBAAC,kBAAe,OAAO,IAAI,MAAM,uCAAuC,WAAW,EAAE,GAAG,oBAAoB,MAAM;AAAA,IAAC,GAAE;AAAA,EAC9H;AAGA,SAAO;AAAA,IAAC;AAAA;AAAA,MACN,UAAU,aAAa,QAAQ;AAAA,MAC/B;AAAA,MACA;AAAA,MAEA,YAAY;AAAA;AAAA,EACd;AACF;","names":[]}
@@ -29,15 +29,10 @@ var import_react_error_boundary = require("react-error-boundary");
29
29
  var import_routing = require("../routing");
30
30
  var import_urlUtils = require("../urlUtils");
31
31
  var import_defaults = require("./defaults");
32
- const directories = ["/", "/src/"];
33
- const basenames = ["App", "landing", "main", "README"];
34
- const extensions = [".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx", ".mdx", ".md"];
35
- const candidates = directories.flatMap(
36
- (dir) => basenames.flatMap((basename) => extensions.map((ext) => `${dir}${basename}${ext}`))
37
- );
32
+ const candidates = ["/src/App.tsx", "/src/App.ts", "/src/App.js", "/App.tsx", "/App.ts", "/App.js", "/README.md", "/README.mdx", "/README.html"];
38
33
  const fileExists = async (path) => {
39
34
  const bundler = module.evaluation.module.bundler;
40
- const exists = await bundler.fs.isFile.async(path);
35
+ const exists = await bundler.fs.isFile.async((0, import_urlUtils.underAppRoot)(path));
41
36
  return [path, exists];
42
37
  };
43
38
  const MainContentRedirect = ({ filename }) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/MainContent.tsx"],"sourcesContent":["import { Suspense, use, useMemo } from 'react';\nimport { ErrorBoundary } from 'react-error-boundary';\nimport { navigate, useTinkerableLink } from '../routing';\nimport { FILES_PREFIX } from '../urlUtils';\n\nimport { defaultErrorComponent, defaultLoadingComponent } from './defaults';\n\nconst directories = ['/', '/src/'];\nconst basenames = ['App', 'landing', 'main', 'README'];\nconst extensions = ['.js', '.jsx', '.mjs', '.cjs', '.ts', '.tsx', '.mdx', '.md'];\nconst candidates = directories.flatMap((dir) =>\n basenames.flatMap((basename) => extensions.map((ext) => `${dir}${basename}${ext}`))\n);\n\nconst fileExists = async (path: string): Promise<[string, boolean]> => {\n // @ts-ignore\n const bundler = module.evaluation.module.bundler;\n const exists = await bundler.fs.isFile.async(path);\n return [path, exists];\n};\n\nexport const MainContentRedirect = ({filename}:{filename:string}) => {\n const url = useTinkerableLink(filename);\n navigate(url);\n return <>Redirecting to {filename}</>;\n}\n\nexport const MainContentInner = ({\n candidatesExistPromise,\n}: {\n candidatesExistPromise: Promise<[string, boolean][]>;\n}) => {\n const candidatesExist = use(candidatesExistPromise);\n const filename = candidatesExist.find(([_, exists]) => exists)?.[0];\n if (!filename) {\n // todo: show file list\n throw new Error(`No main content file present`);\n }\n return <MainContentRedirect filename={FILES_PREFIX + filename}/>;\n};\n\nexport const MainContent = ({\n LoadingComponent = defaultLoadingComponent,\n ErrorComponent = defaultErrorComponent,\n}: {\n LoadingComponent?: typeof defaultLoadingComponent;\n ErrorComponent?: typeof defaultErrorComponent;\n} = {}) => {\n // TODO: when to invalidate?\n const candidatesExistPromise = useMemo(() => Promise.all(candidates.map(fileExists)), []);\n return (\n <ErrorBoundary fallbackRender={ErrorComponent}>\n <Suspense fallback={<LoadingComponent />}>\n <MainContentInner candidatesExistPromise={candidatesExistPromise} />\n </Suspense>\n </ErrorBoundary>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBS;AAxBT,mBAAuC;AACvC,kCAA8B;AAC9B,qBAA4C;AAC5C,sBAA6B;AAE7B,sBAA+D;AAE/D,MAAM,cAAc,CAAC,KAAK,OAAO;AACjC,MAAM,YAAY,CAAC,OAAO,WAAW,QAAQ,QAAQ;AACrD,MAAM,aAAa,CAAC,OAAO,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,QAAQ,KAAK;AAC/E,MAAM,aAAa,YAAY;AAAA,EAAQ,CAAC,QACtC,UAAU,QAAQ,CAAC,aAAa,WAAW,IAAI,CAAC,QAAQ,GAAG,GAAG,GAAG,QAAQ,GAAG,GAAG,EAAE,CAAC;AACpF;AAEA,MAAM,aAAa,OAAO,SAA6C;AAErE,QAAM,UAAU,OAAO,WAAW,OAAO;AACzC,QAAM,SAAS,MAAM,QAAQ,GAAG,OAAO,MAAM,IAAI;AACjD,SAAO,CAAC,MAAM,MAAM;AACtB;AAEO,MAAM,sBAAsB,CAAC,EAAC,SAAQ,MAAwB;AACnE,QAAM,UAAM,kCAAkB,QAAQ;AACtC,+BAAS,GAAG;AACZ,SAAO,4EAAE;AAAA;AAAA,IAAgB;AAAA,KAAS;AACpC;AAEO,MAAM,mBAAmB,CAAC;AAAA,EAC/B;AACF,MAEM;AACJ,QAAM,sBAAkB,kBAAI,sBAAsB;AAClD,QAAM,WAAW,gBAAgB,KAAK,CAAC,CAAC,GAAG,MAAM,MAAM,MAAM,IAAI,CAAC;AAClE,MAAI,CAAC,UAAU;AAEb,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AACA,SAAO,4CAAC,uBAAoB,UAAU,+BAAe,UAAS;AAChE;AAEO,MAAM,cAAc,CAAC;AAAA,EAC1B,mBAAmB;AAAA,EACnB,iBAAiB;AACnB,IAGI,CAAC,MAAM;AAET,QAAM,6BAAyB,sBAAQ,MAAM,QAAQ,IAAI,WAAW,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AACxF,SACE,4CAAC,6CAAc,gBAAgB,gBAC7B,sDAAC,yBAAS,UAAU,4CAAC,oBAAiB,GACpC,sDAAC,oBAAiB,wBAAgD,GACpE,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/MainContent.tsx"],"sourcesContent":["import { Suspense, use, useMemo } from 'react';\nimport { ErrorBoundary } from 'react-error-boundary';\nimport { navigate, useTinkerableLink } from '../routing';\nimport { FILES_PREFIX, underAppRoot } from '../urlUtils';\n\nimport { defaultErrorComponent, defaultLoadingComponent } from './defaults';\n\n// Repo-relative candidate paths. These are kept repo-relative because the\n// returned path is reused below to build the redirect URL (which is anchored to\n// `/app` by the file router); only the filesystem existence check is resolved\n// under `APP_ROOT`, since `bundler.fs` is rooted at `/`.\nconst candidates = ['/src/App.tsx', '/src/App.ts', '/src/App.js', '/App.tsx', '/App.ts', '/App.js', '/README.md', '/README.mdx', '/README.html'];\n\nconst fileExists = async (path: string): Promise<[string, boolean]> => {\n // @ts-ignore\n const bundler = module.evaluation.module.bundler;\n const exists = await bundler.fs.isFile.async(underAppRoot(path));\n return [path, exists];\n};\n\nexport const MainContentRedirect = ({filename}:{filename:string}) => {\n const url = useTinkerableLink(filename);\n navigate(url);\n return <>Redirecting to {filename}</>;\n}\n\nexport const MainContentInner = ({\n candidatesExistPromise,\n}: {\n candidatesExistPromise: Promise<[string, boolean][]>;\n}) => {\n const candidatesExist = use(candidatesExistPromise);\n const filename = candidatesExist.find(([_, exists]) => exists)?.[0];\n if (!filename) {\n // todo: show file list\n throw new Error(`No main content file present`);\n }\n return <MainContentRedirect filename={FILES_PREFIX + filename}/>;\n};\n\nexport const MainContent = ({\n LoadingComponent = defaultLoadingComponent,\n ErrorComponent = defaultErrorComponent,\n}: {\n LoadingComponent?: typeof defaultLoadingComponent;\n ErrorComponent?: typeof defaultErrorComponent;\n} = {}) => {\n // TODO: when to invalidate?\n const candidatesExistPromise = useMemo(() => Promise.all(candidates.map(fileExists)), []);\n return (\n <ErrorBoundary fallbackRender={ErrorComponent}>\n <Suspense fallback={<LoadingComponent />}>\n <MainContentInner candidatesExistPromise={candidatesExistPromise} />\n </Suspense>\n </ErrorBoundary>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBS;AAvBT,mBAAuC;AACvC,kCAA8B;AAC9B,qBAA4C;AAC5C,sBAA2C;AAE3C,sBAA+D;AAM/D,MAAM,aAAa,CAAC,gBAAgB,eAAe,eAAe,YAAY,WAAW,WAAW,cAAc,eAAe,cAAc;AAE/I,MAAM,aAAa,OAAO,SAA6C;AAErE,QAAM,UAAU,OAAO,WAAW,OAAO;AACzC,QAAM,SAAS,MAAM,QAAQ,GAAG,OAAO,UAAM,8BAAa,IAAI,CAAC;AAC/D,SAAO,CAAC,MAAM,MAAM;AACtB;AAEO,MAAM,sBAAsB,CAAC,EAAC,SAAQ,MAAwB;AACnE,QAAM,UAAM,kCAAkB,QAAQ;AACtC,+BAAS,GAAG;AACZ,SAAO,4EAAE;AAAA;AAAA,IAAgB;AAAA,KAAS;AACpC;AAEO,MAAM,mBAAmB,CAAC;AAAA,EAC/B;AACF,MAEM;AACJ,QAAM,sBAAkB,kBAAI,sBAAsB;AAClD,QAAM,WAAW,gBAAgB,KAAK,CAAC,CAAC,GAAG,MAAM,MAAM,MAAM,IAAI,CAAC;AAClE,MAAI,CAAC,UAAU;AAEb,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AACA,SAAO,4CAAC,uBAAoB,UAAU,+BAAe,UAAS;AAChE;AAEO,MAAM,cAAc,CAAC;AAAA,EAC1B,mBAAmB;AAAA,EACnB,iBAAiB;AACnB,IAGI,CAAC,MAAM;AAET,QAAM,6BAAyB,sBAAQ,MAAM,QAAQ,IAAI,WAAW,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AACxF,SACE,4CAAC,6CAAc,gBAAgB,gBAC7B,sDAAC,yBAAS,UAAU,4CAAC,oBAAiB,GACpC,sDAAC,oBAAiB,wBAAgD,GACpE,GACF;AAEJ;","names":[]}
@@ -2,17 +2,12 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Suspense, use, useMemo } from "react";
3
3
  import { ErrorBoundary } from "react-error-boundary";
4
4
  import { navigate, useTinkerableLink } from "../routing";
5
- import { FILES_PREFIX } from "../urlUtils";
5
+ import { FILES_PREFIX, underAppRoot } from "../urlUtils";
6
6
  import { defaultErrorComponent, defaultLoadingComponent } from "./defaults";
7
- const directories = ["/", "/src/"];
8
- const basenames = ["App", "landing", "main", "README"];
9
- const extensions = [".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx", ".mdx", ".md"];
10
- const candidates = directories.flatMap(
11
- (dir) => basenames.flatMap((basename) => extensions.map((ext) => `${dir}${basename}${ext}`))
12
- );
7
+ const candidates = ["/src/App.tsx", "/src/App.ts", "/src/App.js", "/App.tsx", "/App.ts", "/App.js", "/README.md", "/README.mdx", "/README.html"];
13
8
  const fileExists = async (path) => {
14
9
  const bundler = module.evaluation.module.bundler;
15
- const exists = await bundler.fs.isFile.async(path);
10
+ const exists = await bundler.fs.isFile.async(underAppRoot(path));
16
11
  return [path, exists];
17
12
  };
18
13
  const MainContentRedirect = ({ filename }) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/MainContent.tsx"],"sourcesContent":["import { Suspense, use, useMemo } from 'react';\nimport { ErrorBoundary } from 'react-error-boundary';\nimport { navigate, useTinkerableLink } from '../routing';\nimport { FILES_PREFIX } from '../urlUtils';\n\nimport { defaultErrorComponent, defaultLoadingComponent } from './defaults';\n\nconst directories = ['/', '/src/'];\nconst basenames = ['App', 'landing', 'main', 'README'];\nconst extensions = ['.js', '.jsx', '.mjs', '.cjs', '.ts', '.tsx', '.mdx', '.md'];\nconst candidates = directories.flatMap((dir) =>\n basenames.flatMap((basename) => extensions.map((ext) => `${dir}${basename}${ext}`))\n);\n\nconst fileExists = async (path: string): Promise<[string, boolean]> => {\n // @ts-ignore\n const bundler = module.evaluation.module.bundler;\n const exists = await bundler.fs.isFile.async(path);\n return [path, exists];\n};\n\nexport const MainContentRedirect = ({filename}:{filename:string}) => {\n const url = useTinkerableLink(filename);\n navigate(url);\n return <>Redirecting to {filename}</>;\n}\n\nexport const MainContentInner = ({\n candidatesExistPromise,\n}: {\n candidatesExistPromise: Promise<[string, boolean][]>;\n}) => {\n const candidatesExist = use(candidatesExistPromise);\n const filename = candidatesExist.find(([_, exists]) => exists)?.[0];\n if (!filename) {\n // todo: show file list\n throw new Error(`No main content file present`);\n }\n return <MainContentRedirect filename={FILES_PREFIX + filename}/>;\n};\n\nexport const MainContent = ({\n LoadingComponent = defaultLoadingComponent,\n ErrorComponent = defaultErrorComponent,\n}: {\n LoadingComponent?: typeof defaultLoadingComponent;\n ErrorComponent?: typeof defaultErrorComponent;\n} = {}) => {\n // TODO: when to invalidate?\n const candidatesExistPromise = useMemo(() => Promise.all(candidates.map(fileExists)), []);\n return (\n <ErrorBoundary fallbackRender={ErrorComponent}>\n <Suspense fallback={<LoadingComponent />}>\n <MainContentInner candidatesExistPromise={candidatesExistPromise} />\n </Suspense>\n </ErrorBoundary>\n );\n};\n"],"mappings":"AAwBS,mBAcA,KAdA;AAxBT,SAAS,UAAU,KAAK,eAAe;AACvC,SAAS,qBAAqB;AAC9B,SAAS,UAAU,yBAAyB;AAC5C,SAAS,oBAAoB;AAE7B,SAAS,uBAAuB,+BAA+B;AAE/D,MAAM,cAAc,CAAC,KAAK,OAAO;AACjC,MAAM,YAAY,CAAC,OAAO,WAAW,QAAQ,QAAQ;AACrD,MAAM,aAAa,CAAC,OAAO,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,QAAQ,KAAK;AAC/E,MAAM,aAAa,YAAY;AAAA,EAAQ,CAAC,QACtC,UAAU,QAAQ,CAAC,aAAa,WAAW,IAAI,CAAC,QAAQ,GAAG,GAAG,GAAG,QAAQ,GAAG,GAAG,EAAE,CAAC;AACpF;AAEA,MAAM,aAAa,OAAO,SAA6C;AAErE,QAAM,UAAU,OAAO,WAAW,OAAO;AACzC,QAAM,SAAS,MAAM,QAAQ,GAAG,OAAO,MAAM,IAAI;AACjD,SAAO,CAAC,MAAM,MAAM;AACtB;AAEO,MAAM,sBAAsB,CAAC,EAAC,SAAQ,MAAwB;AACnE,QAAM,MAAM,kBAAkB,QAAQ;AACtC,WAAS,GAAG;AACZ,SAAO,iCAAE;AAAA;AAAA,IAAgB;AAAA,KAAS;AACpC;AAEO,MAAM,mBAAmB,CAAC;AAAA,EAC/B;AACF,MAEM;AACJ,QAAM,kBAAkB,IAAI,sBAAsB;AAClD,QAAM,WAAW,gBAAgB,KAAK,CAAC,CAAC,GAAG,MAAM,MAAM,MAAM,IAAI,CAAC;AAClE,MAAI,CAAC,UAAU;AAEb,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AACA,SAAO,oBAAC,uBAAoB,UAAU,eAAe,UAAS;AAChE;AAEO,MAAM,cAAc,CAAC;AAAA,EAC1B,mBAAmB;AAAA,EACnB,iBAAiB;AACnB,IAGI,CAAC,MAAM;AAET,QAAM,yBAAyB,QAAQ,MAAM,QAAQ,IAAI,WAAW,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AACxF,SACE,oBAAC,iBAAc,gBAAgB,gBAC7B,8BAAC,YAAS,UAAU,oBAAC,oBAAiB,GACpC,8BAAC,oBAAiB,wBAAgD,GACpE,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/MainContent.tsx"],"sourcesContent":["import { Suspense, use, useMemo } from 'react';\nimport { ErrorBoundary } from 'react-error-boundary';\nimport { navigate, useTinkerableLink } from '../routing';\nimport { FILES_PREFIX, underAppRoot } from '../urlUtils';\n\nimport { defaultErrorComponent, defaultLoadingComponent } from './defaults';\n\n// Repo-relative candidate paths. These are kept repo-relative because the\n// returned path is reused below to build the redirect URL (which is anchored to\n// `/app` by the file router); only the filesystem existence check is resolved\n// under `APP_ROOT`, since `bundler.fs` is rooted at `/`.\nconst candidates = ['/src/App.tsx', '/src/App.ts', '/src/App.js', '/App.tsx', '/App.ts', '/App.js', '/README.md', '/README.mdx', '/README.html'];\n\nconst fileExists = async (path: string): Promise<[string, boolean]> => {\n // @ts-ignore\n const bundler = module.evaluation.module.bundler;\n const exists = await bundler.fs.isFile.async(underAppRoot(path));\n return [path, exists];\n};\n\nexport const MainContentRedirect = ({filename}:{filename:string}) => {\n const url = useTinkerableLink(filename);\n navigate(url);\n return <>Redirecting to {filename}</>;\n}\n\nexport const MainContentInner = ({\n candidatesExistPromise,\n}: {\n candidatesExistPromise: Promise<[string, boolean][]>;\n}) => {\n const candidatesExist = use(candidatesExistPromise);\n const filename = candidatesExist.find(([_, exists]) => exists)?.[0];\n if (!filename) {\n // todo: show file list\n throw new Error(`No main content file present`);\n }\n return <MainContentRedirect filename={FILES_PREFIX + filename}/>;\n};\n\nexport const MainContent = ({\n LoadingComponent = defaultLoadingComponent,\n ErrorComponent = defaultErrorComponent,\n}: {\n LoadingComponent?: typeof defaultLoadingComponent;\n ErrorComponent?: typeof defaultErrorComponent;\n} = {}) => {\n // TODO: when to invalidate?\n const candidatesExistPromise = useMemo(() => Promise.all(candidates.map(fileExists)), []);\n return (\n <ErrorBoundary fallbackRender={ErrorComponent}>\n <Suspense fallback={<LoadingComponent />}>\n <MainContentInner candidatesExistPromise={candidatesExistPromise} />\n </Suspense>\n </ErrorBoundary>\n );\n};\n"],"mappings":"AAuBS,mBAcA,KAdA;AAvBT,SAAS,UAAU,KAAK,eAAe;AACvC,SAAS,qBAAqB;AAC9B,SAAS,UAAU,yBAAyB;AAC5C,SAAS,cAAc,oBAAoB;AAE3C,SAAS,uBAAuB,+BAA+B;AAM/D,MAAM,aAAa,CAAC,gBAAgB,eAAe,eAAe,YAAY,WAAW,WAAW,cAAc,eAAe,cAAc;AAE/I,MAAM,aAAa,OAAO,SAA6C;AAErE,QAAM,UAAU,OAAO,WAAW,OAAO;AACzC,QAAM,SAAS,MAAM,QAAQ,GAAG,OAAO,MAAM,aAAa,IAAI,CAAC;AAC/D,SAAO,CAAC,MAAM,MAAM;AACtB;AAEO,MAAM,sBAAsB,CAAC,EAAC,SAAQ,MAAwB;AACnE,QAAM,MAAM,kBAAkB,QAAQ;AACtC,WAAS,GAAG;AACZ,SAAO,iCAAE;AAAA;AAAA,IAAgB;AAAA,KAAS;AACpC;AAEO,MAAM,mBAAmB,CAAC;AAAA,EAC/B;AACF,MAEM;AACJ,QAAM,kBAAkB,IAAI,sBAAsB;AAClD,QAAM,WAAW,gBAAgB,KAAK,CAAC,CAAC,GAAG,MAAM,MAAM,MAAM,IAAI,CAAC;AAClE,MAAI,CAAC,UAAU;AAEb,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AACA,SAAO,oBAAC,uBAAoB,UAAU,eAAe,UAAS;AAChE;AAEO,MAAM,cAAc,CAAC;AAAA,EAC1B,mBAAmB;AAAA,EACnB,iBAAiB;AACnB,IAGI,CAAC,MAAM;AAET,QAAM,yBAAyB,QAAQ,MAAM,QAAQ,IAAI,WAAW,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AACxF,SACE,oBAAC,iBAAc,gBAAgB,gBAC7B,8BAAC,YAAS,UAAU,oBAAC,oBAAiB,GACpC,8BAAC,oBAAiB,wBAAgD,GACpE,GACF;AAEJ;","names":[]}
package/dist/index.cjs CHANGED
@@ -21,6 +21,8 @@ __reExport(index_exports, require("./boot"), module.exports);
21
21
  __reExport(index_exports, require("./components/Include"), module.exports);
22
22
  __reExport(index_exports, require("./components/MDXComponents"), module.exports);
23
23
  __reExport(index_exports, require("./hooks"), module.exports);
24
+ __reExport(index_exports, require("./auth"), module.exports);
25
+ __reExport(index_exports, require("./mounts"), module.exports);
24
26
  __reExport(index_exports, require("./sandboxTypes"), module.exports);
25
27
  // Annotate the CommonJS export names for ESM import in node:
26
28
  0 && (module.exports = {
@@ -30,6 +32,8 @@ __reExport(index_exports, require("./sandboxTypes"), module.exports);
30
32
  ...require("./components/Include"),
31
33
  ...require("./components/MDXComponents"),
32
34
  ...require("./hooks"),
35
+ ...require("./auth"),
36
+ ...require("./mounts"),
33
37
  ...require("./sandboxTypes")
34
38
  });
35
39
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./MDXProvider\";\nexport * from \"./routing\";\nexport * from \"./boot\";\nexport * from './components/Include';\nexport * from './components/MDXComponents';\nexport * from './hooks'\nexport * from './sandboxTypes';\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,0BAAc,0BAAd;AACA,0BAAc,sBADd;AAEA,0BAAc,mBAFd;AAGA,0BAAc,iCAHd;AAIA,0BAAc,uCAJd;AAKA,0BAAc,oBALd;AAMA,0BAAc,2BANd;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./MDXProvider\";\nexport * from \"./routing\";\nexport * from \"./boot\";\nexport * from './components/Include';\nexport * from './components/MDXComponents';\nexport * from './hooks'\nexport * from './auth';\nexport * from './mounts';\nexport * from './sandboxTypes';\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,0BAAc,0BAAd;AACA,0BAAc,sBADd;AAEA,0BAAc,mBAFd;AAGA,0BAAc,iCAHd;AAIA,0BAAc,uCAJd;AAKA,0BAAc,oBALd;AAMA,0BAAc,mBANd;AAOA,0BAAc,qBAPd;AAQA,0BAAc,2BARd;","names":[]}
package/dist/index.d.cts CHANGED
@@ -4,6 +4,8 @@ export { BootProps, DEFAULT_ROUTING_SPEC, TinkerableApp, boot } from './boot.cjs
4
4
  export { Include, RenderExportedComponent, RenderExportedComponentContext, RenderFileContextType } from './components/Include.cjs';
5
5
  export { DEFAULT_MDX_COMPONENTS, InternalLink, Link } from './components/MDXComponents.cjs';
6
6
  export { useFileMetadata, useMetadataQuery } from './hooks.cjs';
7
+ export { AuthState, AuthStatus, SandboxUser, getAuthState, onAuthChange, useAuth } from './auth.cjs';
8
+ export { MountQuery, SandboxMount, findMount, getMounts, onMountsChange, useMounts, waitForMount } from './mounts.cjs';
7
9
  export { EvaluationContext, FileQueryResult, FilesMetadata, Metadata, MetadataQueryFunction, MetadataQueryResult, ModuleExports } from './sandboxTypes.cjs';
8
10
  import 'react';
9
11
  import './TinkerableContext.cjs';
package/dist/index.d.ts CHANGED
@@ -4,6 +4,8 @@ export { BootProps, DEFAULT_ROUTING_SPEC, TinkerableApp, boot } from './boot.js'
4
4
  export { Include, RenderExportedComponent, RenderExportedComponentContext, RenderFileContextType } from './components/Include.js';
5
5
  export { DEFAULT_MDX_COMPONENTS, InternalLink, Link } from './components/MDXComponents.js';
6
6
  export { useFileMetadata, useMetadataQuery } from './hooks.js';
7
+ export { AuthState, AuthStatus, SandboxUser, getAuthState, onAuthChange, useAuth } from './auth.js';
8
+ export { MountQuery, SandboxMount, findMount, getMounts, onMountsChange, useMounts, waitForMount } from './mounts.js';
7
9
  export { EvaluationContext, FileQueryResult, FilesMetadata, Metadata, MetadataQueryFunction, MetadataQueryResult, ModuleExports } from './sandboxTypes.js';
8
10
  import 'react';
9
11
  import './TinkerableContext.js';
package/dist/index.js CHANGED
@@ -4,5 +4,7 @@ export * from "./boot";
4
4
  export * from "./components/Include";
5
5
  export * from "./components/MDXComponents";
6
6
  export * from "./hooks";
7
+ export * from "./auth";
8
+ export * from "./mounts";
7
9
  export * from "./sandboxTypes";
8
10
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./MDXProvider\";\nexport * from \"./routing\";\nexport * from \"./boot\";\nexport * from './components/Include';\nexport * from './components/MDXComponents';\nexport * from './hooks'\nexport * from './sandboxTypes';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./MDXProvider\";\nexport * from \"./routing\";\nexport * from \"./boot\";\nexport * from './components/Include';\nexport * from './components/MDXComponents';\nexport * from './hooks'\nexport * from './auth';\nexport * from './mounts';\nexport * from './sandboxTypes';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var mounts_exports = {};
20
+ __export(mounts_exports, {
21
+ findMount: () => findMount,
22
+ getMounts: () => getMounts,
23
+ onMountsChange: () => onMountsChange,
24
+ useMounts: () => useMounts,
25
+ waitForMount: () => waitForMount
26
+ });
27
+ module.exports = __toCommonJS(mounts_exports);
28
+ var import_react = require("react");
29
+ const mountService = () => {
30
+ return module.evaluation.module.bundler.mounts;
31
+ };
32
+ const matches = (mount, query) => (query.type === void 0 || mount.type === query.type) && (query.id === void 0 || mount.id === query.id) && (query.path === void 0 || mount.path === query.path);
33
+ const getMounts = () => mountService().getMounts();
34
+ const findMount = (query) => getMounts().find((m) => matches(m, query));
35
+ const onMountsChange = (listener) => {
36
+ const disposable = mountService().onChange(listener);
37
+ return () => disposable.dispose();
38
+ };
39
+ const waitForMount = (query) => new Promise((resolve) => {
40
+ const unsubscribe = onMountsChange((mounts) => {
41
+ const found = mounts.find((m) => matches(m, query));
42
+ if (found) {
43
+ Promise.resolve().then(unsubscribe);
44
+ resolve(found);
45
+ }
46
+ });
47
+ });
48
+ const useMounts = () => {
49
+ const [mounts, setMounts] = (0, import_react.useState)(getMounts);
50
+ (0, import_react.useEffect)(() => onMountsChange(setMounts), []);
51
+ return mounts;
52
+ };
53
+ // Annotate the CommonJS export names for ESM import in node:
54
+ 0 && (module.exports = {
55
+ findMount,
56
+ getMounts,
57
+ onMountsChange,
58
+ useMounts,
59
+ waitForMount
60
+ });
61
+ //# sourceMappingURL=mounts.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mounts.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\n/**\n * A filesystem mount available to the sandbox, mirrored from the host window.\n *\n * Mounts appear and disappear at runtime — e.g. a Firestore-backed store is\n * mounted at `/firestore` after the user signs in and removed on logout. Read\n * or subscribe to the set, then access the files through the `fs` module at the\n * mount's `path`.\n */\nexport interface SandboxMount {\n /** Absolute path where the mount is reachable (e.g. `/firestore`). */\n path: string;\n /** Backend kind, e.g. `'firestore'`. */\n type: string;\n /** Optional stable identifier. */\n id?: string;\n}\n\ninterface MountService {\n getMounts(): SandboxMount[];\n onChange(listener: (mounts: SandboxMount[]) => void): { dispose(): void };\n}\n\n// `module.evaluation.module.bundler` is the sandbox bundler injected into the\n// evaluation context (same path the other SDK helpers reach for `messageBus`).\nconst mountService = (): MountService => {\n // @ts-ignore - injected by the sandbox runtime\n return module.evaluation.module.bundler.mounts;\n};\n\n/** A predicate-style matcher for {@link findMount} / {@link waitForMount}. */\nexport type MountQuery = { type?: string; id?: string; path?: string };\n\nconst matches = (mount: SandboxMount, query: MountQuery): boolean =>\n (query.type === undefined || mount.type === query.type) &&\n (query.id === undefined || mount.id === query.id) &&\n (query.path === undefined || mount.path === query.path);\n\n/**\n * Returns the mounts currently available. Poll this whenever you need a one-off\n * read; use {@link onMountsChange} or {@link useMounts} to react to changes.\n */\nexport const getMounts = (): SandboxMount[] => mountService().getMounts();\n\n/** Returns the first mount matching `query`, or `undefined`. */\nexport const findMount = (query: MountQuery): SandboxMount | undefined =>\n getMounts().find((m) => matches(m, query));\n\n/**\n * Subscribe to mount changes. The listener is invoked immediately with the\n * current mounts, then again on every change. Returns an unsubscribe fn.\n */\nexport const onMountsChange = (listener: (mounts: SandboxMount[]) => void): (() => void) => {\n const disposable = mountService().onChange(listener);\n return () => disposable.dispose();\n};\n\n/**\n * Resolves once a mount matching `query` is present (immediately if it already\n * is). Handy for \"use it when it appears\" — e.g.\n * `await waitForMount({ type: 'firestore' })` before reading `/firestore`.\n */\nexport const waitForMount = (query: MountQuery): Promise<SandboxMount> =>\n new Promise((resolve) => {\n const unsubscribe = onMountsChange((mounts) => {\n const found = mounts.find((m) => matches(m, query));\n if (found) {\n // Defer unsubscribe so we don't dispose during the initial replay call.\n Promise.resolve().then(unsubscribe);\n resolve(found);\n }\n });\n });\n\n/** React hook returning the mounts currently available, re-rendering on change. */\nexport const useMounts = (): SandboxMount[] => {\n const [mounts, setMounts] = useState<SandboxMount[]>(getMounts);\n useEffect(() => onMountsChange(setMounts), []);\n return mounts;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAoC;AA0BpC,MAAM,eAAe,MAAoB;AAEvC,SAAO,OAAO,WAAW,OAAO,QAAQ;AAC1C;AAKA,MAAM,UAAU,CAAC,OAAqB,WACnC,MAAM,SAAS,UAAa,MAAM,SAAS,MAAM,UACjD,MAAM,OAAO,UAAa,MAAM,OAAO,MAAM,QAC7C,MAAM,SAAS,UAAa,MAAM,SAAS,MAAM;AAM7C,MAAM,YAAY,MAAsB,aAAa,EAAE,UAAU;AAGjE,MAAM,YAAY,CAAC,UACxB,UAAU,EAAE,KAAK,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC;AAMpC,MAAM,iBAAiB,CAAC,aAA6D;AAC1F,QAAM,aAAa,aAAa,EAAE,SAAS,QAAQ;AACnD,SAAO,MAAM,WAAW,QAAQ;AAClC;AAOO,MAAM,eAAe,CAAC,UAC3B,IAAI,QAAQ,CAAC,YAAY;AACvB,QAAM,cAAc,eAAe,CAAC,WAAW;AAC7C,UAAM,QAAQ,OAAO,KAAK,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC;AAClD,QAAI,OAAO;AAET,cAAQ,QAAQ,EAAE,KAAK,WAAW;AAClC,cAAQ,KAAK;AAAA,IACf;AAAA,EACF,CAAC;AACH,CAAC;AAGI,MAAM,YAAY,MAAsB;AAC7C,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAyB,SAAS;AAC9D,8BAAU,MAAM,eAAe,SAAS,GAAG,CAAC,CAAC;AAC7C,SAAO;AACT;","names":[]}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * A filesystem mount available to the sandbox, mirrored from the host window.
3
+ *
4
+ * Mounts appear and disappear at runtime — e.g. a Firestore-backed store is
5
+ * mounted at `/firestore` after the user signs in and removed on logout. Read
6
+ * or subscribe to the set, then access the files through the `fs` module at the
7
+ * mount's `path`.
8
+ */
9
+ interface SandboxMount {
10
+ /** Absolute path where the mount is reachable (e.g. `/firestore`). */
11
+ path: string;
12
+ /** Backend kind, e.g. `'firestore'`. */
13
+ type: string;
14
+ /** Optional stable identifier. */
15
+ id?: string;
16
+ }
17
+ /** A predicate-style matcher for {@link findMount} / {@link waitForMount}. */
18
+ type MountQuery = {
19
+ type?: string;
20
+ id?: string;
21
+ path?: string;
22
+ };
23
+ /**
24
+ * Returns the mounts currently available. Poll this whenever you need a one-off
25
+ * read; use {@link onMountsChange} or {@link useMounts} to react to changes.
26
+ */
27
+ declare const getMounts: () => SandboxMount[];
28
+ /** Returns the first mount matching `query`, or `undefined`. */
29
+ declare const findMount: (query: MountQuery) => SandboxMount | undefined;
30
+ /**
31
+ * Subscribe to mount changes. The listener is invoked immediately with the
32
+ * current mounts, then again on every change. Returns an unsubscribe fn.
33
+ */
34
+ declare const onMountsChange: (listener: (mounts: SandboxMount[]) => void) => (() => void);
35
+ /**
36
+ * Resolves once a mount matching `query` is present (immediately if it already
37
+ * is). Handy for "use it when it appears" — e.g.
38
+ * `await waitForMount({ type: 'firestore' })` before reading `/firestore`.
39
+ */
40
+ declare const waitForMount: (query: MountQuery) => Promise<SandboxMount>;
41
+ /** React hook returning the mounts currently available, re-rendering on change. */
42
+ declare const useMounts: () => SandboxMount[];
43
+
44
+ export { type MountQuery, type SandboxMount, findMount, getMounts, onMountsChange, useMounts, waitForMount };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * A filesystem mount available to the sandbox, mirrored from the host window.
3
+ *
4
+ * Mounts appear and disappear at runtime — e.g. a Firestore-backed store is
5
+ * mounted at `/firestore` after the user signs in and removed on logout. Read
6
+ * or subscribe to the set, then access the files through the `fs` module at the
7
+ * mount's `path`.
8
+ */
9
+ interface SandboxMount {
10
+ /** Absolute path where the mount is reachable (e.g. `/firestore`). */
11
+ path: string;
12
+ /** Backend kind, e.g. `'firestore'`. */
13
+ type: string;
14
+ /** Optional stable identifier. */
15
+ id?: string;
16
+ }
17
+ /** A predicate-style matcher for {@link findMount} / {@link waitForMount}. */
18
+ type MountQuery = {
19
+ type?: string;
20
+ id?: string;
21
+ path?: string;
22
+ };
23
+ /**
24
+ * Returns the mounts currently available. Poll this whenever you need a one-off
25
+ * read; use {@link onMountsChange} or {@link useMounts} to react to changes.
26
+ */
27
+ declare const getMounts: () => SandboxMount[];
28
+ /** Returns the first mount matching `query`, or `undefined`. */
29
+ declare const findMount: (query: MountQuery) => SandboxMount | undefined;
30
+ /**
31
+ * Subscribe to mount changes. The listener is invoked immediately with the
32
+ * current mounts, then again on every change. Returns an unsubscribe fn.
33
+ */
34
+ declare const onMountsChange: (listener: (mounts: SandboxMount[]) => void) => (() => void);
35
+ /**
36
+ * Resolves once a mount matching `query` is present (immediately if it already
37
+ * is). Handy for "use it when it appears" — e.g.
38
+ * `await waitForMount({ type: 'firestore' })` before reading `/firestore`.
39
+ */
40
+ declare const waitForMount: (query: MountQuery) => Promise<SandboxMount>;
41
+ /** React hook returning the mounts currently available, re-rendering on change. */
42
+ declare const useMounts: () => SandboxMount[];
43
+
44
+ export { type MountQuery, type SandboxMount, findMount, getMounts, onMountsChange, useMounts, waitForMount };
package/dist/mounts.js ADDED
@@ -0,0 +1,33 @@
1
+ import { useEffect, useState } from "react";
2
+ const mountService = () => {
3
+ return module.evaluation.module.bundler.mounts;
4
+ };
5
+ const matches = (mount, query) => (query.type === void 0 || mount.type === query.type) && (query.id === void 0 || mount.id === query.id) && (query.path === void 0 || mount.path === query.path);
6
+ const getMounts = () => mountService().getMounts();
7
+ const findMount = (query) => getMounts().find((m) => matches(m, query));
8
+ const onMountsChange = (listener) => {
9
+ const disposable = mountService().onChange(listener);
10
+ return () => disposable.dispose();
11
+ };
12
+ const waitForMount = (query) => new Promise((resolve) => {
13
+ const unsubscribe = onMountsChange((mounts) => {
14
+ const found = mounts.find((m) => matches(m, query));
15
+ if (found) {
16
+ Promise.resolve().then(unsubscribe);
17
+ resolve(found);
18
+ }
19
+ });
20
+ });
21
+ const useMounts = () => {
22
+ const [mounts, setMounts] = useState(getMounts);
23
+ useEffect(() => onMountsChange(setMounts), []);
24
+ return mounts;
25
+ };
26
+ export {
27
+ findMount,
28
+ getMounts,
29
+ onMountsChange,
30
+ useMounts,
31
+ waitForMount
32
+ };
33
+ //# sourceMappingURL=mounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mounts.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\n/**\n * A filesystem mount available to the sandbox, mirrored from the host window.\n *\n * Mounts appear and disappear at runtime — e.g. a Firestore-backed store is\n * mounted at `/firestore` after the user signs in and removed on logout. Read\n * or subscribe to the set, then access the files through the `fs` module at the\n * mount's `path`.\n */\nexport interface SandboxMount {\n /** Absolute path where the mount is reachable (e.g. `/firestore`). */\n path: string;\n /** Backend kind, e.g. `'firestore'`. */\n type: string;\n /** Optional stable identifier. */\n id?: string;\n}\n\ninterface MountService {\n getMounts(): SandboxMount[];\n onChange(listener: (mounts: SandboxMount[]) => void): { dispose(): void };\n}\n\n// `module.evaluation.module.bundler` is the sandbox bundler injected into the\n// evaluation context (same path the other SDK helpers reach for `messageBus`).\nconst mountService = (): MountService => {\n // @ts-ignore - injected by the sandbox runtime\n return module.evaluation.module.bundler.mounts;\n};\n\n/** A predicate-style matcher for {@link findMount} / {@link waitForMount}. */\nexport type MountQuery = { type?: string; id?: string; path?: string };\n\nconst matches = (mount: SandboxMount, query: MountQuery): boolean =>\n (query.type === undefined || mount.type === query.type) &&\n (query.id === undefined || mount.id === query.id) &&\n (query.path === undefined || mount.path === query.path);\n\n/**\n * Returns the mounts currently available. Poll this whenever you need a one-off\n * read; use {@link onMountsChange} or {@link useMounts} to react to changes.\n */\nexport const getMounts = (): SandboxMount[] => mountService().getMounts();\n\n/** Returns the first mount matching `query`, or `undefined`. */\nexport const findMount = (query: MountQuery): SandboxMount | undefined =>\n getMounts().find((m) => matches(m, query));\n\n/**\n * Subscribe to mount changes. The listener is invoked immediately with the\n * current mounts, then again on every change. Returns an unsubscribe fn.\n */\nexport const onMountsChange = (listener: (mounts: SandboxMount[]) => void): (() => void) => {\n const disposable = mountService().onChange(listener);\n return () => disposable.dispose();\n};\n\n/**\n * Resolves once a mount matching `query` is present (immediately if it already\n * is). Handy for \"use it when it appears\" — e.g.\n * `await waitForMount({ type: 'firestore' })` before reading `/firestore`.\n */\nexport const waitForMount = (query: MountQuery): Promise<SandboxMount> =>\n new Promise((resolve) => {\n const unsubscribe = onMountsChange((mounts) => {\n const found = mounts.find((m) => matches(m, query));\n if (found) {\n // Defer unsubscribe so we don't dispose during the initial replay call.\n Promise.resolve().then(unsubscribe);\n resolve(found);\n }\n });\n });\n\n/** React hook returning the mounts currently available, re-rendering on change. */\nexport const useMounts = (): SandboxMount[] => {\n const [mounts, setMounts] = useState<SandboxMount[]>(getMounts);\n useEffect(() => onMountsChange(setMounts), []);\n return mounts;\n};\n"],"mappings":"AAAA,SAAS,WAAW,gBAAgB;AA0BpC,MAAM,eAAe,MAAoB;AAEvC,SAAO,OAAO,WAAW,OAAO,QAAQ;AAC1C;AAKA,MAAM,UAAU,CAAC,OAAqB,WACnC,MAAM,SAAS,UAAa,MAAM,SAAS,MAAM,UACjD,MAAM,OAAO,UAAa,MAAM,OAAO,MAAM,QAC7C,MAAM,SAAS,UAAa,MAAM,SAAS,MAAM;AAM7C,MAAM,YAAY,MAAsB,aAAa,EAAE,UAAU;AAGjE,MAAM,YAAY,CAAC,UACxB,UAAU,EAAE,KAAK,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC;AAMpC,MAAM,iBAAiB,CAAC,aAA6D;AAC1F,QAAM,aAAa,aAAa,EAAE,SAAS,QAAQ;AACnD,SAAO,MAAM,WAAW,QAAQ;AAClC;AAOO,MAAM,eAAe,CAAC,UAC3B,IAAI,QAAQ,CAAC,YAAY;AACvB,QAAM,cAAc,eAAe,CAAC,WAAW;AAC7C,UAAM,QAAQ,OAAO,KAAK,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC;AAClD,QAAI,OAAO;AAET,cAAQ,QAAQ,EAAE,KAAK,WAAW;AAClC,cAAQ,KAAK;AAAA,IACf;AAAA,EACF,CAAC;AACH,CAAC;AAGI,MAAM,YAAY,MAAsB;AAC7C,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAyB,SAAS;AAC9D,YAAU,MAAM,eAAe,SAAS,GAAG,CAAC,CAAC;AAC7C,SAAO;AACT;","names":[]}
package/dist/urlUtils.cjs CHANGED
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var urlUtils_exports = {};
20
20
  __export(urlUtils_exports, {
21
+ APP_ROOT: () => APP_ROOT,
21
22
  FILES_PREFIX: () => FILES_PREFIX,
22
23
  constructOuterUrl: () => constructOuterUrl,
23
24
  constructUrl: () => constructUrl,
@@ -29,11 +30,14 @@ __export(urlUtils_exports, {
29
30
  parseHref: () => parseHref,
30
31
  parsePath: () => parsePath,
31
32
  parseTarget: () => parseTarget,
32
- repositoryPrefixURL: () => repositoryPrefixURL
33
+ repositoryPrefixURL: () => repositoryPrefixURL,
34
+ underAppRoot: () => underAppRoot
33
35
  });
34
36
  module.exports = __toCommonJS(urlUtils_exports);
35
37
  var import_pathUtils = require("./pathUtils");
36
38
  const FILES_PREFIX = "/files";
39
+ const APP_ROOT = "/app";
40
+ const underAppRoot = (repoRelativePath) => (0, import_pathUtils.joinPaths)(APP_ROOT, repoRelativePath);
37
41
  const getOuterHostname = (outerHref) => {
38
42
  const url = new URL(outerHref);
39
43
  return `${url.protocol}//${url.hostname}`;
@@ -97,9 +101,13 @@ const PATH_SEGMENTS = [
97
101
  { name: "namespace", pattern: "[a-zA-Z0-9-_]+" },
98
102
  { name: "repository", pattern: "[a-zA-Z0-9-_]+" },
99
103
  { name: "ref", pattern: "[a-zA-Z0-9-_]+" },
100
- { name: "sandboxPath", pattern: ".*", transform: (s) => `/${s}` }
104
+ { name: "sandboxPath", pattern: ".*", transform: (s) => `/${s}`, optionalLeadingSlash: true }
101
105
  ];
102
- const OUTER_HREF_REGEXP = new RegExp("^" + PATH_SEGMENTS.map(({ name, pattern }) => `/(?<${name}>${pattern})`).join("") + "$");
106
+ const OUTER_HREF_REGEXP = new RegExp(
107
+ "^" + PATH_SEGMENTS.map(
108
+ ({ name, pattern, optionalLeadingSlash }) => optionalLeadingSlash ? `(?:/(?<${name}>${pattern}))?` : `/(?<${name}>${pattern})`
109
+ ).join("") + "$"
110
+ );
103
111
  const parsePath = (pathname) => {
104
112
  const matchResults = pathname.match(OUTER_HREF_REGEXP)?.groups ?? {};
105
113
  return PATH_SEGMENTS.reduce((acc, { name, transform }) => {
@@ -143,6 +151,7 @@ const constructUrl = (outerHref, navigationState) => {
143
151
  };
144
152
  // Annotate the CommonJS export names for ESM import in node:
145
153
  0 && (module.exports = {
154
+ APP_ROOT,
146
155
  FILES_PREFIX,
147
156
  constructOuterUrl,
148
157
  constructUrl,
@@ -154,6 +163,7 @@ const constructUrl = (outerHref, navigationState) => {
154
163
  parseHref,
155
164
  parsePath,
156
165
  parseTarget,
157
- repositoryPrefixURL
166
+ repositoryPrefixURL,
167
+ underAppRoot
158
168
  });
159
169
  //# sourceMappingURL=urlUtils.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/urlUtils.ts"],"sourcesContent":["import { joinPaths } from \"./pathUtils\";\nimport { NavigationState, PathState } from \"./TinkerableContext\";\n\nexport const FILES_PREFIX = '/files';\n\nexport const getOuterHostname = (outerHref:string) => {\n const url = new URL(outerHref);\n return `${url.protocol}//${url.hostname}`;\n}\n\nexport const getSearchParams = (search?: string): Record<string, string> => Object.fromEntries(\n [...(new URLSearchParams(search ?? window.location.search).entries())]);\n\n\nexport const parseTarget = (target: string, navigation: NavigationState): NavigationState => {\n const newNavigation = { ...navigation };\n let [prehash, hash] = target.split(\"#\")\n if (prehash) {\n let [path, search] = prehash.split(\"?\")\n if (path) {\n newNavigation.sandboxPath = path\n }\n newNavigation.search = search ? search : '';\n }\n newNavigation.hash = hash ? hash : '';\n return newNavigation\n}\n\n\nexport const maybeParseUrl = (str: string): URL | null => {\n try {\n return new URL(str);\n } catch (_) {\n return null;\n }\n}\n\nexport const isAbsolutePath = (sandboxPath: string) => sandboxPath.startsWith('/');\n\nexport const repositoryPrefixURL = (outerHref:string, navigationState: NavigationState) => constructUrl(outerHref, {\n ...navigationState,\n sandboxPath: ''\n });\n\nexport const constructOuterUrl = (previousOuterHref:string, sandboxTarget:string, navigationState: NavigationState, addFilesPrefix=true):string => {\n if (isAbsolutePath(sandboxTarget)) {\n return constructUrl(\n previousOuterHref,\n {\n ...navigationState,\n sandboxPath: addFilesPrefix ? joinPaths(FILES_PREFIX, sandboxTarget) : sandboxTarget\n })\n }\n return (\n new URL(\n sandboxTarget,\n constructUrl(\n previousOuterHref,\n navigationState\n )\n )\n ).toString();\n}\n\nexport const isInternalHref = (outerHref:string, target: string, navigationState: NavigationState) => {\n const parsedUrl = maybeParseUrl(target);\n if (parsedUrl) {\n return target.startsWith(repositoryPrefixURL(outerHref, navigationState));\n }\n // if target is not a valid URL, then assume it's relative.\n return true;\n}\n\nexport type PathSegment = {\n name: string,\n pattern: string,\n transform?: (pathSegment: string) => string\n}\n\nconst PATH_SEGMENTS: PathSegment[] = [\n { name: 'mode', pattern: '\\\\w+' },\n { name: 'provider', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'namespace', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'repository', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'ref', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'sandboxPath', pattern: '.*', transform: s => `/${s}` }\n];\n\nconst OUTER_HREF_REGEXP = new RegExp('^' + PATH_SEGMENTS.map(({ name, pattern }) => `\\/(?<${name}>${pattern})`).join('') + \"$\");\n\n\nexport const parsePath = (pathname: string): PathState => {\n const matchResults = pathname.match(OUTER_HREF_REGEXP)?.groups ?? {};\n return PATH_SEGMENTS.reduce((acc: Partial<PathState>, { name, transform }: PathSegment) => {\n let value: string | undefined = undefined;\n if (name in matchResults) {\n value = matchResults[name];\n }\n if (!value) {\n // fall back to default value if var not present in\n value = '';\n }\n if (typeof value === 'string') {\n acc[name] = transform ? transform(value) : value;\n }\n return acc;\n }, {}) as PathState;\n}\n\nexport const parseHref = (href: string): NavigationState => {\n const parsedUrl = new URL(href);\n const pathnameState = parsePath(parsedUrl.pathname);\n return {\n ...pathnameState,\n search: parsedUrl.search.substring(1),\n hash: parsedUrl.hash.substring(1),\n } as NavigationState\n}\n\nconst stripSlashPrefix = (s: string): string => s.startsWith('/') ? s.substring(1) : s;\n\nexport const constructUrl = (outerHref:string, navigationState: NavigationState): string => {\n const path = PATH_SEGMENTS.map(({ name }) => {\n let value = navigationState[name];\n return stripSlashPrefix(value ?? '');\n }).join('/');\n const host = getOuterHostname(outerHref);\n let url = `${host}/${path}`\n if (navigationState.search) {\n url += '?' + navigationState.search\n }\n if (navigationState.hash) {\n url += '#' + navigationState.hash\n }\n return url;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAA0B;AAGnB,MAAM,eAAe;AAErB,MAAM,mBAAmB,CAAC,cAAqB;AACpD,QAAM,MAAM,IAAI,IAAI,SAAS;AAC7B,SAAO,GAAG,IAAI,QAAQ,KAAK,IAAI,QAAQ;AACzC;AAEO,MAAM,kBAAkB,CAAC,WAA4C,OAAO;AAAA,EACjF,CAAC,GAAI,IAAI,gBAAgB,UAAU,OAAO,SAAS,MAAM,EAAE,QAAQ,CAAE;AAAC;AAGjE,MAAM,cAAc,CAAC,QAAgB,eAAiD;AAC3F,QAAM,gBAAgB,EAAE,GAAG,WAAW;AACtC,MAAI,CAAC,SAAS,IAAI,IAAI,OAAO,MAAM,GAAG;AACtC,MAAI,SAAS;AACX,QAAI,CAAC,MAAM,MAAM,IAAI,QAAQ,MAAM,GAAG;AACtC,QAAI,MAAM;AACR,oBAAc,cAAc;AAAA,IAC9B;AACA,kBAAc,SAAS,SAAS,SAAS;AAAA,EAC3C;AACA,gBAAc,OAAO,OAAO,OAAO;AACnC,SAAO;AACT;AAGO,MAAM,gBAAgB,CAAC,QAA4B;AACxD,MAAI;AACF,WAAO,IAAI,IAAI,GAAG;AAAA,EACpB,SAAS,GAAG;AACV,WAAO;AAAA,EACT;AACF;AAEO,MAAM,iBAAiB,CAAC,gBAAwB,YAAY,WAAW,GAAG;AAE1E,MAAM,sBAAsB,CAAC,WAAkB,oBAAqC,aAAa,WAAW;AAAA,EAC7G,GAAG;AAAA,EACH,aAAa;AACf,CAAC;AAEE,MAAM,oBAAoB,CAAC,mBAA0B,eAAsB,iBAAkC,iBAAe,SAAgB;AACjJ,MAAI,eAAe,aAAa,GAAG;AACjC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,GAAG;AAAA,QACH,aAAa,qBAAiB,4BAAU,cAAc,aAAa,IAAI;AAAA,MACzE;AAAA,IAAC;AAAA,EACL;AACA,SACE,IAAI;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,IACF;AAAA,EACF,EACA,SAAS;AACb;AAEO,MAAM,iBAAiB,CAAC,WAAkB,QAAgB,oBAAqC;AACpG,QAAM,YAAY,cAAc,MAAM;AACtC,MAAI,WAAW;AACb,WAAO,OAAO,WAAW,oBAAoB,WAAW,eAAe,CAAC;AAAA,EAC1E;AAEA,SAAO;AACT;AAQA,MAAM,gBAA+B;AAAA,EACnC,EAAE,MAAM,QAAQ,SAAS,OAAO;AAAA,EAChC,EAAE,MAAM,YAAY,SAAS,iBAAiB;AAAA,EAC9C,EAAE,MAAM,aAAa,SAAS,iBAAiB;AAAA,EAC/C,EAAE,MAAM,cAAc,SAAS,iBAAiB;AAAA,EAChD,EAAE,MAAM,OAAO,SAAS,iBAAiB;AAAA,EACzC,EAAE,MAAM,eAAe,SAAS,MAAM,WAAW,OAAK,IAAI,CAAC,GAAG;AAChE;AAEA,MAAM,oBAAoB,IAAI,OAAO,MAAM,cAAc,IAAI,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAQ,IAAI,IAAI,OAAO,GAAG,EAAE,KAAK,EAAE,IAAI,GAAG;AAGvH,MAAM,YAAY,CAAC,aAAgC;AACxD,QAAM,eAAe,SAAS,MAAM,iBAAiB,GAAG,UAAU,CAAC;AACnE,SAAO,cAAc,OAAO,CAAC,KAAyB,EAAE,MAAM,UAAU,MAAmB;AACzF,QAAI,QAA4B;AAChC,QAAI,QAAQ,cAAc;AACxB,cAAQ,aAAa,IAAI;AAAA,IAC3B;AACA,QAAI,CAAC,OAAO;AAEV,cAAQ;AAAA,IACV;AACA,QAAI,OAAO,UAAU,UAAU;AAC7B,UAAI,IAAI,IAAI,YAAY,UAAU,KAAK,IAAI;AAAA,IAC7C;AACA,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AACP;AAEO,MAAM,YAAY,CAAC,SAAkC;AAC1D,QAAM,YAAY,IAAI,IAAI,IAAI;AAC9B,QAAM,gBAAgB,UAAU,UAAU,QAAQ;AAClD,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ,UAAU,OAAO,UAAU,CAAC;AAAA,IACpC,MAAM,UAAU,KAAK,UAAU,CAAC;AAAA,EAClC;AACF;AAEA,MAAM,mBAAmB,CAAC,MAAsB,EAAE,WAAW,GAAG,IAAI,EAAE,UAAU,CAAC,IAAI;AAE9E,MAAM,eAAe,CAAC,WAAkB,oBAA6C;AAC1F,QAAM,OAAO,cAAc,IAAI,CAAC,EAAE,KAAK,MAAM;AAC3C,QAAI,QAAQ,gBAAgB,IAAI;AAChC,WAAO,iBAAiB,SAAS,EAAE;AAAA,EACrC,CAAC,EAAE,KAAK,GAAG;AACX,QAAM,OAAO,iBAAiB,SAAS;AACvC,MAAI,MAAM,GAAG,IAAI,IAAI,IAAI;AACzB,MAAI,gBAAgB,QAAQ;AAC1B,WAAO,MAAM,gBAAgB;AAAA,EAC/B;AACA,MAAI,gBAAgB,MAAM;AACxB,WAAO,MAAM,gBAAgB;AAAA,EAC/B;AACA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/urlUtils.ts"],"sourcesContent":["import { joinPaths } from \"./pathUtils\";\nimport { NavigationState, PathState } from \"./TinkerableContext\";\n\nexport const FILES_PREFIX = '/files';\n\n/**\n * Mount point of the Git repository inside the sandbox filesystem. The sandbox\n * fs is rooted at `/` (so apps can reach dynamic mounts like `/firestore`), with\n * the repo mounted here. URL subpaths are repo-relative, so the file router\n * resolves them under `APP_ROOT`.\n */\nexport const APP_ROOT = '/app';\n\n/** Resolve a repo-relative path (e.g. a URL subpath) to its absolute sandbox path. */\nexport const underAppRoot = (repoRelativePath: string): string =>\n joinPaths(APP_ROOT, repoRelativePath);\n\nexport const getOuterHostname = (outerHref:string) => {\n const url = new URL(outerHref);\n return `${url.protocol}//${url.hostname}`;\n}\n\nexport const getSearchParams = (search?: string): Record<string, string> => Object.fromEntries(\n [...(new URLSearchParams(search ?? window.location.search).entries())]);\n\n\nexport const parseTarget = (target: string, navigation: NavigationState): NavigationState => {\n const newNavigation = { ...navigation };\n let [prehash, hash] = target.split(\"#\")\n if (prehash) {\n let [path, search] = prehash.split(\"?\")\n if (path) {\n newNavigation.sandboxPath = path\n }\n newNavigation.search = search ? search : '';\n }\n newNavigation.hash = hash ? hash : '';\n return newNavigation\n}\n\n\nexport const maybeParseUrl = (str: string): URL | null => {\n try {\n return new URL(str);\n } catch (_) {\n return null;\n }\n}\n\nexport const isAbsolutePath = (sandboxPath: string) => sandboxPath.startsWith('/');\n\nexport const repositoryPrefixURL = (outerHref:string, navigationState: NavigationState) => constructUrl(outerHref, {\n ...navigationState,\n sandboxPath: ''\n });\n\nexport const constructOuterUrl = (previousOuterHref:string, sandboxTarget:string, navigationState: NavigationState, addFilesPrefix=true):string => {\n if (isAbsolutePath(sandboxTarget)) {\n return constructUrl(\n previousOuterHref,\n {\n ...navigationState,\n sandboxPath: addFilesPrefix ? joinPaths(FILES_PREFIX, sandboxTarget) : sandboxTarget\n })\n }\n return (\n new URL(\n sandboxTarget,\n constructUrl(\n previousOuterHref,\n navigationState\n )\n )\n ).toString();\n}\n\nexport const isInternalHref = (outerHref:string, target: string, navigationState: NavigationState) => {\n const parsedUrl = maybeParseUrl(target);\n if (parsedUrl) {\n return target.startsWith(repositoryPrefixURL(outerHref, navigationState));\n }\n // if target is not a valid URL, then assume it's relative.\n return true;\n}\n\nexport type PathSegment = {\n name: string,\n pattern: string,\n transform?: (pathSegment: string) => string,\n // When true, the leading slash that delimits this segment is optional, so the\n // whole `/segment` group can be absent. Used for the trailing sandboxPath:\n // an outer href of `/mode/provider/namespace/repository/ref` (no trailing\n // slash, no sub-path) must still parse, otherwise the regex matches nothing\n // and every segment comes back empty.\n optionalLeadingSlash?: boolean\n}\n\nconst PATH_SEGMENTS: PathSegment[] = [\n { name: 'mode', pattern: '\\\\w+' },\n { name: 'provider', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'namespace', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'repository', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'ref', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'sandboxPath', pattern: '.*', transform: s => `/${s}`, optionalLeadingSlash: true }\n];\n\nconst OUTER_HREF_REGEXP = new RegExp(\n '^' +\n PATH_SEGMENTS.map(({ name, pattern, optionalLeadingSlash }) =>\n optionalLeadingSlash\n ? `(?:\\/(?<${name}>${pattern}))?`\n : `\\/(?<${name}>${pattern})`\n ).join('') +\n \"$\"\n);\n\n\nexport const parsePath = (pathname: string): PathState => {\n const matchResults = pathname.match(OUTER_HREF_REGEXP)?.groups ?? {};\n return PATH_SEGMENTS.reduce((acc: Partial<PathState>, { name, transform }: PathSegment) => {\n let value: string | undefined = undefined;\n if (name in matchResults) {\n value = matchResults[name];\n }\n if (!value) {\n // fall back to default value if var not present in\n value = '';\n }\n if (typeof value === 'string') {\n acc[name] = transform ? transform(value) : value;\n }\n return acc;\n }, {}) as PathState;\n}\n\nexport const parseHref = (href: string): NavigationState => {\n const parsedUrl = new URL(href);\n const pathnameState = parsePath(parsedUrl.pathname);\n return {\n ...pathnameState,\n search: parsedUrl.search.substring(1),\n hash: parsedUrl.hash.substring(1),\n } as NavigationState\n}\n\nconst stripSlashPrefix = (s: string): string => s.startsWith('/') ? s.substring(1) : s;\n\nexport const constructUrl = (outerHref:string, navigationState: NavigationState): string => {\n const path = PATH_SEGMENTS.map(({ name }) => {\n let value = navigationState[name];\n return stripSlashPrefix(value ?? '');\n }).join('/');\n const host = getOuterHostname(outerHref);\n let url = `${host}/${path}`\n if (navigationState.search) {\n url += '?' + navigationState.search\n }\n if (navigationState.hash) {\n url += '#' + navigationState.hash\n }\n return url;\n}\n"],"mappings":"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","names":[]}
@@ -4,6 +4,15 @@ import './RoutingSpec.cjs';
4
4
  import './sandboxTypes.cjs';
5
5
 
6
6
  declare const FILES_PREFIX = "/files";
7
+ /**
8
+ * Mount point of the Git repository inside the sandbox filesystem. The sandbox
9
+ * fs is rooted at `/` (so apps can reach dynamic mounts like `/firestore`), with
10
+ * the repo mounted here. URL subpaths are repo-relative, so the file router
11
+ * resolves them under `APP_ROOT`.
12
+ */
13
+ declare const APP_ROOT = "/app";
14
+ /** Resolve a repo-relative path (e.g. a URL subpath) to its absolute sandbox path. */
15
+ declare const underAppRoot: (repoRelativePath: string) => string;
7
16
  declare const getOuterHostname: (outerHref: string) => string;
8
17
  declare const getSearchParams: (search?: string) => Record<string, string>;
9
18
  declare const parseTarget: (target: string, navigation: NavigationState) => NavigationState;
@@ -16,9 +25,10 @@ type PathSegment = {
16
25
  name: string;
17
26
  pattern: string;
18
27
  transform?: (pathSegment: string) => string;
28
+ optionalLeadingSlash?: boolean;
19
29
  };
20
30
  declare const parsePath: (pathname: string) => PathState;
21
31
  declare const parseHref: (href: string) => NavigationState;
22
32
  declare const constructUrl: (outerHref: string, navigationState: NavigationState) => string;
23
33
 
24
- export { FILES_PREFIX, type PathSegment, constructOuterUrl, constructUrl, getOuterHostname, getSearchParams, isAbsolutePath, isInternalHref, maybeParseUrl, parseHref, parsePath, parseTarget, repositoryPrefixURL };
34
+ export { APP_ROOT, FILES_PREFIX, type PathSegment, constructOuterUrl, constructUrl, getOuterHostname, getSearchParams, isAbsolutePath, isInternalHref, maybeParseUrl, parseHref, parsePath, parseTarget, repositoryPrefixURL, underAppRoot };
@@ -4,6 +4,15 @@ import './RoutingSpec.js';
4
4
  import './sandboxTypes.js';
5
5
 
6
6
  declare const FILES_PREFIX = "/files";
7
+ /**
8
+ * Mount point of the Git repository inside the sandbox filesystem. The sandbox
9
+ * fs is rooted at `/` (so apps can reach dynamic mounts like `/firestore`), with
10
+ * the repo mounted here. URL subpaths are repo-relative, so the file router
11
+ * resolves them under `APP_ROOT`.
12
+ */
13
+ declare const APP_ROOT = "/app";
14
+ /** Resolve a repo-relative path (e.g. a URL subpath) to its absolute sandbox path. */
15
+ declare const underAppRoot: (repoRelativePath: string) => string;
7
16
  declare const getOuterHostname: (outerHref: string) => string;
8
17
  declare const getSearchParams: (search?: string) => Record<string, string>;
9
18
  declare const parseTarget: (target: string, navigation: NavigationState) => NavigationState;
@@ -16,9 +25,10 @@ type PathSegment = {
16
25
  name: string;
17
26
  pattern: string;
18
27
  transform?: (pathSegment: string) => string;
28
+ optionalLeadingSlash?: boolean;
19
29
  };
20
30
  declare const parsePath: (pathname: string) => PathState;
21
31
  declare const parseHref: (href: string) => NavigationState;
22
32
  declare const constructUrl: (outerHref: string, navigationState: NavigationState) => string;
23
33
 
24
- export { FILES_PREFIX, type PathSegment, constructOuterUrl, constructUrl, getOuterHostname, getSearchParams, isAbsolutePath, isInternalHref, maybeParseUrl, parseHref, parsePath, parseTarget, repositoryPrefixURL };
34
+ export { APP_ROOT, FILES_PREFIX, type PathSegment, constructOuterUrl, constructUrl, getOuterHostname, getSearchParams, isAbsolutePath, isInternalHref, maybeParseUrl, parseHref, parsePath, parseTarget, repositoryPrefixURL, underAppRoot };
package/dist/urlUtils.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import { joinPaths } from "./pathUtils";
2
2
  const FILES_PREFIX = "/files";
3
+ const APP_ROOT = "/app";
4
+ const underAppRoot = (repoRelativePath) => joinPaths(APP_ROOT, repoRelativePath);
3
5
  const getOuterHostname = (outerHref) => {
4
6
  const url = new URL(outerHref);
5
7
  return `${url.protocol}//${url.hostname}`;
@@ -63,9 +65,13 @@ const PATH_SEGMENTS = [
63
65
  { name: "namespace", pattern: "[a-zA-Z0-9-_]+" },
64
66
  { name: "repository", pattern: "[a-zA-Z0-9-_]+" },
65
67
  { name: "ref", pattern: "[a-zA-Z0-9-_]+" },
66
- { name: "sandboxPath", pattern: ".*", transform: (s) => `/${s}` }
68
+ { name: "sandboxPath", pattern: ".*", transform: (s) => `/${s}`, optionalLeadingSlash: true }
67
69
  ];
68
- const OUTER_HREF_REGEXP = new RegExp("^" + PATH_SEGMENTS.map(({ name, pattern }) => `/(?<${name}>${pattern})`).join("") + "$");
70
+ const OUTER_HREF_REGEXP = new RegExp(
71
+ "^" + PATH_SEGMENTS.map(
72
+ ({ name, pattern, optionalLeadingSlash }) => optionalLeadingSlash ? `(?:/(?<${name}>${pattern}))?` : `/(?<${name}>${pattern})`
73
+ ).join("") + "$"
74
+ );
69
75
  const parsePath = (pathname) => {
70
76
  const matchResults = pathname.match(OUTER_HREF_REGEXP)?.groups ?? {};
71
77
  return PATH_SEGMENTS.reduce((acc, { name, transform }) => {
@@ -108,6 +114,7 @@ const constructUrl = (outerHref, navigationState) => {
108
114
  return url;
109
115
  };
110
116
  export {
117
+ APP_ROOT,
111
118
  FILES_PREFIX,
112
119
  constructOuterUrl,
113
120
  constructUrl,
@@ -119,6 +126,7 @@ export {
119
126
  parseHref,
120
127
  parsePath,
121
128
  parseTarget,
122
- repositoryPrefixURL
129
+ repositoryPrefixURL,
130
+ underAppRoot
123
131
  };
124
132
  //# sourceMappingURL=urlUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/urlUtils.ts"],"sourcesContent":["import { joinPaths } from \"./pathUtils\";\nimport { NavigationState, PathState } from \"./TinkerableContext\";\n\nexport const FILES_PREFIX = '/files';\n\nexport const getOuterHostname = (outerHref:string) => {\n const url = new URL(outerHref);\n return `${url.protocol}//${url.hostname}`;\n}\n\nexport const getSearchParams = (search?: string): Record<string, string> => Object.fromEntries(\n [...(new URLSearchParams(search ?? window.location.search).entries())]);\n\n\nexport const parseTarget = (target: string, navigation: NavigationState): NavigationState => {\n const newNavigation = { ...navigation };\n let [prehash, hash] = target.split(\"#\")\n if (prehash) {\n let [path, search] = prehash.split(\"?\")\n if (path) {\n newNavigation.sandboxPath = path\n }\n newNavigation.search = search ? search : '';\n }\n newNavigation.hash = hash ? hash : '';\n return newNavigation\n}\n\n\nexport const maybeParseUrl = (str: string): URL | null => {\n try {\n return new URL(str);\n } catch (_) {\n return null;\n }\n}\n\nexport const isAbsolutePath = (sandboxPath: string) => sandboxPath.startsWith('/');\n\nexport const repositoryPrefixURL = (outerHref:string, navigationState: NavigationState) => constructUrl(outerHref, {\n ...navigationState,\n sandboxPath: ''\n });\n\nexport const constructOuterUrl = (previousOuterHref:string, sandboxTarget:string, navigationState: NavigationState, addFilesPrefix=true):string => {\n if (isAbsolutePath(sandboxTarget)) {\n return constructUrl(\n previousOuterHref,\n {\n ...navigationState,\n sandboxPath: addFilesPrefix ? joinPaths(FILES_PREFIX, sandboxTarget) : sandboxTarget\n })\n }\n return (\n new URL(\n sandboxTarget,\n constructUrl(\n previousOuterHref,\n navigationState\n )\n )\n ).toString();\n}\n\nexport const isInternalHref = (outerHref:string, target: string, navigationState: NavigationState) => {\n const parsedUrl = maybeParseUrl(target);\n if (parsedUrl) {\n return target.startsWith(repositoryPrefixURL(outerHref, navigationState));\n }\n // if target is not a valid URL, then assume it's relative.\n return true;\n}\n\nexport type PathSegment = {\n name: string,\n pattern: string,\n transform?: (pathSegment: string) => string\n}\n\nconst PATH_SEGMENTS: PathSegment[] = [\n { name: 'mode', pattern: '\\\\w+' },\n { name: 'provider', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'namespace', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'repository', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'ref', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'sandboxPath', pattern: '.*', transform: s => `/${s}` }\n];\n\nconst OUTER_HREF_REGEXP = new RegExp('^' + PATH_SEGMENTS.map(({ name, pattern }) => `\\/(?<${name}>${pattern})`).join('') + \"$\");\n\n\nexport const parsePath = (pathname: string): PathState => {\n const matchResults = pathname.match(OUTER_HREF_REGEXP)?.groups ?? {};\n return PATH_SEGMENTS.reduce((acc: Partial<PathState>, { name, transform }: PathSegment) => {\n let value: string | undefined = undefined;\n if (name in matchResults) {\n value = matchResults[name];\n }\n if (!value) {\n // fall back to default value if var not present in\n value = '';\n }\n if (typeof value === 'string') {\n acc[name] = transform ? transform(value) : value;\n }\n return acc;\n }, {}) as PathState;\n}\n\nexport const parseHref = (href: string): NavigationState => {\n const parsedUrl = new URL(href);\n const pathnameState = parsePath(parsedUrl.pathname);\n return {\n ...pathnameState,\n search: parsedUrl.search.substring(1),\n hash: parsedUrl.hash.substring(1),\n } as NavigationState\n}\n\nconst stripSlashPrefix = (s: string): string => s.startsWith('/') ? s.substring(1) : s;\n\nexport const constructUrl = (outerHref:string, navigationState: NavigationState): string => {\n const path = PATH_SEGMENTS.map(({ name }) => {\n let value = navigationState[name];\n return stripSlashPrefix(value ?? '');\n }).join('/');\n const host = getOuterHostname(outerHref);\n let url = `${host}/${path}`\n if (navigationState.search) {\n url += '?' + navigationState.search\n }\n if (navigationState.hash) {\n url += '#' + navigationState.hash\n }\n return url;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/urlUtils.ts"],"sourcesContent":["import { joinPaths } from \"./pathUtils\";\nimport { NavigationState, PathState } from \"./TinkerableContext\";\n\nexport const FILES_PREFIX = '/files';\n\n/**\n * Mount point of the Git repository inside the sandbox filesystem. The sandbox\n * fs is rooted at `/` (so apps can reach dynamic mounts like `/firestore`), with\n * the repo mounted here. URL subpaths are repo-relative, so the file router\n * resolves them under `APP_ROOT`.\n */\nexport const APP_ROOT = '/app';\n\n/** Resolve a repo-relative path (e.g. a URL subpath) to its absolute sandbox path. */\nexport const underAppRoot = (repoRelativePath: string): string =>\n joinPaths(APP_ROOT, repoRelativePath);\n\nexport const getOuterHostname = (outerHref:string) => {\n const url = new URL(outerHref);\n return `${url.protocol}//${url.hostname}`;\n}\n\nexport const getSearchParams = (search?: string): Record<string, string> => Object.fromEntries(\n [...(new URLSearchParams(search ?? window.location.search).entries())]);\n\n\nexport const parseTarget = (target: string, navigation: NavigationState): NavigationState => {\n const newNavigation = { ...navigation };\n let [prehash, hash] = target.split(\"#\")\n if (prehash) {\n let [path, search] = prehash.split(\"?\")\n if (path) {\n newNavigation.sandboxPath = path\n }\n newNavigation.search = search ? search : '';\n }\n newNavigation.hash = hash ? hash : '';\n return newNavigation\n}\n\n\nexport const maybeParseUrl = (str: string): URL | null => {\n try {\n return new URL(str);\n } catch (_) {\n return null;\n }\n}\n\nexport const isAbsolutePath = (sandboxPath: string) => sandboxPath.startsWith('/');\n\nexport const repositoryPrefixURL = (outerHref:string, navigationState: NavigationState) => constructUrl(outerHref, {\n ...navigationState,\n sandboxPath: ''\n });\n\nexport const constructOuterUrl = (previousOuterHref:string, sandboxTarget:string, navigationState: NavigationState, addFilesPrefix=true):string => {\n if (isAbsolutePath(sandboxTarget)) {\n return constructUrl(\n previousOuterHref,\n {\n ...navigationState,\n sandboxPath: addFilesPrefix ? joinPaths(FILES_PREFIX, sandboxTarget) : sandboxTarget\n })\n }\n return (\n new URL(\n sandboxTarget,\n constructUrl(\n previousOuterHref,\n navigationState\n )\n )\n ).toString();\n}\n\nexport const isInternalHref = (outerHref:string, target: string, navigationState: NavigationState) => {\n const parsedUrl = maybeParseUrl(target);\n if (parsedUrl) {\n return target.startsWith(repositoryPrefixURL(outerHref, navigationState));\n }\n // if target is not a valid URL, then assume it's relative.\n return true;\n}\n\nexport type PathSegment = {\n name: string,\n pattern: string,\n transform?: (pathSegment: string) => string,\n // When true, the leading slash that delimits this segment is optional, so the\n // whole `/segment` group can be absent. Used for the trailing sandboxPath:\n // an outer href of `/mode/provider/namespace/repository/ref` (no trailing\n // slash, no sub-path) must still parse, otherwise the regex matches nothing\n // and every segment comes back empty.\n optionalLeadingSlash?: boolean\n}\n\nconst PATH_SEGMENTS: PathSegment[] = [\n { name: 'mode', pattern: '\\\\w+' },\n { name: 'provider', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'namespace', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'repository', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'ref', pattern: '[a-zA-Z0-9-_]+' },\n { name: 'sandboxPath', pattern: '.*', transform: s => `/${s}`, optionalLeadingSlash: true }\n];\n\nconst OUTER_HREF_REGEXP = new RegExp(\n '^' +\n PATH_SEGMENTS.map(({ name, pattern, optionalLeadingSlash }) =>\n optionalLeadingSlash\n ? `(?:\\/(?<${name}>${pattern}))?`\n : `\\/(?<${name}>${pattern})`\n ).join('') +\n \"$\"\n);\n\n\nexport const parsePath = (pathname: string): PathState => {\n const matchResults = pathname.match(OUTER_HREF_REGEXP)?.groups ?? {};\n return PATH_SEGMENTS.reduce((acc: Partial<PathState>, { name, transform }: PathSegment) => {\n let value: string | undefined = undefined;\n if (name in matchResults) {\n value = matchResults[name];\n }\n if (!value) {\n // fall back to default value if var not present in\n value = '';\n }\n if (typeof value === 'string') {\n acc[name] = transform ? transform(value) : value;\n }\n return acc;\n }, {}) as PathState;\n}\n\nexport const parseHref = (href: string): NavigationState => {\n const parsedUrl = new URL(href);\n const pathnameState = parsePath(parsedUrl.pathname);\n return {\n ...pathnameState,\n search: parsedUrl.search.substring(1),\n hash: parsedUrl.hash.substring(1),\n } as NavigationState\n}\n\nconst stripSlashPrefix = (s: string): string => s.startsWith('/') ? s.substring(1) : s;\n\nexport const constructUrl = (outerHref:string, navigationState: NavigationState): string => {\n const path = PATH_SEGMENTS.map(({ name }) => {\n let value = navigationState[name];\n return stripSlashPrefix(value ?? '');\n }).join('/');\n const host = getOuterHostname(outerHref);\n let url = `${host}/${path}`\n if (navigationState.search) {\n url += '?' + navigationState.search\n }\n if (navigationState.hash) {\n url += '#' + navigationState.hash\n }\n return url;\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@immediately-run/sdk",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Runtime SDK for code executing inside an immediately.run sandbox.",
5
5
  "license": "MIT",
6
6
  "repository": "github:immediately-run/immediately-run-sdk",