@pylonsync/sdk 0.8.3 → 0.9.1

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/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export type RouteMode = "static" | "server" | "live" | "ssr";
1
+ export type { RouteMode } from "./route";
2
+ import type { RouteDefinition } from "./route";
2
3
  export type FieldType = "string" | "int" | "float" | "bool" | "datetime" | "richtext" | "json" | `id(${string})` | `vector(${number})`;
3
4
  /**
4
5
  * CRDT container override for a field. Wire format is the kebab-case
@@ -376,38 +377,8 @@ export declare function entity(name: string, fields: Record<string, FieldBuilder
376
377
  sync?: boolean | SyncScope;
377
378
  }): EntityDefinition;
378
379
  export declare function relation(def: RelationDefinition): RelationDefinition;
379
- export type AuthMode = "public" | "user";
380
- export interface RouteDefinition {
381
- path: string;
382
- mode: RouteMode;
383
- query?: string;
384
- auth?: AuthMode;
385
- /**
386
- * Project-relative module path (e.g. `app/hello/page`) for SSR
387
- * routes. Required when `mode === "ssr"`. Discovered automatically
388
- * by `discoverAppRoutes()`; only specify manually for one-off
389
- * SSR routes outside the `app/` tree.
390
- */
391
- component?: string;
392
- /**
393
- * Layout module path chain (root→leaf). Each layout wraps the next
394
- * as `children`. Only relevant for `mode === "ssr"`.
395
- */
396
- layouts?: string[];
397
- /**
398
- * Route kind. Omitted (or `"page"`) is a normal navigable page.
399
- * `"not-found"` / `"error"` are SSR boundary modules discovered from
400
- * `app/.../not-found.tsx` and `app/.../error.tsx`. Boundary routes are
401
- * NOT matched as navigable URLs — the host renders `not-found` for
402
- * unmatched URLs (HTTP 404) and `error` on render failure (HTTP 500).
403
- * `path` records the segment prefix the boundary covers (`/` for root).
404
- * `"route"` is a form/method handler (`app/.../route.ts` exporting
405
- * POST/PUT/PATCH/DELETE) — matched on its `path` for non-GET requests only,
406
- * never rendered as a page.
407
- */
408
- kind?: "page" | "not-found" | "error" | "route" | "sitemap" | "robots" | "llms" | "og-image";
409
- }
410
- export declare function defineRoute(route: RouteDefinition): RouteDefinition;
380
+ export { defineRoute } from "./route";
381
+ export type { AuthMode, RouteDefinition } from "./route";
411
382
  export interface InputFieldDefinition {
412
383
  name: string;
413
384
  type: FieldType;
@@ -950,6 +921,17 @@ export type AuthConfig = {
950
921
  * any port) is always auto-trusted at every gate.
951
922
  */
952
923
  trustedOrigins?: string[];
924
+ /**
925
+ * Name of a function the runtime calls before it deletes a user through
926
+ * `DELETE /api/auth/account`. Pylon deletes the User row and its own
927
+ * auth-side rows (sessions, API keys, linked accounts, trusted devices).
928
+ * It does not know which app tables belong to the user, so the named
929
+ * function must remove them. It runs as the user with `{ userId }`; a
930
+ * failure aborts the deletion and the client gets
931
+ * `ACCOUNT_DELETE_HOOK_FAILED`. Required by the App Store's account
932
+ * deletion rule whenever an app stores user content.
933
+ */
934
+ onDeleteAccount?: string;
953
935
  };
954
936
  /**
955
937
  * Developer-facing camelCase config consumed by the `llm({...})`
@@ -1074,6 +1056,7 @@ export type ManifestAuthConfig = {
1074
1056
  };
1075
1057
  org_roles: string[];
1076
1058
  trusted_origins: string[];
1059
+ on_delete_account?: string;
1077
1060
  };
1078
1061
  /**
1079
1062
  * Build the manifest's `auth` block from the user-facing camelCase
@@ -0,0 +1,33 @@
1
+ export type RouteMode = "static" | "server" | "live" | "ssr";
2
+ export type AuthMode = "public" | "user";
3
+ export interface RouteDefinition {
4
+ path: string;
5
+ mode: RouteMode;
6
+ query?: string;
7
+ auth?: AuthMode;
8
+ /**
9
+ * Project-relative module path (e.g. `app/hello/page`) for SSR
10
+ * routes. Required when `mode === "ssr"`. Discovered automatically
11
+ * by `discoverAppRoutes()`; only specify manually for one-off
12
+ * SSR routes outside the `app/` tree.
13
+ */
14
+ component?: string;
15
+ /**
16
+ * Layout module path chain (root→leaf). Each layout wraps the next
17
+ * as `children`. Only relevant for `mode === "ssr"`.
18
+ */
19
+ layouts?: string[];
20
+ /**
21
+ * Route kind. Omitted (or `"page"`) is a normal navigable page.
22
+ * `"not-found"` / `"error"` are SSR boundary modules discovered from
23
+ * `app/.../not-found.tsx` and `app/.../error.tsx`. Boundary routes are
24
+ * NOT matched as navigable URLs — the host renders `not-found` for
25
+ * unmatched URLs (HTTP 404) and `error` on render failure (HTTP 500).
26
+ * `path` records the segment prefix the boundary covers (`/` for root).
27
+ * `"route"` is a form/method handler (`app/.../route.ts` exporting
28
+ * POST/PUT/PATCH/DELETE) — matched on its `path` for non-GET requests only,
29
+ * never rendered as a page.
30
+ */
31
+ kind?: "page" | "not-found" | "error" | "route" | "sitemap" | "robots" | "llms" | "og-image";
32
+ }
33
+ export declare function defineRoute(route: RouteDefinition): RouteDefinition;
package/package.json CHANGED
@@ -3,10 +3,28 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.8.3",
6
+ "version": "0.9.1",
7
7
  "type": "module",
