@dereekb/firebase-server 13.6.17 → 13.7.0

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/index.cjs.js +2615 -951
  2. package/index.esm.js +2598 -932
  3. package/mailgun/package.json +9 -9
  4. package/model/package.json +9 -9
  5. package/model/src/lib/storagefile/storagefile.action.server.d.ts +1 -1
  6. package/oidc/index.cjs.js +245 -180
  7. package/oidc/index.esm.js +242 -178
  8. package/oidc/package.json +10 -10
  9. package/oidc/src/lib/middleware/oauth-auth.module.d.ts +18 -25
  10. package/package.json +11 -10
  11. package/src/lib/function/error.d.ts +11 -28
  12. package/src/lib/nest/app.d.ts +4 -45
  13. package/src/lib/nest/app.module.d.ts +4 -2
  14. package/src/lib/nest/auth/auth.util.d.ts +71 -5
  15. package/src/lib/nest/controller/index.d.ts +1 -0
  16. package/src/lib/nest/controller/model/index.d.ts +4 -0
  17. package/src/lib/nest/controller/model/model.api.controller.d.ts +93 -0
  18. package/src/lib/nest/controller/model/model.api.dispatch.d.ts +73 -0
  19. package/src/lib/nest/controller/model/model.api.get.service.d.ts +73 -0
  20. package/src/lib/nest/controller/model/model.api.module.d.ts +32 -0
  21. package/src/lib/nest/model/analytics.handler.d.ts +2 -0
  22. package/src/lib/nest/model/api.details.d.ts +53 -1
  23. package/src/lib/nest/model/call.model.function.d.ts +8 -5
  24. package/src/lib/nest/model/create.model.function.d.ts +1 -1
  25. package/src/lib/nest/model/crud.assert.function.d.ts +1 -1
  26. package/src/lib/nest/model/delete.model.function.d.ts +1 -1
  27. package/src/lib/nest/model/index.d.ts +1 -0
  28. package/src/lib/nest/model/query.model.function.d.ts +207 -0
  29. package/src/lib/nest/model/read.model.function.d.ts +1 -1
  30. package/src/lib/nest/model/update.model.function.d.ts +1 -1
  31. package/src/lib/nest/nest.provider.d.ts +19 -0
  32. package/test/index.cjs.js +1358 -398
  33. package/test/index.esm.js +1355 -400
  34. package/test/package.json +13 -11
  35. package/test/src/lib/firebase/firebase.test.d.ts +1 -1
  36. package/test/src/lib/index.d.ts +1 -0
  37. package/test/src/lib/oidc/index.d.ts +2 -0
  38. package/test/src/lib/oidc/oidc.test.fixture.d.ts +126 -0
  39. package/test/src/lib/oidc/oidc.test.flow.d.ts +43 -0
  40. package/zoho/package.json +9 -9
