@lpdjs/firestore-repo-service 2.2.4 → 2.2.6

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.
Files changed (40) hide show
  1. package/README.md +40 -19
  2. package/dist/create-servers-D4-NGpKm.d.ts +105 -0
  3. package/dist/create-servers-DmggzSb3.d.cts +105 -0
  4. package/dist/{index-BiWZwHS_.d.ts → index-Cvip2Sgt.d.ts} +1 -1
  5. package/dist/{index-B3-vAYx0.d.cts → index-DpD4DEqH.d.cts} +1 -1
  6. package/dist/index.cjs +619 -57
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +7 -2
  9. package/dist/index.d.ts +7 -2
  10. package/dist/index.js +619 -57
  11. package/dist/index.js.map +1 -1
  12. package/dist/openapi-B3P2F8op.d.ts +69 -0
  13. package/dist/openapi-UJJ1aCFk.d.cts +69 -0
  14. package/dist/queue-D_-aMf4H.d.ts +52 -0
  15. package/dist/queue-Dk1Ezhkf.d.cts +52 -0
  16. package/dist/servers/admin/index.cjs +547 -75
  17. package/dist/servers/admin/index.cjs.map +1 -1
  18. package/dist/servers/admin/index.d.cts +1 -1
  19. package/dist/servers/admin/index.d.ts +1 -1
  20. package/dist/servers/admin/index.js +547 -75
  21. package/dist/servers/admin/index.js.map +1 -1
  22. package/dist/servers/crud/index.d.cts +5 -69
  23. package/dist/servers/crud/index.d.ts +5 -69
  24. package/dist/servers/index.cjs +637 -75
  25. package/dist/servers/index.cjs.map +1 -1
  26. package/dist/servers/index.d.cts +10 -5
  27. package/dist/servers/index.d.ts +10 -5
  28. package/dist/servers/index.js +637 -75
  29. package/dist/servers/index.js.map +1 -1
  30. package/dist/sync/bigquery.d.cts +1 -1
  31. package/dist/sync/bigquery.d.ts +1 -1
  32. package/dist/sync/index.cjs +33 -33
  33. package/dist/sync/index.cjs.map +1 -1
  34. package/dist/sync/index.d.cts +5 -107
  35. package/dist/sync/index.d.ts +5 -107
  36. package/dist/sync/index.js +33 -33
  37. package/dist/sync/index.js.map +1 -1
  38. package/dist/{types-BbCdscqh.d.cts → types-CX5AbZWV.d.cts} +1 -1
  39. package/dist/{types-BbCdscqh.d.ts → types-CX5AbZWV.d.ts} +1 -1
  40. package/package.json +1 -1
package/README.md CHANGED
@@ -251,24 +251,50 @@ const users = await repos.users.query.by({
251
251
  });
252
252
  ```
253
253
 
254
- ## Firestore → SQL Sync
254
+ ## Servers (admin UI · CRUD REST · Firestore → SQL sync)
255
255
 
256
- Replicate Firestore collections to BigQuery (or any SQL database) via Cloud Pub/Sub and Cloud Functions v2.
257
-
258
- ```
259
- Firestore triggers → Pub/Sub → CF v2 worker → BigQuery MERGE
260
- ```
256
+ A single unified factory binds all servers to your repository registry. Per-repo `repo: …` is no longer needed — the registry key drives both the runtime binding and the inferred model type for `fieldsConfig` autocomplete.
261
257
 
262
258
  ```typescript
263
- import { createFirestoreSync } from "@lpdjs/firestore-repo-service/sync";
259
+ import { createServers } from "@lpdjs/firestore-repo-service";
260
+ import { onRequest } from "firebase-functions/v2/https";
264
261
  import { BigQueryAdapter } from "@lpdjs/firestore-repo-service/sync/bigquery";
265
262
  import { BigQuery } from "@google-cloud/bigquery";
266
263
  import { PubSub } from "@google-cloud/pubsub";
267
264
  import * as firestoreTriggers from "firebase-functions/v2/firestore";
268
265
  import * as pubsubHandler from "firebase-functions/v2/pubsub";
269
- import { onRequest } from "firebase-functions/v2/https";
270
266
 