8
8
  "main": "./src/index.ts",
9
9
  "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./src/index.ts"
14
+ },
15
+ "./route": {
16
+ "types": "./dist/route.d.ts",
17
+ "default": "./src/route.ts"
18
+ },
19
+ "./package.json": "./package.json"
20
+ },
21
+ "typesVersions": {
22
+ "*": {
23
+ "route": [
24
+ "./dist/route.d.ts"
25
+ ]
26
+ }
27
+ },
10
28
  "scripts": {
11
29
  "build": "tsc -p tsconfig.build.json",
12
30
  "check": "tsc -p tsconfig.json --noEmit",
package/src/index.ts CHANGED
@@ -2,7 +2,8 @@
2
2
  // Route modes
3
3
  // ---------------------------------------------------------------------------
4
4
 
5
- export type RouteMode = "static" | "server" | "live" | "ssr";
5
+ export type { RouteMode } from "./route";
6
+ import type { RouteDefinition } from "./route";
6
7
 
7
8
  // ---------------------------------------------------------------------------
8
9
  // Field types
@@ -493,53 +494,12 @@ export function relation(def: RelationDefinition): RelationDefinition {
493
494
  }
494
495
 
495
496
  // ---------------------------------------------------------------------------
496
- // Route definition
497
+ // Route definition — lives in ./route so client bundles can import it
498
+ // without the Node-only discovery helpers below.
497
499
  // ---------------------------------------------------------------------------
498
500
 
499
- export type AuthMode = "public" | "user";
500
-
501
- export interface RouteDefinition {
502
- path: string;
503
- mode: RouteMode;
504
- query?: string;
505
- auth?: AuthMode;
506
- /**
507
- * Project-relative module path (e.g. `app/hello/page`) for SSR
508
- * routes. Required when `mode === "ssr"`. Discovered automatically
509
- * by `discoverAppRoutes()`; only specify manually for one-off
510
- * SSR routes outside the `app/` tree.
511
- */
512
- component?: string;
513
- /**
514
- * Layout module path chain (root→leaf). Each layout wraps the next
515
- * as `children`. Only relevant for `mode === "ssr"`.
516
- */
517
- layouts?: string[];
518
- /**
519
- * Route kind. Omitted (or `"page"`) is a normal navigable page.
520
- * `"not-found"` / `"error"` are SSR boundary modules discovered from
521
- * `app/.../not-found.tsx` and `app/.../error.tsx`. Boundary routes are
522
- * NOT matched as navigable URLs — the host renders `not-found` for
523
- * unmatched URLs (HTTP 404) and `error` on render failure (HTTP 500).
524
- * `path` records the segment prefix the boundary covers (`/` for root).
525
- * `"route"` is a form/method handler (`app/.../route.ts` exporting
526
- * POST/PUT/PATCH/DELETE) — matched on its `path` for non-GET requests only,
527
- * never rendered as a page.
528
- */
529
- kind?:
530
- | "page"
531
- | "not-found"
532
- | "error"
533
- | "route"
534
- | "sitemap"
535
- | "robots"
536
- | "llms"
537
- | "og-image";
538
- }
539
-
540
- export function defineRoute(route: RouteDefinition): RouteDefinition {
541
- return route;
542
- }
501
+ export { defineRoute } from "./route";
502
+ export type { AuthMode, RouteDefinition } from "./route";
543
503
 
544
504
  // ---------------------------------------------------------------------------
545
505
  // Query definition
@@ -1778,6 +1738,17 @@ export type AuthConfig = {
1778
1738
  * any port) is always auto-trusted at every gate.
1779
1739
  */
1780
1740
  trustedOrigins?: string[];
1741
+ /**
1742
+ * Name of a function the runtime calls before it deletes a user through
1743
+ * `DELETE /api/auth/account`. Pylon deletes the User row and its own
1744
+ * auth-side rows (sessions, API keys, linked accounts, trusted devices).
1745
+ * It does not know which app tables belong to the user, so the named
1746
+ * function must remove them. It runs as the user with `{ userId }`; a
1747
+ * failure aborts the deletion and the client gets
1748
+ * `ACCOUNT_DELETE_HOOK_FAILED`. Required by the App Store's account
1749
+ * deletion rule whenever an app stores user content.
1750
+ */
1751
+ onDeleteAccount?: string;
1781
1752
  };
