@dereekb/firebase-server 13.6.17 → 13.8.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.
- package/index.cjs.js +4233 -1923
- package/index.esm.js +4204 -1904
- package/mailgun/index.cjs.js +91 -1
- package/mailgun/index.esm.js +92 -3
- package/mailgun/package.json +9 -9
- package/mailgun/src/lib/auth.mailgun.d.ts +37 -1
- package/model/package.json +10 -10
- package/model/src/lib/storagefile/storagefile.action.server.d.ts +1 -1
- package/oidc/index.cjs.js +245 -180
- package/oidc/index.esm.js +242 -178
- package/oidc/package.json +12 -12
- package/oidc/src/lib/middleware/oauth-auth.module.d.ts +18 -25
- package/package.json +15 -14
- package/src/lib/auth/auth.service.d.ts +233 -0
- package/src/lib/auth/auth.service.error.d.ts +29 -0
- package/src/lib/auth/auth.service.error.util.d.ts +40 -0
- package/src/lib/auth/index.d.ts +1 -0
- package/src/lib/function/error.d.ts +11 -28
- package/src/lib/nest/app.d.ts +4 -45
- package/src/lib/nest/app.module.d.ts +4 -2
- package/src/lib/nest/auth/auth.util.d.ts +71 -5
- package/src/lib/nest/controller/index.d.ts +1 -0
- package/src/lib/nest/controller/model/index.d.ts +4 -0
- package/src/lib/nest/controller/model/model.api.controller.d.ts +93 -0
- package/src/lib/nest/controller/model/model.api.dispatch.d.ts +73 -0
- package/src/lib/nest/controller/model/model.api.get.service.d.ts +73 -0
- package/src/lib/nest/controller/model/model.api.module.d.ts +32 -0
- package/src/lib/nest/model/analytics.handler.d.ts +2 -0
- package/src/lib/nest/model/api.details.d.ts +53 -1
- package/src/lib/nest/model/call.model.function.d.ts +8 -5
- package/src/lib/nest/model/create.model.function.d.ts +1 -1
- package/src/lib/nest/model/crud.assert.function.d.ts +1 -1
- package/src/lib/nest/model/delete.model.function.d.ts +1 -1
- package/src/lib/nest/model/index.d.ts +1 -0
- package/src/lib/nest/model/query.model.function.d.ts +207 -0
- package/src/lib/nest/model/read.model.function.d.ts +1 -1
- package/src/lib/nest/model/update.model.function.d.ts +1 -1
- package/src/lib/nest/nest.provider.d.ts +19 -0
- package/test/index.cjs.js +1358 -398
- package/test/index.esm.js +1355 -400
- package/test/package.json +14 -12
- package/test/src/lib/firebase/firebase.test.d.ts +1 -1
- package/test/src/lib/index.d.ts +1 -0
- package/test/src/lib/oidc/index.d.ts +2 -0
- package/test/src/lib/oidc/oidc.test.fixture.d.ts +126 -0
- package/test/src/lib/oidc/oidc.test.flow.d.ts +43 -0
- package/zoho/package.json +9 -9
|
@@ -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
|
|
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
|
|
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
|