@@ -0,0 +1,73 @@
1
+ import { type Maybe } from '@dereekb/util';
2
+ import { type FirestoreModelKey, type FirestoreModelType } from '@dereekb/firebase';
3
+ import { type INestApplicationContext } from '@nestjs/common';
4
+ import { ModelApiDispatchConfig } from './model.api.dispatch';
5
+ import { type FirebaseServerAuthData } from '../auth.context.server';
6
+ /**
7
+ * Maximum number of keys allowed in a multi-read request.
8
+ */
9
+ export declare const MAX_MODEL_ACCESS_MULTI_READ_KEYS = 50;
10
+ /**
11
+ * Result of a single document access read.
12
+ */
13
+ export interface ModelAccessReadResult {
14
+ readonly key: FirestoreModelKey;
15
+ readonly data: unknown;
16
+ }
17
+ /**
18
+ * Result of a multi-document access read.
19
+ */
20
+ export interface ModelAccessMultiReadResult {
21
+ readonly results: ModelAccessReadResult[];
22
+ readonly errors: ModelAccessReadError[];
23
+ }
24
+ /**
25
+ * Error for a single document in a multi-read request.
26
+ */
27
+ export interface ModelAccessReadError {
28
+ readonly key: FirestoreModelKey;
29
+ readonly message: string;
30
+ readonly code?: string;
31
+ }
32
+ /**
33
+ * Service for direct document reads using the `useModel()` permission-checking pattern.
34
+ *
35
+ * Unlike the dispatch service (which goes through callModel handlers), this service
36
+ * reads documents directly from Firestore via {@link AbstractFirebaseNestContext.useModel},
37
+ * enforcing `'read'` role permissions per document.
38
+ */
39
+ export declare class ModelApiGetService {
40
+ private readonly _nestContext;
41
+ constructor(config: ModelApiDispatchConfig, nestApplication: INestApplicationContext);
42
+ /**
43
+ * Reads a single document by model type and key with permission checking.
44
+ *
45
+ * @param modelType - The Firestore model type string (e.g., 'profile', 'guestbook').
46
+ * @param key - The full Firestore model key (e.g., 'pr/abc123').
47
+ * @param auth - The authenticated user's auth data from the request.
48
+ * @returns The document key and data.
49
+ * @throws Permission or not-found errors from useModel.
50
+ */
51
+ readDocument(modelType: FirestoreModelType, key: FirestoreModelKey, auth: Maybe<FirebaseServerAuthData>): Promise<ModelAccessReadResult>;
52
+ /**
53
+ * Reads multiple documents of the same model type with permission checking.
54
+ *
55
+ * Individual document errors (not-found, forbidden) are captured per-key
56
+ * and returned in the errors array rather than throwing.
57
+ *
58
+ * @param modelType - The Firestore model type string.
59
+ * @param keys - Array of Firestore model keys (max {@link MAX_MODEL_ACCESS_MULTI_READ_KEYS}).
60
+ * @param auth - The authenticated user's auth data from the request.
61
+ * @returns Results and errors for each requested key.
62
+ */
63
+ readDocuments(modelType: FirestoreModelType, keys: FirestoreModelKey[], auth: Maybe<FirebaseServerAuthData>): Promise<ModelAccessMultiReadResult>;
64
+ /**
65
+ * Builds an {@link AuthDataRef} compatible with `useModel()` from the HTTP request auth.
66
+ *
67
+ * Uses the same synthetic auth pattern as {@link ModelApiDispatchService.dispatch}.
68
+ *
69
+ * @param auth - The Firebase server auth data from the HTTP request, or undefined for unauthenticated requests.
70
+ * @returns An object containing a synthetic {@link AuthData} for use with `useModel()`, or undefined auth.
71
+ */
72
+ private _makeAuthRef;
73
+ }
@@ -0,0 +1,32 @@
1
+ import { type ModuleMetadata } from '@nestjs/common';
2
+ import { type ClassType } from '@dereekb/util';
3
+ /**
4
+ * Configuration for {@link modelApiModuleMetadata}.
5
+ */
6
+ export interface ModelApiModuleMetadataConfig extends Pick<ModuleMetadata, 'imports' | 'exports' | 'providers'> {
7
+ /**
8
+ * Module that exports the required dependencies.
9
+ *
10
+ * Must provide {@link ModelApiDispatchConfig} so the dispatch service
11
+ * can access the callModel function and nest context factory.
12
+ */
13
+ readonly dependencyModule: ClassType;
14
+ }
15
+ /**
16
+ * Generates NestJS module metadata for the Model API controller.
17
+ *
18
+ * Follows the same pattern as {@link oidcModuleMetadata} — takes a dependency module
19
+ * that provides the required tokens, and returns a complete module metadata object.
20
+ *
21
+ * @param metadataConfig - Configuration including the dependency module.
22
+ * @returns NestJS module metadata with the Model API controller, dispatch service, and app context provider.
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * @Module(modelApiModuleMetadata({
27
+ * dependencyModule: DemoModelApiDependencyModule
28
+ * }))
29
+ * export class DemoModelApiModule {}
30
+ * ```
31
+ */
32
+ export declare function modelApiModuleMetadata(metadataConfig: ModelApiModuleMetadataConfig): ModuleMetadata;
@@ -71,6 +71,8 @@ export declare const ON_CALL_MODEL_ANALYTICS_SERVICE: InjectionToken<OnCallModel
71
71
  *