271
- const sync = createFirestoreSync(repos, {
267
+ const servers = createServers(repos, {
268
+ onRequest,
269
+ httpsOptions: { invoker: "public" },
270
+ });
271
+
272
+ // Admin UI — repo auto-injected from the key, fieldsConfig typed against the model
273
+ export const admin = servers.admin({
274
+ basePath: "/admin",
275
+ auth: { type: "basic", username: "admin", password: "secret" },
276
+ repos: {
277
+ posts: {
278
+ path: "posts",
279
+ fieldsConfig: { title: ["create", "mutable"], status: ["filterable"] },
280
+ allowDelete: true,
281
+ },
282
+ users: { path: "users" },
283
+ },
284
+ });
285
+
286
+ // CRUD REST API
287
+ export const api = servers.crud({
288
+ basePath: "/api",
289
+ repos: {
290
+ posts: { path: "posts", allowDelete: true },
291
+ users: { path: "users" },
292
+ },
293
+ openapi: { title: "My API", version: "1.0.0" },
294
+ });
295
+
296
+ // Firestore → BigQuery sync (triggers + worker + admin Cloud Functions)
297
+ export const { functions } = servers.sync({
272
298
  deps: { firestoreTriggers, pubsubHandler, pubsub: new PubSub() },
273
299
  adapter: new BigQueryAdapter({
274
300
  bigquery: new BigQuery({ projectId: "my-project" }),
@@ -276,15 +302,7 @@ const sync = createFirestoreSync(repos, {
276
302
  }),
277
303
  topicPrefix: "firestore-sync",
278
304
  autoMigrate: true,
279
- batchSize: 500,
280
- flushIntervalMs: 10_000,
281
- workerOptions: {
282
- concurrency: 5,
283
- maxInstances: 10,
284
- },
285
305
  admin: {
286
- onRequest,
287
- httpsOptions: { invoker: "public" },
288
306
  auth: { type: "basic", username: "admin", password: "secret" },
289
307
  featuresFlag: { healthCheck: true, manualSync: true, viewQueue: true, configCheck: true },
290
308
  },
@@ -295,15 +313,18 @@ const sync = createFirestoreSync(repos, {
295
313
  },
296
314
  });
297
315
 
316
+ // Spread Cloud Functions into your exports
298
317
  export const {
299
318
  users_onCreate, users_onUpdate, users_onDelete, sync_users,
300
319
  posts_onCreate, posts_onUpdate, posts_onDelete, sync_posts,
301
320
  comments_onCreate, comments_onUpdate, comments_onDelete, sync_comments,
302
321
  adminsync,
303
- } = sync.functions;
322
+ } = functions;
304
323
  ```
305
324
 
306
- The admin endpoint (`/`) exposes a UI for health checks, force-sync, queue inspection, and GCP config verification.
325
+ When `onRequest` is passed to `createServers`, `servers.admin()` and `servers.crud()` return ready-to-export Cloud Functions. Without it, they return raw HTTP handlers you can wrap yourself.
326
+
327
+ The sync admin endpoint (`/`) exposes a UI for health checks, force-sync, queue inspection, and GCP config verification.
307
328
 
308
329
  For a custom SQL backend, implement the `SqlAdapter` interface:
309
330
 
@@ -0,0 +1,105 @@
1
+ import { S as SyncQueue } from './queue-D_-aMf4H.js';
2
+ import { F as FirestoreSyncConfig, S as SyncEvent } from './types-CX5AbZWV.js';
3
+ import { O as OpenAPIDocument } from './openapi-B3P2F8op.js';
4
+ import * as firebase_functions_v2_https from 'firebase-functions/v2/https';
5
+ import { onRequest, HttpsOptions } from 'firebase-functions/v2/https';
6
+ import { C as ConfiguredRepository, m as CrudServerOptions, l as CrudRepoConfig } from './types-Z9Qy8Xmx.js';
7
+ import { b as AdminServerOptions, A as AdminRepoConfig } from './index-Cvip2Sgt.js';
8
+
9
+ /** Per-repo admin config with `repo` omitted (auto-bound from the registry key). */
10
+ type BoundAdminRepoConfig<TRepo extends ConfiguredRepository<any>> = Omit<AdminRepoConfig<TRepo>, "repo">;
11
+ /** Per-repo CRUD config with `repo` omitted (auto-bound from the registry key). */
12
+ type BoundCrudRepoConfig<TRepo extends ConfiguredRepository<any>> = Omit<CrudRepoConfig<TRepo>, "repo">;
13
+ /**
14
+ * Admin server options for the bound builder.
15
+ * `repos` becomes a partial record so callers can expose a subset of the
16
+ * underlying registry, and each entry omits `repo` (injected from the key).
17
+ */
18
+ interface BoundAdminServerOptions<TRepos extends Record<string, ConfiguredRepository<any>>> extends Omit<AdminServerOptions<TRepos>, "repos"> {
19
+ repos: {
20
+ [K in keyof TRepos]?: BoundAdminRepoConfig<TRepos[K]>;
21
+ };
22
+ }
23
+ /** CRUD server options for the bound builder. */
24
+ interface BoundCrudServerOptions<TRepos extends Record<string, ConfiguredRepository<any>>> extends Omit<CrudServerOptions<TRepos>, "repos"> {
25
+ repos: {
26
+ [K in keyof TRepos]?: BoundCrudRepoConfig<TRepos[K]>;
27
+ };
28
+ }
29
+ /**
30
+ * Sync config for the bound builder — identical to `FirestoreSyncConfig`
31
+ * but the top-level `repoMapping` argument is supplied by `createServers`.
32
+ */
33
+ type BoundFirestoreSyncConfig<TRepos extends Record<string, any>> = FirestoreSyncConfig<TRepos>;
34
+ /** Optional dependencies shared across every server. */
35
+ interface CreateServersDeps {
36
+ /**
37
+ * `onRequest` from `firebase-functions/v2/https`. When provided, the
38
+ * admin/CRUD builders return a ready-to-export Cloud Function instead of
39
+ * the raw handler. Also forwarded to the sync admin (so the bundled
40
+ * `adminsync` Cloud Function is generated automatically).
41
+ */
42
+ onRequest?: typeof onRequest;
43
+ /**
44
+ * Default `httpsOptions` applied to every server. Per-server options
45
+ * override these defaults.
46
+ */
47
+ httpsOptions?: HttpsOptions;
48
+ }
49
+ /**
50
+ * Pre-binds a repository mapping to all server builders.
51
+ *
52
+ * @template TRepos - Repository registry; inferred at the call site.
53
+ * @param repos - The repository mapping (e.g. result of `createRepositoryMapping`).
54
+ * @param deps - Optional shared deps (notably `onRequest` for auto-wrapping).
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * import { onRequest } from "firebase-functions/v2/https";
59
+ * import { createServers } from "@lpdjs/firestore-repo-service/servers";
60
+ *
61
+ * const servers = createServers(repos, { onRequest });
62
+ *
63
+ * export const admin = servers.admin({
64
+ * basePath: "/admin",
65
+ * repos: {
66
+ * posts: { path: "posts", allowDelete: true },
67
+ * users: { path: "users" },
68
+ * },
69
+ * });
70
+ * ```
71
+ */
72
+ declare function createServers<TRepos extends Record<string, ConfiguredRepository<any>>>(repos: TRepos, deps?: CreateServersDeps): {
73
+ /**
74
+ * Build the admin UI handler with `repo` auto-injected from each registry key.
75
+ * Returns a Cloud Function when `onRequest` was passed to `createServers`,
76
+ * otherwise the raw HTTP handler.
77
+ */
78
+ admin(options: BoundAdminServerOptions<TRepos>): firebase_functions_v2_https.HttpsFunction | (((req: any, res: any) => Promise<void>) & {
79
+ httpsOptions?: HttpsOptions;
80
+ });
81
+ /**
82
+ * Build the CRUD REST API handler with `repo` auto-injected from each
83
+ * registry key. Returns a Cloud Function when `onRequest` was passed to
84
+ * `createServers`, otherwise the raw HTTP handler (which still exposes
85
+ * `.spec()` and `.httpsOptions` on the raw form).
86
+ */
87
+ crud(options: BoundCrudServerOptions<TRepos>): firebase_functions_v2_https.HttpsFunction | (((req: any, res: any) => Promise<void>) & {
88
+ spec: () => OpenAPIDocument;
89
+ httpsOptions?: HttpsOptions;
90
+ });
91
+ /**
92
+ * Build the Firestore→SQL sync pipeline using the bound registry.
93
+ * Forwards the shared `onRequest` to the sync admin config so the
94
+ * bundled `adminsync` Cloud Function is auto-generated.
95
+ */
96
+ sync(config: BoundFirestoreSyncConfig<TRepos>): {
97
+ functions: Record<string, any>;
98
+ adminHandler: ((req: any, res: any) => Promise<void>) | null;
99
+ handleMessage: (event: SyncEvent) => Promise<void>;
100
+ queues: Map<string, SyncQueue>;
101
+ shutdown: () => Promise<void>;
102
+ };
103
+ };
104
+
105
+ export { type BoundAdminRepoConfig as B, type CreateServersDeps as C, type BoundAdminServerOptions as a, type BoundCrudRepoConfig as b, createServers as c, type BoundCrudServerOptions as d, type BoundFirestoreSyncConfig as e };
@@ -0,0 +1,105 @@
1
+ import { S as SyncQueue } from './queue-Dk1Ezhkf.cjs';
2
+ import { F as FirestoreSyncConfig, S as SyncEvent } from './types-CX5AbZWV.cjs';
3
+ import { O as OpenAPIDocument } from './openapi-UJJ1aCFk.cjs';
4
+ import * as firebase_functions_v2_https from 'firebase-functions/v2/https';
5
+ import { onRequest, HttpsOptions } from 'firebase-functions/v2/https';
6
+ import { C as ConfiguredRepository, m as CrudServerOptions, l as CrudRepoConfig } from './types-Z9Qy8Xmx.cjs';
7
+ import { b as AdminServerOptions, A as AdminRepoConfig } from './index-DpD4DEqH.cjs';
8
+
9
+ /** Per-repo admin config with `repo` omitted (auto-bound from the registry key). */
10
+ type BoundAdminRepoConfig<TRepo extends ConfiguredRepository<any>> = Omit<AdminRepoConfig<TRepo>, "repo">;
11
+ /** Per-repo CRUD config with `repo` omitted (auto-bound from the registry key). */
12
+ type BoundCrudRepoConfig<TRepo extends ConfiguredRepository<any>> = Omit<CrudRepoConfig<TRepo>, "repo">;
13
+ /**
14
+ * Admin server options for the bound builder.
15
+ * `repos` becomes a partial record so callers can expose a subset of the
16
+ * underlying registry, and each entry omits `repo` (injected from the key).
17
+ */
18
+ interface BoundAdminServerOptions<TRepos extends Record<string, ConfiguredRepository<any>>> extends Omit<AdminServerOptions<TRepos>, "repos"> {
19
+ repos: {
20
+ [K in keyof TRepos]?: BoundAdminRepoConfig<TRepos[K]>;
21
+ };
22
+ }
23
+ /** CRUD server options for the bound builder. */
24
+ interface BoundCrudServerOptions<TRepos extends Record<string, ConfiguredRepository<any>>> extends Omit<CrudServerOptions<TRepos>, "repos"> {
25
+ repos: {
26
+ [K in keyof TRepos]?: BoundCrudRepoConfig<TRepos[K]>;
27
+ };
28
+ }
29
+ /**
30
+ * Sync config for the bound builder — identical to `FirestoreSyncConfig`
31
+ * but the top-level `repoMapping` argument is supplied by `createServers`.
32
+ */
33
+ type BoundFirestoreSyncConfig<TRepos extends Record<string, any>> = FirestoreSyncConfig<TRepos>;
34
+ /** Optional dependencies shared across every server. */
35
+ interface CreateServersDeps {
36
+ /**
37
+ * `onRequest` from `firebase-functions/v2/https`. When provided, the
38
+ * admin/CRUD builders return a ready-to-export Cloud Function instead of
39
+ * the raw handler. Also forwarded to the sync admin (so the bundled
40
+ * `adminsync` Cloud Function is generated automatically).
41
+ */
42
+ onRequest?: typeof onRequest;
43
+ /**
44
+ * Default `httpsOptions` applied to every server. Per-server options
45
+ * override these defaults.
46
+ */
47
+ httpsOptions?: HttpsOptions;
48
+ }
49
+ /**
50
+ * Pre-binds a repository mapping to all server builders.
51
+ *
52
+ * @template TRepos - Repository registry; inferred at the call site.
53
+ * @param repos - The repository mapping (e.g. result of `createRepositoryMapping`).
54
+ * @param deps - Optional shared deps (notably `onRequest` for auto-wrapping).
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * import { onRequest } from "firebase-functions/v2/https";
59
+ * import { createServers } from "@lpdjs/firestore-repo-service/servers";
60
+ *
61
+ * const servers = createServers(repos, { onRequest });
62
+ *
63
+ * export const admin = servers.admin({
64
+ * basePath: "/admin",
65
+ * repos: {
66
+ * posts: { path: "posts", allowDelete: true },
67
+ * users: { path: "users" },
68
+ * },
69
+ * });
70
+ * ```
71
+ */
72
+ declare function createServers<TRepos extends Record<string, ConfiguredRepository<any>>>(repos: TRepos, deps?: CreateServersDeps): {
73
+ /**
74
+ * Build the admin UI handler with `repo` auto-injected from each registry key.
75
+ * Returns a Cloud Function when `onRequest` was passed to `createServers`,
76
+ * otherwise the raw HTTP handler.
77
+ */
78
+ admin(options: BoundAdminServerOptions<TRepos>): firebase_functions_v2_https.HttpsFunction | (((req: any, res: any) => Promise<void>) & {
79
+ httpsOptions?: HttpsOptions;
80
+ });
81
+ /**
82
+ * Build the CRUD REST API handler with `repo` auto-injected from each
83
+ * registry key. Returns a Cloud Function when `onRequest` was passed to
84
+ * `createServers`, otherwise the raw HTTP handler (which still exposes
85
+ * `.spec()` and `.httpsOptions` on the raw form).
86
+ */
87
+ crud(options: BoundCrudServerOptions<TRepos>): firebase_functions_v2_https.HttpsFunction | (((req: any, res: any) => Promise<void>) & {
88
+ spec: () => OpenAPIDocument;
89
+ httpsOptions?: HttpsOptions;
90
+ });
91
+ /**
92
+ * Build the Firestore→SQL sync pipeline using the bound registry.
93
+ * Forwards the shared `onRequest` to the sync admin config so the
94
+ * bundled `adminsync` Cloud Function is auto-generated.
95
+ */
96
+ sync(config: BoundFirestoreSyncConfig<TRepos>): {
97
+ functions: Record<string, any>;
98
+ adminHandler: ((req: any, res: any) => Promise<void>) | null;
99
+ handleMessage: (event: SyncEvent) => Promise<void>;
100
+ queues: Map<string, SyncQueue>;
101
+ shutdown: () => Promise<void>;
102
+ };
103
+ };
104
+
105
+ export { type BoundAdminRepoConfig as B, type CreateServersDeps as C, type BoundAdminServerOptions as a, type BoundCrudRepoConfig as b, createServers as c, type BoundCrudServerOptions as d, type BoundFirestoreSyncConfig as e };
@@ -562,4 +562,4 @@ declare function createAdminServer<TRepos extends Record<string, ConfiguredRepos
562
562
  httpsOptions?: HttpsOptions;
563
563
  };
564
564
 
565
- export { type AdminRepoConfig as A, type BasicAuthConfig as B, type ColumnMeta as C, type FilterState as F, MiniRouter as M, type PageOptions as P, type QueryError as Q, type RelationalFieldMeta as R, type SortState as S, type AdminRepoEntry as a, type AdminServerOptions as b, createAdminServer as c, type Middleware as d, type RepoRegistry as e, type RouteHandler as f };
565
+ export { type AdminRepoConfig as A, type BasicAuthConfig as B, type ColumnMeta as C, type FilterState as F, MiniRouter as M, type PageOptions as P, type QueryError as Q, type RelationalFieldMeta as R, type SortState as S, type AdminRepoEntry as a, type AdminServerOptions as b, type Middleware as c, type RepoRegistry as d, type RouteHandler as e, createAdminServer as f };
@@ -562,4 +562,4 @@ declare function createAdminServer<TRepos extends Record<string, ConfiguredRepos
562
562
  httpsOptions?: HttpsOptions;
563
563
  };
564
564
 
565
- export { type AdminRepoConfig as A, type BasicAuthConfig as B, type ColumnMeta as C, type FilterState as F, MiniRouter as M, type PageOptions as P, type QueryError as Q, type RelationalFieldMeta as R, type SortState as S, type AdminRepoEntry as a, type AdminServerOptions as b, createAdminServer as c, type Middleware as d, type RepoRegistry as e, type RouteHandler as f };
565
+ export { type AdminRepoConfig as A, type BasicAuthConfig as B, type ColumnMeta as C, type FilterState as F, MiniRouter as M, type PageOptions as P, type QueryError as Q, type RelationalFieldMeta as R, type SortState as S, type AdminRepoEntry as a, type AdminServerOptions as b, type Middleware as c, type RepoRegistry as d, type RouteHandler as e, createAdminServer as f };