1782
1753
 
1783
1754
  // ---------------------------------------------------------------------------
@@ -1931,6 +1902,7 @@ export type ManifestAuthConfig = {
1931
1902
  };
1932
1903
  org_roles: string[];
1933
1904
  trusted_origins: string[];
1905
+ on_delete_account?: string;
1934
1906
  };
1935
1907
 
1936
1908
  const BUILTIN_ORG_ROLES = new Set(["owner", "admin", "member"]);
@@ -2001,6 +1973,7 @@ export function auth(cfg: AuthConfig = {}): ManifestAuthConfig {
2001
1973
  },
2002
1974
  org_roles: validateOrgRoles(cfg.orgRoles ?? []),
2003
1975
  trusted_origins: cfg.trustedOrigins ?? [],
1976
+ ...(cfg.onDeleteAccount ? { on_delete_account: cfg.onDeleteAccount } : {}),
2004
1977
  };
2005
1978
  }
2006
1979
 
package/src/route.ts ADDED
@@ -0,0 +1,52 @@
1
+ // Route definitions. This module has no runtime dependency on Node
2
+ // builtins, so client bundlers (Metro for React Native, Vite, Next.js)
3
+ // can import `defineRoute` through `@pylonsync/sdk/route` without
4
+ // pulling in the filesystem-backed discovery helpers from the package
5
+ // root. `@pylonsync/react` re-exports from here for that reason.
6
+
7
+ export type RouteMode = "static" | "server" | "live" | "ssr";
8
+
9
+ export type AuthMode = "public" | "user";
10
+
11
+ export interface RouteDefinition {
12
+ path: string;
13
+ mode: RouteMode;
14
+ query?: string;
15
+ auth?: AuthMode;
16
+ /**
17
+ * Project-relative module path (e.g. `app/hello/page`) for SSR
18
+ * routes. Required when `mode === "ssr"`. Discovered automatically
19
+ * by `discoverAppRoutes()`; only specify manually for one-off
20
+ * SSR routes outside the `app/` tree.
21
+ */
22
+ component?: string;
23
+ /**
24
+ * Layout module path chain (root→leaf). Each layout wraps the next
25
+ * as `children`. Only relevant for `mode === "ssr"`.
26
+ */
27
+ layouts?: string[];
28
+ /**
29
+ * Route kind. Omitted (or `"page"`) is a normal navigable page.
30
+ * `"not-found"` / `"error"` are SSR boundary modules discovered from
31
+ * `app/.../not-found.tsx` and `app/.../error.tsx`. Boundary routes are
32
+ * NOT matched as navigable URLs — the host renders `not-found` for
33
+ * unmatched URLs (HTTP 404) and `error` on render failure (HTTP 500).
34
+ * `path` records the segment prefix the boundary covers (`/` for root).
35
+ * `"route"` is a form/method handler (`app/.../route.ts` exporting
36
+ * POST/PUT/PATCH/DELETE) — matched on its `path` for non-GET requests only,
37
+ * never rendered as a page.
38
+ */
39
+ kind?:
40
+ | "page"
41
+ | "not-found"
42
+ | "error"
43
+ | "route"
44
+ | "sitemap"
45
+ | "robots"
46
+ | "llms"
47
+ | "og-image";
48
+ }
49
+
50
+ export function defineRoute(route: RouteDefinition): RouteDefinition {
51
+ return route;
52
+ }
@@ -102,3 +102,10 @@ describe("custom organization roles", () => {
102
102
  expect(() => auth({ orgRoles: ["member"] })).toThrow("is built in");
103
103
  });
104
104
  });
105
+
106
+ describe("auth() account deletion hook", () => {
107
+ test("names the function in the manifest only when configured", () => {
108
+ expect(auth({ onDeleteAccount: "purgeMyData" }).on_delete_account).toBe("purgeMyData");
109
+ expect("on_delete_account" in auth({})).toBe(false);
110
+ });
111
+ });