72
72
  * Used as the default fallback by {@link OnCallModelAnalyticsResolver} when no analytics
73
73
  * service is registered.
74
+ *
75
+ * @returns An {@link OnCallModelAnalyticsService} that discards all analytics events.
74
76
  */
75
77
  export declare function noopOnCallModelAnalyticsService(): OnCallModelAnalyticsService;
76
78
  /**
@@ -1,5 +1,5 @@
1
1
  import { type Maybe } from '@dereekb/util';
2
- import { type OnCallFunctionType, type FirestoreModelType, type ModelFirebaseCrudFunctionSpecifier } from '@dereekb/firebase';
2
+ import { type OnCallFunctionType, type OnCallTypedModelParams, type FirestoreModelType, type ModelFirebaseCrudFunctionSpecifier } from '@dereekb/firebase';
3
3
  import { type OnCallModelFunctionAnalyticsDetails } from './analytics.details';
4
4
  /**
5
5
  * Reference to a type that can produce a JSON Schema representation.
@@ -11,10 +11,41 @@ import { type OnCallModelFunctionAnalyticsDetails } from './analytics.details';
11
11
  export interface JsonSchemaRef {
12
12
  toJsonSchema(options?: object): object;
13
13
  }
14
+ /**
15
+ * A natural language summary of an MCP tool operation result.
16
+ */
17
+ export type McpToolResponseSummary = string;
18
+ /**
19
+ * Minimal structural type for MCP tool response content.
20
+ *
21
+ * Mirrors the shape of MCP SDK's CallToolResult without importing the SDK directly,
22
+ * so api.details.ts remains dependency-free.
23
+ */
24
+ export interface McpToolResponseContent {
25
+ readonly content: ReadonlyArray<McpToolResponseContentBlock>;
26
+ readonly structuredContent?: unknown;
27
+ readonly isError?: boolean;
28
+ }
29
+ /**
30
+ * A single content block in an MCP tool response.
31
+ */
32
+ export interface McpToolResponseContentBlock {
33
+ readonly type: string;
34
+ readonly text?: string;
35
+ readonly mimeType?: string;
36
+ readonly data?: string;
37
+ }
14
38
  /**
15
39
  * MCP-specific customization for a model function.
16
40
  *
17
41
  * When omitted, defaults are auto-generated from the handler's position in the call model tree.
42
+ *
43
+ * Response formatting uses a tiered system:
44
+ * - **Tier 1 (default)**: Auto-generated summary from the result shape. No config needed.
45
+ * - **Tier 2**: Provide {@link summarizeResponse} to return a natural language string. The framework wraps it into MCP content + structuredContent automatically.
46
+ * - **Tier 3**: Provide {@link formatResponse} for complete control over the MCP response content blocks.
47
+ *
48
+ * Resolution order: formatResponse > summarizeResponse > auto-generated default.
18
49
  */
19
50
  export interface OnCallModelFunctionMcpDetails {
20
51
  /**
@@ -25,6 +56,27 @@ export interface OnCallModelFunctionMcpDetails {
25
56
  * Custom tool name override.
26
57
  */
27
58
  readonly name?: string;
59
+ /**
60
+ * Tier 2 response formatter: returns a natural language summary string.
61
+ *
62
+ * The framework wraps the string into a text content block and attaches the raw result
63
+ * as structuredContent automatically.
64
+ *
65
+ * @param result - The handler's return value.
66
+ * @param params - The OnCallTypedModelParams that were dispatched.
67
+ * @returns A human-readable summary of the operation result.
68
+ */
69
+ readonly summarizeResponse?: (result: unknown, params: OnCallTypedModelParams) => McpToolResponseSummary;
70
+ /**
71
+ * Tier 3 response formatter: complete control over the MCP tool response.
72
+ *
73
+ * When provided, takes precedence over {@link summarizeResponse} and the auto-generated default.
74
+ *
75
+ * @param result - The handler's return value.
76
+ * @param params - The OnCallTypedModelParams that were dispatched.
77
+ * @returns The full MCP tool response content.
78
+ */
79
+ readonly formatResponse?: (result: unknown, params: OnCallTypedModelParams) => McpToolResponseContent;
28
80
  }
29
81
  /**
30
82
  * API details metadata for a single model call handler function.
@@ -5,13 +5,13 @@ import { type AssertModelCrudRequestFunctionContextCrudType, type AssertModelCru
5
5
  import { type NestContextCallableRequest } from '../function/nest';
6
6
  import { type OnCallApiDetailsRef } from './api.details';
7
7
  /**
8
- * Maps CRUD call type strings (e.g., 'create', 'read', 'update', 'delete') to their
8
+ * Maps call type strings (e.g., 'create', 'read', 'update', 'delete', 'query') to their
9
9
  * corresponding handler functions.
10
10
  *
11
- * Used by {@link onCallModel} to dispatch incoming requests to the correct CRUD handler.
11
+ * Used by {@link onCallModel} to dispatch incoming requests to the correct handler.
12
12
  */
13
13
  export type OnCallModelMap = {
14
- readonly [call: OnCallFunctionType]: OnCallWithNestContext<any, OnCallTypedModelParams>;
14
+ readonly [call: OnCallFunctionType]: OnCallWithNestContext<any, OnCallTypedModelParams<any>>;
15
15
  };
16
16
  /**
17
17
  * Configuration for {@link onCallModel}.
@@ -51,7 +51,8 @@ export interface OnCallModelConfig {
51
51
  * create: onCallCreateModel({ profile: createProfile, guestbook: createGuestbook }),
52
52
  * read: onCallReadModel({ profile: readProfile }),
53
53
  * update: onCallUpdateModel({ profile: updateProfile }),
54
- * delete: onCallDeleteModel({ guestbook: deleteGuestbook })
54
+ * delete: onCallDeleteModel({ guestbook: deleteGuestbook }),
55
+ * query: onCallQueryModel({ profile: queryProfiles })
55
56
  * });
56
57
  * ```
57
58
  */
@@ -95,7 +96,9 @@ export interface OnCallWithCallTypeModelConfig<N> {
95
96
  */
96
97
  readonly callType: string;
97
98
  /**
98
- * The CRUD category used by {@link AssertModelCrudRequestFunction}.
99
+ * The operation category used by {@link AssertModelCrudRequestFunction}.
100
+ *
101
+ * One of: 'call', 'create', 'read', 'update', 'delete', 'query'.
99
102
  */
100
103
  readonly crudType: AssertModelCrudRequestFunctionContextCrudType;
101
104
  /**
@@ -89,6 +89,6 @@ export declare function onCallCreateModel<N>(map: OnCallCreateModelMap<N>, confi
89
89
  * Creates a bad-request error indicating the requested model type is not valid for creation.
90
90
  *
91
91
  * @param modelType - The unrecognized model type string.
92
- * @returns A bad-request error with UNKNOWN_TYPE_ERROR code.
92
+ * @returns A bad-request error with {@link UNKNOWN_MODEL_TYPE_ERROR_CODE} code.
93
93
  */
94
94
  export declare function createModelUnknownModelTypeError(modelType: FirestoreModelType): import("firebase-functions/https").HttpsError;
@@ -7,7 +7,7 @@ import { type OnCallFunctionType, type FirestoreModelType } from '@dereekb/fireb
7
7
  * Used by {@link AssertModelCrudRequestFunction} to let assertions branch on operation type,
8
8
  * enabling cross-cutting rules like "block all deletes for archived models."
9
9
  */
10
- export type AssertModelCrudRequestFunctionContextCrudType = 'call' | 'create' | 'read' | 'update' | 'delete';
10
+ export type AssertModelCrudRequestFunctionContextCrudType = 'call' | 'create' | 'read' | 'update' | 'delete' | 'query';
11
11
  /**
12
12
  * Context passed to a {@link AssertModelCrudRequestFunction} before a CRUD handler executes.
13
13
  *
@@ -78,6 +78,6 @@ export declare function onCallDeleteModel<N>(map: OnCallDeleteModelMap<N>, confi
78
78
  * Creates a bad-request error indicating the requested model type is not valid for deletion.
79
79
  *
80
80
  * @param modelType - The unrecognized model type string.
81
- * @returns A bad-request error with UNKNOWN_TYPE_ERROR code.
81
+ * @returns A bad-request error with {@link UNKNOWN_MODEL_TYPE_ERROR_CODE} code.
82
82
  */
83
83
  export declare function deleteModelUnknownModelTypeError(modelType: FirestoreModelType): import("firebase-functions/https").HttpsError;
@@ -9,3 +9,4 @@ export * from './create.model.function';
9
9
  export * from './read.model.function';
10
10
  export * from './update.model.function';
11
11
  export * from './delete.model.function';
12
+ export * from './query.model.function';
@@ -0,0 +1,207 @@
1
+ import { type Maybe, type PromiseOrValue } from '@dereekb/util';
2
+ import { type FirestoreModelType, type FirestoreModelIdentity, type FirestoreModelTypes, type OnCallQueryModelParams, type OnCallQueryModelRequestParams, type OnCallQueryModelResult, type ModelFirebaseCrudFunctionSpecifierRef, type FirestoreModelKey, type FirestoreCollectionLike, type FirestoreQueryConstraint, type DocumentSnapshot, type QueryDocumentSnapshot } from '@dereekb/firebase';
3
+ import { type OnCallWithAuthAwareNestRequireAuthRef, type OnCallWithNestContext } from '../function/call';
4
+ import { type NestContextCallableRequestWithAuth, type NestContextCallableRequestWithOptionalAuth } from '../function/nest';
5
+ import { type AssertModelCrudRequestFunction } from './crud.assert.function';
6
+ /**
7
+ * Request type for model query handlers that require authentication.
8
+ *
9
+ * @typeParam N - The NestJS context type.
10
+ * @typeParam I - The input data type for the query operation. Must extend {@link OnCallQueryModelRequestParams}.
11
+ */
12
+ export type OnCallQueryModelRequest<N, I extends OnCallQueryModelRequestParams = OnCallQueryModelRequestParams> = NestContextCallableRequestWithAuth<N, I> & ModelFirebaseCrudFunctionSpecifierRef;
13
+ /**
14
+ * A model query handler function that requires an authenticated caller.
15
+ */
16
+ export type OnCallQueryModelFunctionWithAuth<N, I extends OnCallQueryModelRequestParams = OnCallQueryModelRequestParams, O = unknown> = ((request: OnCallQueryModelRequest<N, I>) => PromiseOrValue<O>) & {
17
+ readonly _requiresAuth?: true;
18
+ };
19
+ /**
20
+ * Request type for model query handlers that allow unauthenticated callers.
21
+ */
22
+ export type OnCallQueryModelRequestWithOptionalAuth<N, I extends OnCallQueryModelRequestParams = OnCallQueryModelRequestParams> = NestContextCallableRequestWithOptionalAuth<N, I> & ModelFirebaseCrudFunctionSpecifierRef;
23
+ /**
24
+ * A model query handler function that does not require authentication.
25
+ *
26
+ * Useful for public-facing query endpoints such as listing public content.
27
+ */
28
+ export type OnCallQueryModelFunctionWithOptionalAuth<N, I extends OnCallQueryModelRequestParams = OnCallQueryModelRequestParams, O = unknown> = ((request: OnCallQueryModelRequestWithOptionalAuth<N, I>) => PromiseOrValue<O>) & {
29
+ readonly _requireAuth: false;
30
+ };
31
+ /**
32
+ * Standard model query handler requiring auth (the common case).
33
+ */
34
+ export type OnCallQueryModelFunction<N, I extends OnCallQueryModelRequestParams = OnCallQueryModelRequestParams, O = unknown> = OnCallQueryModelFunctionWithAuth<N, I, O> & OnCallWithAuthAwareNestRequireAuthRef;
35
+ /**
36
+ * Union of auth-required and optional-auth query handlers.
37
+ */
38
+ export type OnCallQueryModelFunctionAuthAware<N, I extends OnCallQueryModelRequestParams = OnCallQueryModelRequestParams, O = unknown> = OnCallQueryModelFunction<N, I, O> | OnCallQueryModelFunctionWithOptionalAuth<N, I, O>;
39
+ /**
40
+ * Maps Firestore model type strings to their query handler functions.
41
+ *
42
+ * Pass this map to {@link onCallQueryModel} to register all model types
43
+ * that support querying through the call model system.
44
+ *
45
+ * @typeParam N - The NestJS context type.
46
+ * @typeParam T - The Firestore model identity constraining valid model type keys.
47
+ */
48
+ export type OnCallQueryModelMap<N, T extends FirestoreModelIdentity = FirestoreModelIdentity> = {
49
+ readonly [K in FirestoreModelTypes<T>]?: OnCallQueryModelFunctionAuthAware<N, any, any>;
50
+ };
51
+ /**
52
+ * Configuration for {@link onCallQueryModel}.
53
+ */
54
+ export interface OnCallQueryModelConfig<N> {
55
+ /**
56
+ * Optional assertion run before the query handler; throw to reject.
57
+ */
58
+ readonly preAssert?: AssertModelCrudRequestFunction<N, OnCallQueryModelParams>;
59
+ }
60
+ /**
61
+ * Factory that creates a callable function handling model queries for multiple model types.
62
+ *
63
+ * Dispatches to the correct handler based on the `modelType` field in the request,
64
+ * enforces auth requirements per handler, and aggregates API details for MCP introspection.
65
+ *
66
+ * Query handlers receive filter/pagination params in the request data and should return
67
+ * an {@link OnCallQueryModelResult} with paginated results. Use {@link executeOnCallQuery}
68
+ * within handlers to handle cursor pagination automatically.
69
+ *
70
+ * @param map - Maps model type strings to their query handler functions.
71
+ * @param config - Optional configuration including a pre-assertion hook.
72
+ * @returns A callable function for the 'query' call type.
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * const queryHandler = onCallQueryModel<DemoNestContext>({
77
+ * profile: queryProfiles,
78
+ * guestbook: queryGuestbooks
79
+ * });
80
+ *
81
+ * // Register as the 5th call type in onCallModel:
82
+ * const callModel = onCallModel({
83
+ * create: onCallCreateModel({ ... }),
84
+ * read: onCallReadModel({ ... }),
85
+ * update: onCallUpdateModel({ ... }),
86
+ * delete: onCallDeleteModel({ ... }),
87
+ * query: queryHandler
88
+ * });
89
+ * ```
90
+ */
91
+ export declare function onCallQueryModel<N>(map: OnCallQueryModelMap<N>, config?: OnCallQueryModelConfig<N>): OnCallWithNestContext<N, OnCallQueryModelParams, unknown>;
92
+ /**
93
+ * Creates a bad-request error indicating the requested model type is not valid for querying.
94
+ *
95
+ * @param modelType - The unrecognized model type string.
96
+ * @returns A bad-request error with {@link UNKNOWN_MODEL_TYPE_ERROR_CODE} code.
97
+ */
98
+ export declare function queryModelUnknownModelTypeError(modelType: FirestoreModelType): import("firebase-functions/https").HttpsError;
99
+ /**
100
+ * Creates a bad-request error indicating the cursor document key is invalid or inaccessible.
101
+ *
102
+ * @param cursorDocumentKey - The cursor document key that failed to resolve.
103
+ * @returns A bad-request error with {@link BAD_DOCUMENT_QUERY_CURSOR_ERROR_CODE} code.
104
+ */
105
+ export declare function queryModelBadCursorError(cursorDocumentKey: Maybe<FirestoreModelKey>): import("firebase-functions/https").HttpsError;
106
+ /**
107
+ * Configuration for {@link executeOnCallQuery}.
108
+ *
109
+ * @typeParam T - The Firestore document data type.
110
+ * @typeParam R - The mapped result type for each document. Defaults to T.
111
+ */
112
+ export interface ExecuteOnCallQueryConfig<T, R = T> {
113
+ /**
114
+ * The query request params containing limit and cursorDocumentKey.
115
+ */
116
+ readonly params: OnCallQueryModelRequestParams;
117
+ /**
118
+ * The Firestore collection to query against.
119
+ *
120
+ * Used for building queries (via {@link FirestoreQueryFactory}).
121
+ */
122
+ readonly collection: FirestoreCollectionLike<T>;
123
+ /**
124
+ * Loads and permission-checks the cursor document when {@link OnCallQueryModelRequestParams.cursorDocumentKey} is provided.
125
+ *
126
+ * This function must verify that the caller has read access to the cursor document.
127
+ * Typically implemented using `nest.useModel()` which enforces permission checking.
128
+ * Must return the document's snapshot for use with `startAfter`.
129
+ *
130
+ * If the cursor document does not exist or the caller lacks permission, this function
131
+ * should throw an appropriate error (e.g., forbidden or not-found).
132
+ *
133
+ * @param cursorDocumentKey - The Firestore model key of the cursor document.
134
+ * @returns A promise resolving to the cursor document's snapshot.
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * loadCursorDocument: async (key) => {
139
+ * const doc = await nest.useModel('guestbook', {
140
+ * request,
141
+ * key,
142
+ * roles: 'read',
143
+ * use: (x) => x.document
144
+ * });
145
+ * return doc.accessor.get();
146
+ * }
147
+ * ```
148
+ */
149
+ readonly loadCursorDocument: (cursorDocumentKey: FirestoreModelKey) => PromiseOrValue<DocumentSnapshot<T>>;
150
+ /**
151
+ * Builds query constraints to apply to the query.
152
+ *
153
+ * Return where/orderBy constraints here. Do NOT add limit or startAfter —
154
+ * those are managed by {@link executeOnCallQuery} automatically.
155
+ *
156
+ * @returns Array of query constraints to apply. May be async if constraints depend on external data.
157
+ */
158
+ readonly buildConstraints: () => PromiseOrValue<FirestoreQueryConstraint[]>;
159
+ /**
160
+ * Optional maximum items per page override. Defaults to {@link MAX_ON_CALL_QUERY_MODEL_LIMIT}.
161
+ *
162
+ * The effective limit is: `min(params.limit ?? DEFAULT, maxLimit)`.
163
+ */
164
+ readonly maxLimit?: number;
165
+ /**
166
+ * Optional transform applied to each document snapshot's data before returning.
167
+ *
168
+ * Defaults to `snapshot.data()`.
169
+ */
170
+ readonly mapResult?: (snapshot: QueryDocumentSnapshot<T>) => R;
171
+ }
172
+ /**
173
+ * Executes a paginated query using cursor-based pagination.
174
+ *
175
+ * Handles the mechanics of:
176
+ * - Clamping the page limit to the configured maximum
177
+ * - Resolving the cursor document key to a snapshot for `startAfter`
178
+ * - Fetching one extra document to detect whether more results exist
179
+ * - Building the {@link OnCallQueryModelResult} with cursorDocumentKey and hasMore
180
+ *
181
+ * @example
182
+ * ```typescript
183
+ * export const queryGuestbooks: DemoQueryModelFunction<QueryGuestbooksParams, OnCallQueryModelResult<Guestbook>> = async (request) => {
184
+ * const { nest, data } = request;
185
+ * return executeOnCallQuery({
186
+ * params: data,
187
+ * collection: nest.demoFirestoreCollections.guestbookCollection,
188
+ * loadCursorDocument: async (key) => {
189
+ * const doc = await nest.useModel('guestbook', { request, key, roles: 'read', use: (x) => x.document });
190
+ * return doc.accessor.get();
191
+ * },
192
+ * buildConstraints: () => {
193
+ * const constraints: FirestoreQueryConstraint[] = [];
194
+ * if (data.published != null) {
195
+ * constraints.push(where('published', '==', data.published));
196
+ * }
197
+ * constraints.push(orderBy('name', 'asc'));
198
+ * return constraints;
199
+ * }
200
+ * });
201
+ * };
202
+ * ```
203
+ *
204
+ * @param config - Query configuration including collection, constraints, and pagination params.
205
+ * @returns Paginated query result with cursor for the next page.
206
+ */
207
+ export declare function executeOnCallQuery<T, R = T>(config: ExecuteOnCallQueryConfig<T, R>): Promise<OnCallQueryModelResult<R>>;
@@ -80,6 +80,6 @@ export declare function onCallReadModel<N>(map: OnCallReadModelMap<N>, config?:
80
80
  * Creates a bad-request error indicating the requested model type is not valid for reading.
81
81
  *
82
82
  * @param modelType - The unrecognized model type string.
83
- * @returns A bad-request error with UNKNOWN_TYPE_ERROR code.
83
+ * @returns A bad-request error with {@link UNKNOWN_MODEL_TYPE_ERROR_CODE} code.
84
84
  */
85
85
  export declare function readModelUnknownModelTypeError(modelType: FirestoreModelType): import("firebase-functions/https").HttpsError;
@@ -81,6 +81,6 @@ export declare function onCallUpdateModel<N>(map: OnCallUpdateModelMap<N>, confi
81
81
  * Creates a bad-request error indicating the requested model type is not valid for updating.
82
82
  *
83
83
  * @param modelType - The unrecognized model type string.
84
- * @returns A bad-request error with UNKNOWN_TYPE_ERROR code.
84
+ * @returns A bad-request error with {@link UNKNOWN_MODEL_TYPE_ERROR_CODE} code.
85
85
  */
86
86
  export declare function updateModelUnknownModelTypeError(modelType: FirestoreModelType): import("firebase-functions/https").HttpsError;
@@ -87,6 +87,20 @@ export declare abstract class AbstractFirebaseNestContext<A, Y extends FirebaseM
87
87
  * @returns An in-context models service scoped to the given auth context.
88
88
  */
89
89
  model(context: AuthDataRef, buildFn?: BuildFunction<FirebaseAppModelContext<A>>): InContextFirebaseModelsService<Y>;
90
+ /**
91
+ * Loads a model document by key, checks permissions against the requested roles,
92
+ * and optionally transforms the result via a `use` function.
93
+ *
94
+ * When called without a `use` function, returns the {@link ContextGrantedModelRolesReader}
95
+ * which provides access to the document and its granted roles.
96
+ *
97
+ * @throws Throws {@link nestFirebaseDoesNotExistError} if the document does not exist.
98
+ * @throws Throws {@link nestFirebaseForbiddenPermissionError} if the caller lacks the requested roles.
99
+ *
100
+ * @param type - The model type string (e.g., 'profile', 'guestbook').
101
+ * @param select - Selection params including key, roles, and optional use function.
102
+ * @returns The result of the `use` function, or the roles reader if no `use` function is provided.
103
+ */
90
104
  useModel<T extends FirebaseModelsServiceTypes<Y>, O>(type: T, select: UseModelInput<FirebaseAppModelContext<A>, Y, T, O>): Promise<O>;
91
105
  useModel<T extends FirebaseModelsServiceTypes<Y>>(type: T, select: UseModelInputForRolesReader<FirebaseAppModelContext<A>, Y, T>): Promise<FirebaseModelsServiceSelectionResultRolesReader<Y, T>>;
92
106
  /**
@@ -95,6 +109,11 @@ export declare abstract class AbstractFirebaseNestContext<A, Y extends FirebaseM
95
109
  * Uses {@link performAsyncTasks} internally. The `use` function receives the array of
96
110
  * successful {@link ContextGrantedModelRolesReader} values and an array of failed items.
97
111
  *
112
+ * Individual documents that do not exist throw {@link nestFirebaseDoesNotExistError},
113
+ * and documents where the caller lacks the requested roles throw
114
+ * {@link nestFirebaseForbiddenPermissionError}. These errors are captured per-key
115
+ * and passed to the `use` function via the failure array (unless `throwOnFirstError` is true).
116
+ *
98
117
  * @param type - the model type to load
99
118
  * @param select - selection params including keys array, roles, and use function
100
119
  * @returns the result of the use function