@mxpicture/gcp-functions-backend 1.1.3 → 1.1.5

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.
@@ -2,19 +2,74 @@ import type { DocumentData, WithKey, ApiFromRoutes, CrudRoutes, WithoutKey, Docu
2
2
  import { Store } from "../store/Store.js";
3
3
  import type { Validation } from "../validation/Validation.js";
4
4
  import { IBackendApi } from "./IBackendApi.js";
5
+ /**
6
+ * Backend API providing standard CRUD operations for a document type.
7
+ *
8
+ * @remarks
9
+ * Extends {@link IBackendApi} and implements all routes defined by {@link CrudRoutes}.
10
+ * Delegates persistence to a {@link Store} and input validation to a {@link Validation} instance.
11
+ *
12
+ * @typeParam DTO - The document data transfer object type.
13
+ * @typeParam STORE - The store implementation used for persistence.
14
+ * @typeParam VAL - The validation implementation used for input validation.
15
+ */
5
16
  export declare class BackendApi<DTO extends DocumentData, STORE extends Store<DTO> = Store<DTO>, VAL extends Validation<DTO> = Validation<DTO>> extends IBackendApi<DTO, STORE, VAL> implements ApiFromRoutes<CrudRoutes<DTO>> {
17
+ /**
18
+ * Delete a document by its key.
19
+ *
20
+ * @param request - The document key identifying the document to delete.
21
+ * @returns An object confirming the deletion.
22
+ */
6
23
  delete(request: DocumentKey): Promise<{
7
24
  deleted: true;
8
25
  }>;
26
+ /**
27
+ * Retrieve a single document by its key.
28
+ *
29
+ * @param request - The document key identifying the document to retrieve.
30
+ * @returns The document including its key metadata.
31
+ */
9
32
  get(request: DocumentKey): Promise<WithKey<DTO>>;
33
+ /**
34
+ * Query documents with optional filters.
35
+ *
36
+ * @param request - Optional filter criteria to narrow the query results.
37
+ * @returns An array of documents matching the filter criteria.
38
+ */
10
39
  query(request?: ApiFilter | null): Promise<WithKey<DTO>[]>;
40
+ /**
41
+ * Count documents matching optional filter criteria.
42
+ *
43
+ * @param request - Optional filter criteria to narrow the count.
44
+ * @returns An object containing the count of matching documents.
45
+ */
11
46
  count(request?: ApiFilter | null): Promise<{
12
47
  count: number;
13
48
  }>;
49
+ /**
50
+ * Check whether a document exists by its key.
51
+ *
52
+ * @param request - The document key identifying the document to check.
53
+ * @returns An object indicating whether the document exists.
54
+ */
14
55
  exists(request: DocumentKey): Promise<{
15
56
  exists: boolean;
16
57
  }>;
58
+ /**
59
+ * Create a new document after validating the input.
60
+ *
61
+ * @param request - The document data without key metadata.
62
+ * @returns The newly created document including its generated key.
63
+ * @throws {@link HttpsError} if validation fails.
64
+ */
17
65
  create(request: WithoutKey<DTO>): Promise<WithKey<DTO>>;
66
+ /**
67
+ * Update an existing document after validating the partial input.
68
+ *
69
+ * @param request - The partial document data including the key of the document to update.
70
+ * @returns The updated document including its key metadata.
71
+ * @throws {@link HttpsError} if validation fails.
72
+ */
18
73
  update(request: WithKey<Partial<DTO>>): Promise<WithKey<DTO>>;
19
74
  }
20
75
  //# sourceMappingURL=BackendApi.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BackendApi.d.ts","sourceRoot":"","sources":["../../src/api/BackendApi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,OAAO,EACP,aAAa,EACb,UAAU,EACV,UAAU,EACV,WAAW,EACX,SAAS,EACV,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,qBAAa,UAAU,CACnB,GAAG,SAAS,YAAY,EACxB,KAAK,SAAS,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,EACrC,GAAG,SAAS,UAAU,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAE/C,SAAQ,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CACnC,YAAW,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAE5B,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,IAAI,CAAA;KAAE,CAAC;IAKxD,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAIhD,KAAK,CAAC,OAAO,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;IAI1D,KAAK,CAAC,OAAO,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAI7D,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;IAI1D,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAKvD,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;CAI3E"}
1
+ {"version":3,"file":"BackendApi.d.ts","sourceRoot":"","sources":["../../src/api/BackendApi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,OAAO,EACP,aAAa,EACb,UAAU,EACV,UAAU,EACV,WAAW,EACX,SAAS,EACV,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,qBAAa,UAAU,CACnB,GAAG,SAAS,YAAY,EACxB,KAAK,SAAS,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,EACrC,GAAG,SAAS,UAAU,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAE/C,SAAQ,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CACnC,YAAW,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAEzC;;;;;OAKG;IACU,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,IAAI,CAAA;KAAE,CAAC;IAKrE;;;;;OAKG;IACU,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAI7D;;;;;OAKG;IACU,KAAK,CAAC,OAAO,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;IAIvE;;;;;OAKG;IACU,KAAK,CAAC,OAAO,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAI1E;;;;;OAKG;IACU,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;IAIvE;;;;;;OAMG;IACU,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAKpE;;;;;;OAMG;IACU,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;CAI3E"}
@@ -1,25 +1,80 @@
1
1
  import { IBackendApi } from "./IBackendApi.js";
2
+ /**
3
+ * Backend API providing standard CRUD operations for a document type.
4
+ *
5
+ * @remarks
6
+ * Extends {@link IBackendApi} and implements all routes defined by {@link CrudRoutes}.
7
+ * Delegates persistence to a {@link Store} and input validation to a {@link Validation} instance.
8
+ *
9
+ * @typeParam DTO - The document data transfer object type.
10
+ * @typeParam STORE - The store implementation used for persistence.
11
+ * @typeParam VAL - The validation implementation used for input validation.
12
+ */
2
13
  export class BackendApi extends IBackendApi {
14
+ /**
15
+ * Delete a document by its key.
16
+ *
17
+ * @param request - The document key identifying the document to delete.
18
+ * @returns An object confirming the deletion.
19
+ */
3
20
  async delete(request) {
4
21
  await this.store().delete(request.id);
5
22
  return { deleted: true };
6
23
  }
24
+ /**
25
+ * Retrieve a single document by its key.
26
+ *
27
+ * @param request - The document key identifying the document to retrieve.
28
+ * @returns The document including its key metadata.
29
+ */
7
30
  async get(request) {
8
31
  return this.store().get(request.id);
9
32
  }
33
+ /**
34
+ * Query documents with optional filters.
35
+ *
36
+ * @param request - Optional filter criteria to narrow the query results.
37
+ * @returns An array of documents matching the filter criteria.
38
+ */
10
39
  async query(request) {
11
40
  return this.store().query(request?.filters);
12
41
  }
42
+ /**
43
+ * Count documents matching optional filter criteria.
44
+ *
45
+ * @param request - Optional filter criteria to narrow the count.
46
+ * @returns An object containing the count of matching documents.
47
+ */
13
48
  async count(request) {
14
49
  return { count: await this.store().count(request?.filters) };
15
50
  }
51
+ /**
52
+ * Check whether a document exists by its key.
53
+ *
54
+ * @param request - The document key identifying the document to check.
55
+ * @returns An object indicating whether the document exists.
56
+ */
16
57
  async exists(request) {
17
58
  return { exists: await this.store().exists(request.id) };
18
59
  }
60
+ /**
61
+ * Create a new document after validating the input.
62
+ *
63
+ * @param request - The document data without key metadata.
64
+ * @returns The newly created document including its generated key.
65
+ * @throws {@link HttpsError} if validation fails.
66
+ */
19
67
  async create(request) {
20
68
  const result = this.validation().validate(request);
21
69
  return this.store().create(result);
22
70
  }
71
+ /**
72
+ * Update an existing document after validating the partial input.
73
+ *
74
+ * @param request - The partial document data including the key of the document to update.
75
+ * @returns The updated document including its key metadata.
76
+ * @throws {@link HttpsError} if validation fails.
77
+ */
23
78
  async update(request) {
24
79
  const result = this.validation().validatePartial(request);
25
80
  return this.store().update(request.id, result);
@@ -1 +1 @@
1
- {"version":3,"file":"BackendApi.js","sourceRoot":"","sources":["../../src/api/BackendApi.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,OAAO,UAKX,SAAQ,WAA4B;IAG7B,KAAK,CAAC,MAAM,CAAC,OAAoB;QACtC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACtC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,OAAoB;QACnC,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC;IAEM,KAAK,CAAC,KAAK,CAAC,OAA0B;QAC3C,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAEM,KAAK,CAAC,KAAK,CAAC,OAA0B;QAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;IAC/D,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,OAAoB;QACtC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;IAC3D,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,OAAwB;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,OAA8B;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACjD,CAAC;CACF"}
1
+ {"version":3,"file":"BackendApi.js","sourceRoot":"","sources":["../../src/api/BackendApi.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,MAAM,OAAO,UAKX,SAAQ,WAA4B;IAGpC;;;;;OAKG;IACI,KAAK,CAAC,MAAM,CAAC,OAAoB;QACtC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACtC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,GAAG,CAAC,OAAoB;QACnC,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,KAAK,CAAC,OAA0B;QAC3C,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,KAAK,CAAC,OAA0B;QAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;IAC/D,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,MAAM,CAAC,OAAoB;QACtC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;IAC3D,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,MAAM,CAAC,OAAwB;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,MAAM,CAAC,OAA8B;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACjD,CAAC;CACF"}
@@ -1,14 +1,53 @@
1
1
  import type { DocumentData } from "@mxpicture/gcp-functions-common/types";
2
2
  import { Store } from "../store/Store.js";
3
3
  import type { Validation } from "../validation/Validation.js";
4
+ /**
5
+ * Abstract base class for backend API implementations.
6
+ *
7
+ * @remarks
8
+ * Provides dependency-injection points for a {@link Store} and {@link Validation} instance.
9
+ * Subclasses implement the concrete API methods while relying on the injected store and
10
+ * validation via {@link IBackendApi.useStore} and {@link IBackendApi.useValidation}.
11
+ *
12
+ * @typeParam DTO - The document data transfer object type.
13
+ * @typeParam STORE - The store implementation used for persistence.
14
+ * @typeParam VAL - The validation implementation used for input validation.
15
+ */
4
16
  export declare abstract class IBackendApi<DTO extends DocumentData, STORE extends Store<DTO> = Store<DTO>, VAL extends Validation<DTO> = Validation<DTO>> {
5
17
  readonly name: string;
6
18
  protected _store?: STORE;
7
19
  protected _validation?: VAL;
20
+ /**
21
+ * Create a new backend API instance.
22
+ *
23
+ * @param name - A descriptive name for this API, used in error messages.
24
+ */
8
25
  constructor(name: string);
26
+ /**
27
+ * Inject the store instance used for data persistence.
28
+ *
29
+ * @param store - The store to use for persistence operations.
30
+ */
9
31
  useStore(store: STORE): void;
32
+ /**
33
+ * Inject the validation instance used for input validation.
34
+ *
35
+ * @param validation - The validation to use for input checking.
36
+ */
10
37
  useValidation(validation: VAL): void;
38
+ /**
39
+ * Retrieve the injected store instance.
40
+ *
41
+ * @returns The store instance.
42
+ * @throws {@link Error} if no store has been provided via {@link useStore}.
43
+ */
11
44
  protected store(): STORE;
45
+ /**
46
+ * Retrieve the injected validation instance.
47
+ *
48
+ * @returns The validation instance.
49
+ * @throws {@link Error} if no validation has been provided via {@link useValidation}.
50
+ */
12
51
  protected validation(): VAL;
13
52
  }
14
53
  //# sourceMappingURL=IBackendApi.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IBackendApi.d.ts","sourceRoot":"","sources":["../../src/api/IBackendApi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,8BAAsB,WAAW,CAC/B,GAAG,SAAS,YAAY,EACxB,KAAK,SAAS,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,EACrC,GAAG,SAAS,UAAU,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC;aAKV,IAAI,EAAE,MAAM;IAH/C,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC;IACzB,SAAS,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC;gBAEO,IAAI,EAAE,MAAM;IAExC,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAI5B,aAAa,CAAC,UAAU,EAAE,GAAG,GAAG,IAAI;IAI3C,SAAS,CAAC,KAAK,IAAI,KAAK;IAQxB,SAAS,CAAC,UAAU,IAAI,GAAG;CAO5B"}
1
+ {"version":3,"file":"IBackendApi.d.ts","sourceRoot":"","sources":["../../src/api/IBackendApi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D;;;;;;;;;;;GAWG;AACH,8BAAsB,WAAW,CAC/B,GAAG,SAAS,YAAY,EACxB,KAAK,SAAS,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,EACrC,GAAG,SAAS,UAAU,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC;aAUV,IAAI,EAAE,MAAM;IAR/C,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC;IACzB,SAAS,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC;IAE5B;;;;OAIG;gBACgC,IAAI,EAAE,MAAM;IAE/C;;;;OAIG;IACI,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAInC;;;;OAIG;IACI,aAAa,CAAC,UAAU,EAAE,GAAG,GAAG,IAAI;IAI3C;;;;;OAKG;IACH,SAAS,CAAC,KAAK,IAAI,KAAK;IAQxB;;;;;OAKG;IACH,SAAS,CAAC,UAAU,IAAI,GAAG;CAO5B"}
@@ -1,21 +1,60 @@
1
+ /**
2
+ * Abstract base class for backend API implementations.
3
+ *
4
+ * @remarks
5
+ * Provides dependency-injection points for a {@link Store} and {@link Validation} instance.
6
+ * Subclasses implement the concrete API methods while relying on the injected store and
7
+ * validation via {@link IBackendApi.useStore} and {@link IBackendApi.useValidation}.
8
+ *
9
+ * @typeParam DTO - The document data transfer object type.
10
+ * @typeParam STORE - The store implementation used for persistence.
11
+ * @typeParam VAL - The validation implementation used for input validation.
12
+ */
1
13
  export class IBackendApi {
2
14
  name;
3
15
  _store;
4
16
  _validation;
17
+ /**
18
+ * Create a new backend API instance.
19
+ *
20
+ * @param name - A descriptive name for this API, used in error messages.
21
+ */
5
22
  constructor(name) {
6
23
  this.name = name;
7
24
  }
25
+ /**
26
+ * Inject the store instance used for data persistence.
27
+ *
28
+ * @param store - The store to use for persistence operations.
29
+ */
8
30
  useStore(store) {
9
31
  this._store = store;
10
32
  }
33
+ /**
34
+ * Inject the validation instance used for input validation.
35
+ *
36
+ * @param validation - The validation to use for input checking.
37
+ */
11
38
  useValidation(validation) {
12
39
  this._validation = validation;
13
40
  }
41
+ /**
42
+ * Retrieve the injected store instance.
43
+ *
44
+ * @returns The store instance.
45
+ * @throws {@link Error} if no store has been provided via {@link useStore}.
46
+ */
14
47
  store() {
15
48
  if (!this._store)
16
49
  throw new Error(`${this.name}: store not provided. Use "useStore" method`);
17
50
  return this._store;
18
51
  }
52
+ /**
53
+ * Retrieve the injected validation instance.
54
+ *
55
+ * @returns The validation instance.
56
+ * @throws {@link Error} if no validation has been provided via {@link useValidation}.
57
+ */
19
58
  validation() {
20
59
  if (!this._validation)
21
60
  throw new Error(`${this.name}: validation not provided. Use "useValidation" method`);
@@ -1 +1 @@
1
- {"version":3,"file":"IBackendApi.js","sourceRoot":"","sources":["../../src/api/IBackendApi.ts"],"names":[],"mappings":"AAIA,MAAM,OAAgB,WAAW;IAQI;IAHzB,MAAM,CAAS;IACf,WAAW,CAAO;IAE5B,YAAmC,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IAE5C,QAAQ,CAAC,KAAY;QAC1B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAEM,aAAa,CAAC,UAAe;QAClC,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;IAChC,CAAC;IAES,KAAK;QACb,IAAI,CAAC,IAAI,CAAC,MAAM;YACd,MAAM,IAAI,KAAK,CACb,GAAG,IAAI,CAAC,IAAI,6CAA6C,CAC1D,CAAC;QACJ,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAES,UAAU;QAClB,IAAI,CAAC,IAAI,CAAC,WAAW;YACnB,MAAM,IAAI,KAAK,CACb,GAAG,IAAI,CAAC,IAAI,uDAAuD,CACpE,CAAC;QACJ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF"}
1
+ {"version":3,"file":"IBackendApi.js","sourceRoot":"","sources":["../../src/api/IBackendApi.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AACH,MAAM,OAAgB,WAAW;IAaI;IARzB,MAAM,CAAS;IACf,WAAW,CAAO;IAE5B;;;;OAIG;IACH,YAAmC,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IAEnD;;;;OAIG;IACI,QAAQ,CAAC,KAAY;QAC1B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED;;;;OAIG;IACI,aAAa,CAAC,UAAe;QAClC,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;IAChC,CAAC;IAED;;;;;OAKG;IACO,KAAK;QACb,IAAI,CAAC,IAAI,CAAC,MAAM;YACd,MAAM,IAAI,KAAK,CACb,GAAG,IAAI,CAAC,IAAI,6CAA6C,CAC1D,CAAC;QACJ,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;;;;OAKG;IACO,UAAU;QAClB,IAAI,CAAC,IAAI,CAAC,WAAW;YACnB,MAAM,IAAI,KAAK,CACb,GAAG,IAAI,CAAC,IAAI,uDAAuD,CACpE,CAAC;QACJ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF"}
@@ -1,3 +1,5 @@
1
+ /** The default Firebase Admin application instance. */
1
2
  export declare const app: import("firebase-admin/app").App;
3
+ /** The default Firestore database instance. */
2
4
  export declare const db: FirebaseFirestore.Firestore;
3
5
  //# sourceMappingURL=firebase.backend.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"firebase.backend.d.ts","sourceRoot":"","sources":["../../src/firebase/firebase.backend.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,GAAG,kCAAkB,CAAC;AACnC,eAAO,MAAM,EAAE,6BAAiB,CAAC"}
1
+ {"version":3,"file":"firebase.backend.d.ts","sourceRoot":"","sources":["../../src/firebase/firebase.backend.ts"],"names":[],"mappings":"AAGA,uDAAuD;AACvD,eAAO,MAAM,GAAG,kCAAkB,CAAC;AAEnC,+CAA+C;AAC/C,eAAO,MAAM,EAAE,6BAAiB,CAAC"}
@@ -1,5 +1,7 @@
1
1
  import { getFirestore } from "firebase-admin/firestore";
2
2
  import { initializeApp } from "firebase-admin/app";
3
+ /** The default Firebase Admin application instance. */
3
4
  export const app = initializeApp();
5
+ /** The default Firestore database instance. */
4
6
  export const db = getFirestore();
5
7
  //# sourceMappingURL=firebase.backend.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"firebase.backend.js","sourceRoot":"","sources":["../../src/firebase/firebase.backend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,CAAC,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;AACnC,MAAM,CAAC,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"firebase.backend.js","sourceRoot":"","sources":["../../src/firebase/firebase.backend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,uDAAuD;AACvD,MAAM,CAAC,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;AAEnC,+CAA+C;AAC/C,MAAM,CAAC,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC"}
@@ -1,6 +1,17 @@
1
1
  import type { DocumentData, FunctionRequest, FunctionResponse } from "@mxpicture/gcp-functions-common/types";
2
2
  import { BackendApi } from "../api/BackendApi.js";
3
3
  import { CallableFunction } from "firebase-functions/v2/https";
4
+ /**
5
+ * Abstract base class for Firebase callable backend functions.
6
+ *
7
+ * @remarks
8
+ * Encapsulates the wiring between an incoming callable request and a {@link BackendApi}.
9
+ * Subclasses configure the API, routes, region, and service account, then call
10
+ * {@link IBackendFunction.buildFunction} to produce a deployable Cloud Function.
11
+ *
12
+ * @typeParam DTO - The document data transfer object type.
13
+ * @typeParam API - The backend API implementation that handles route logic.
14
+ */
4
15
  export declare abstract class IBackendFunction<DTO extends DocumentData, API extends BackendApi<DTO>> {
5
16
  readonly name: string;
6
17
  readonly region: string;
@@ -8,14 +19,67 @@ export declare abstract class IBackendFunction<DTO extends DocumentData, API ext
8
19
  protected readonly datePaths: string[];
9
20
  protected _api?: API;
10
21
  protected _routes?: string[];
22
+ /**
23
+ * Create a new backend function instance.
24
+ *
25
+ * @param name - A descriptive name for this function, used in error messages.
26
+ * @param region - The GCP region in which the function is deployed.
27
+ * @param serviceAccount - The service account email used to run the function.
28
+ * @param datePaths - JSON paths within the response payload that contain date values to convert to Firestore Timestamps.
29
+ */
11
30
  constructor(name: string, region: string, serviceAccount: string, datePaths: string[]);
31
+ /**
32
+ * Inject the backend API instance that handles route logic.
33
+ *
34
+ * @param api - The API instance to delegate requests to.
35
+ */
12
36
  useApi(api: API): void;
37
+ /**
38
+ * Register the allowed route names for this function.
39
+ *
40
+ * @param routes - An array of route names or a record whose values are route names.
41
+ */
13
42
  useRoutes(routes: {
14
43
  [key: string]: string;
15
44
  } | string[]): void;
45
+ /**
46
+ * Retrieve the injected API instance.
47
+ *
48
+ * @returns The API instance.
49
+ * @throws {@link Error} if no API has been provided via {@link useApi}.
50
+ */
16
51
  protected api(): API;
52
+ /**
53
+ * Retrieve the registered route names.
54
+ *
55
+ * @returns The array of allowed route names.
56
+ * @throws {@link Error} if no routes have been provided via {@link useRoutes}.
57
+ */
17
58
  protected routes(): string[];
59
+ /**
60
+ * Route an incoming function request to the appropriate API method.
61
+ *
62
+ * @remarks
63
+ * Validates that the requested route is registered, delegates to the API, and
64
+ * converts date fields in the response payload to Firestore Timestamps.
65
+ *
66
+ * @typeParam REQ - The request payload type.
67
+ * @typeParam RES - The response document data type.
68
+ * @param request - The incoming function request containing route and data.
69
+ * @returns The function response wrapping the API result.
70
+ * @throws {@link HttpsError} with `invalid-argument` if the route is not registered.
71
+ * @throws {@link HttpsError} with `internal` if the API method throws an unexpected error.
72
+ */
18
73
  ingress<REQ, RES extends DocumentData>(request: FunctionRequest<REQ>): Promise<FunctionResponse<RES>>;
74
+ /**
75
+ * Build and return a Firebase callable Cloud Function.
76
+ *
77
+ * @remarks
78
+ * Wraps {@link ingress} in a Firebase `onCall` handler configured with the
79
+ * specified region and service account.
80
+ *
81
+ * @returns A Firebase {@link CallableFunction} ready for deployment.
82
+ */
19
83
  buildFunction(): CallableFunction<FunctionRequest<any>, Promise<FunctionResponse<any>>>;
20
84
  }
21
85
  //# sourceMappingURL=IBackendFunction.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IBackendFunction.d.ts","sourceRoot":"","sources":["../../src/function/IBackendFunction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EACjB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAEL,gBAAgB,EAEjB,MAAM,6BAA6B,CAAC;AAGrC,8BAAsB,gBAAgB,CACpC,GAAG,SAAS,YAAY,EACxB,GAAG,SAAS,UAAU,CAAC,GAAG,CAAC;aAMT,IAAI,EAAE,MAAM;aACZ,MAAM,EAAE,MAAM;aACd,cAAc,EAAE,MAAM;IACtC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE;IAPxC,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC;IACrB,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;gBAGX,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EAAE;IAGjC,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAItB,SAAS,CAAC,MAAM,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,MAAM,EAAE,GAAG,IAAI;IAIpE,SAAS,CAAC,GAAG,IAAI,GAAG;IAMpB,SAAS,CAAC,MAAM,IAAI,MAAM,EAAE;IAQf,OAAO,CAAC,GAAG,EAAE,GAAG,SAAS,YAAY,EAChD,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC,GAC5B,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAoB1B,aAAa,IAAI,gBAAgB,CAEtC,eAAe,CAAC,GAAG,CAAC,EAEpB,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAC/B;CAMF"}
1
+ {"version":3,"file":"IBackendFunction.d.ts","sourceRoot":"","sources":["../../src/function/IBackendFunction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EACjB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAEL,gBAAgB,EAEjB,MAAM,6BAA6B,CAAC;AAMrC;;;;;;;;;;GAUG;AACH,8BAAsB,gBAAgB,CACpC,GAAG,SAAS,YAAY,EACxB,GAAG,SAAS,UAAU,CAAC,GAAG,CAAC;aAcT,IAAI,EAAE,MAAM;aACZ,MAAM,EAAE,MAAM;aACd,cAAc,EAAE,MAAM;IACtC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE;IAfxC,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC;IACrB,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAE7B;;;;;;;OAOG;gBAEe,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EAAE;IAGxC;;;;OAIG;IACI,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAI7B;;;;OAIG;IACI,SAAS,CAAC,MAAM,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,MAAM,EAAE,GAAG,IAAI;IAIpE;;;;;OAKG;IACH,SAAS,CAAC,GAAG,IAAI,GAAG;IAMpB;;;;;OAKG;IACH,SAAS,CAAC,MAAM,IAAI,MAAM,EAAE;IAQ5B;;;;;;;;;;;;;OAaG;IACU,OAAO,CAAC,GAAG,EAAE,GAAG,SAAS,YAAY,EAChD,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC,GAC5B,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAsBjC;;;;;;;;OAQG;IACI,aAAa,IAAI,gBAAgB,CAEtC,eAAe,CAAC,GAAG,CAAC,EAEpB,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAC/B;CAMF"}
@@ -1,5 +1,16 @@
1
1
  import { onCall, HttpsError, } from "firebase-functions/v2/https";
2
- import { toTimestampsDeep } from "@mxpicture/gcp-functions-common/helper";
2
+ import { toDatesDeep, toTimestampsDeep, } from "@mxpicture/gcp-functions-common/helper";
3
+ /**
4
+ * Abstract base class for Firebase callable backend functions.
5
+ *
6
+ * @remarks
7
+ * Encapsulates the wiring between an incoming callable request and a {@link BackendApi}.
8
+ * Subclasses configure the API, routes, region, and service account, then call
9
+ * {@link IBackendFunction.buildFunction} to produce a deployable Cloud Function.
10
+ *
11
+ * @typeParam DTO - The document data transfer object type.
12
+ * @typeParam API - The backend API implementation that handles route logic.
13
+ */
3
14
  export class IBackendFunction {
4
15
  name;
5
16
  region;
@@ -7,35 +18,80 @@ export class IBackendFunction {
7
18
  datePaths;
8
19
  _api;
9
20
  _routes;
21
+ /**
22
+ * Create a new backend function instance.
23
+ *
24
+ * @param name - A descriptive name for this function, used in error messages.
25
+ * @param region - The GCP region in which the function is deployed.
26
+ * @param serviceAccount - The service account email used to run the function.
27
+ * @param datePaths - JSON paths within the response payload that contain date values to convert to Firestore Timestamps.
28
+ */
10
29
  constructor(name, region, serviceAccount, datePaths) {
11
30
  this.name = name;
12
31
  this.region = region;
13
32
  this.serviceAccount = serviceAccount;
14
33
  this.datePaths = datePaths;
15
34
  }
35
+ /**
36
+ * Inject the backend API instance that handles route logic.
37
+ *
38
+ * @param api - The API instance to delegate requests to.
39
+ */
16
40
  useApi(api) {
17
41
  this._api = api;
18
42
  }
43
+ /**
44
+ * Register the allowed route names for this function.
45
+ *
46
+ * @param routes - An array of route names or a record whose values are route names.
47
+ */
19
48
  useRoutes(routes) {
20
49
  this._routes = Array.isArray(routes) ? routes : Object.values(routes);
21
50
  }
51
+ /**
52
+ * Retrieve the injected API instance.
53
+ *
54
+ * @returns The API instance.
55
+ * @throws {@link Error} if no API has been provided via {@link useApi}.
56
+ */
22
57
  api() {
23
58
  if (!this._api)
24
59
  throw new Error(`${this.name}: api not provided. Use "useApi" method`);
25
60
  return this._api;
26
61
  }
62
+ /**
63
+ * Retrieve the registered route names.
64
+ *
65
+ * @returns The array of allowed route names.
66
+ * @throws {@link Error} if no routes have been provided via {@link useRoutes}.
67
+ */
27
68
  routes() {
28
69
  if (!this._routes)
29
70
  throw new Error(`${this.name}: routes not provided. Use "useRoutes" method`);
30
71
  return this._routes;
31
72
  }
73
+ /**
74
+ * Route an incoming function request to the appropriate API method.
75
+ *
76
+ * @remarks
77
+ * Validates that the requested route is registered, delegates to the API, and
78
+ * converts date fields in the response payload to Firestore Timestamps.
79
+ *
80
+ * @typeParam REQ - The request payload type.
81
+ * @typeParam RES - The response document data type.
82
+ * @param request - The incoming function request containing route and data.
83
+ * @returns The function response wrapping the API result.
84
+ * @throws {@link HttpsError} with `invalid-argument` if the route is not registered.
85
+ * @throws {@link HttpsError} with `internal` if the API method throws an unexpected error.
86
+ */
32
87
  async ingress(request) {
33
88
  const routes = this.routes();
34
89
  if (!routes.find((m) => m === request.route))
35
90
  throw new HttpsError("invalid-argument", `Route ${request.route} not available`);
36
91
  try {
92
+ const requestData = toDatesDeep(request.data, this.datePaths);
37
93
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
- const payload = await this.api()[request.route](request.data);
94
+ const payload = await this.api()[request.route](requestData);
39
95
  return { data: toTimestampsDeep(payload, this.datePaths) };
40
96
  }
41
97
  catch (error) {
@@ -46,6 +102,15 @@ export class IBackendFunction {
46
102
  // }
47
103
  }
48
104
  }
105
+ /**
106
+ * Build and return a Firebase callable Cloud Function.
107
+ *
108
+ * @remarks
109
+ * Wraps {@link ingress} in a Firebase `onCall` handler configured with the
110
+ * specified region and service account.
111
+ *
112
+ * @returns A Firebase {@link CallableFunction} ready for deployment.
113
+ */
49
114
  buildFunction() {
50
115
  return onCall({ region: this.region, serviceAccount: this.serviceAccount }, async (req) => this.ingress(req.data));
51
116
  }
@@ -1 +1 @@
1
- {"version":3,"file":"IBackendFunction.js","sourceRoot":"","sources":["../../src/function/IBackendFunction.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,MAAM,EAEN,UAAU,GACX,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAE1E,MAAM,OAAgB,gBAAgB;IAQlB;IACA;IACA;IACG;IAPX,IAAI,CAAO;IACX,OAAO,CAAY;IAE7B,YACkB,IAAY,EACZ,MAAc,EACd,cAAsB,EACnB,SAAmB;QAHtB,SAAI,GAAJ,IAAI,CAAQ;QACZ,WAAM,GAAN,MAAM,CAAQ;QACd,mBAAc,GAAd,cAAc,CAAQ;QACnB,cAAS,GAAT,SAAS,CAAU;IACrC,CAAC;IAEG,MAAM,CAAC,GAAQ;QACpB,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;IAClB,CAAC;IAEM,SAAS,CAAC,MAA4C;QAC3D,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxE,CAAC;IAES,GAAG;QACX,IAAI,CAAC,IAAI,CAAC,IAAI;YACZ,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,yCAAyC,CAAC,CAAC;QACzE,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAES,MAAM;QACd,IAAI,CAAC,IAAI,CAAC,OAAO;YACf,MAAM,IAAI,KAAK,CACb,GAAG,IAAI,CAAC,IAAI,+CAA+C,CAC5D,CAAC;QACJ,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAEM,KAAK,CAAC,OAAO,CAClB,OAA6B;QAE7B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC;YAC1C,MAAM,IAAI,UAAU,CAClB,kBAAkB,EAClB,SAAS,OAAO,CAAC,KAAK,gBAAgB,CACvC,CAAC;QAEJ,IAAI,CAAC;YACH,8DAA8D;YAC9D,MAAM,OAAO,GAAG,MAAO,IAAI,CAAC,GAAG,EAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACvE,OAAO,EAAE,IAAI,EAAE,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,UAAU;gBAAE,MAAM,KAAK,CAAC;YAC7C,8DAA8D;YAC9D,MAAM,IAAI,UAAU,CAAC,UAAU,EAAG,KAAa,EAAE,OAAO,IAAI,SAAS,CAAC,CAAC;YACvE,IAAI;QACN,CAAC;IACH,CAAC;IAEM,aAAa;QAMlB,OAAO,MAAM,CACX,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,EAC5D,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CACtC,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"IBackendFunction.js","sourceRoot":"","sources":["../../src/function/IBackendFunction.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,MAAM,EAEN,UAAU,GACX,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,WAAW,EACX,gBAAgB,GACjB,MAAM,wCAAwC,CAAC;AAEhD;;;;;;;;;;GAUG;AACH,MAAM,OAAgB,gBAAgB;IAgBlB;IACA;IACA;IACG;IAfX,IAAI,CAAO;IACX,OAAO,CAAY;IAE7B;;;;;;;OAOG;IACH,YACkB,IAAY,EACZ,MAAc,EACd,cAAsB,EACnB,SAAmB;QAHtB,SAAI,GAAJ,IAAI,CAAQ;QACZ,WAAM,GAAN,MAAM,CAAQ;QACd,mBAAc,GAAd,cAAc,CAAQ;QACnB,cAAS,GAAT,SAAS,CAAU;IACrC,CAAC;IAEJ;;;;OAIG;IACI,MAAM,CAAC,GAAQ;QACpB,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;IAClB,CAAC;IAED;;;;OAIG;IACI,SAAS,CAAC,MAA4C;QAC3D,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACO,GAAG;QACX,IAAI,CAAC,IAAI,CAAC,IAAI;YACZ,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,yCAAyC,CAAC,CAAC;QACzE,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACO,MAAM;QACd,IAAI,CAAC,IAAI,CAAC,OAAO;YACf,MAAM,IAAI,KAAK,CACb,GAAG,IAAI,CAAC,IAAI,+CAA+C,CAC5D,CAAC;QACJ,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;;;;;;;;;;;OAaG;IACI,KAAK,CAAC,OAAO,CAClB,OAA6B;QAE7B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC;YAC1C,MAAM,IAAI,UAAU,CAClB,kBAAkB,EAClB,SAAS,OAAO,CAAC,KAAK,gBAAgB,CACvC,CAAC;QAEJ,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAE9D,8DAA8D;YAC9D,MAAM,OAAO,GAAG,MAAO,IAAI,CAAC,GAAG,EAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC;YACtE,OAAO,EAAE,IAAI,EAAE,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,UAAU;gBAAE,MAAM,KAAK,CAAC;YAC7C,8DAA8D;YAC9D,MAAM,IAAI,UAAU,CAAC,UAAU,EAAG,KAAa,EAAE,OAAO,IAAI,SAAS,CAAC,CAAC;YACvE,IAAI;QACN,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACI,aAAa;QAMlB,OAAO,MAAM,CACX,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,EAC5D,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CACtC,CAAC;IACJ,CAAC;CACF"}
@@ -1,24 +1,114 @@
1
1
  import { CollectionReference, DocumentReference, FirestoreDataConverter, Query, QuerySnapshot } from "firebase-admin/firestore";
2
2
  import type { ApiFilterItems, DocumentData, WithKey } from "@mxpicture/gcp-functions-common/types";
3
+ /**
4
+ * Firestore-backed data store for a document type.
5
+ *
6
+ * @remarks
7
+ * Provides CRUD operations and query helpers against a namespaced Firestore collection.
8
+ * The collection path is derived as `{namespace}.{collectionName}`.
9
+ *
10
+ * @typeParam DTO - The document data transfer object type.
11
+ */
3
12
  export declare class Store<DTO extends DocumentData> {
4
13
  readonly collectionName: string;
5
14
  readonly namespace: string;
6
15
  protected readonly converter?: FirestoreDataConverter<DTO> | undefined;
7
16
  protected _db?: CollectionReference<DTO>;
17
+ /**
18
+ * Create a new Store instance.
19
+ *
20
+ * @param collectionName - The Firestore collection name.
21
+ * @param namespace - A namespace prefix for the collection path.
22
+ * @param converter - An optional Firestore data converter for custom serialization.
23
+ */
8
24
  constructor(collectionName: string, namespace: string, converter?: FirestoreDataConverter<DTO> | undefined);
25
+ /**
26
+ * Get or lazily initialize the Firestore collection reference.
27
+ *
28
+ * @returns The typed Firestore collection reference.
29
+ */
9
30
  db(): CollectionReference<DTO>;
31
+ /**
32
+ * Query documents, optionally filtered by parent ID.
33
+ *
34
+ * @param p - Optional filter items; when `parentId` is set, queries by parent.
35
+ * @returns An array of documents with key metadata.
36
+ */
10
37
  query(p?: ApiFilterItems): Promise<WithKey<DTO>[]>;
38
+ /**
39
+ * Execute a Firestore query and return the raw snapshot.
40
+ *
41
+ * @remarks
42
+ * Supports filtering by `parentId` or by arbitrary field-level filters.
43
+ *
44
+ * @param p - Optional filter items to apply.
45
+ * @returns The Firestore query snapshot.
46
+ */
11
47
  protected querySnapshot(p?: ApiFilterItems): Promise<QuerySnapshot<DTO>>;
48
+ /**
49
+ * Count documents, optionally filtered by parent ID.
50
+ *
51
+ * @param p - Optional object with a `parentId` to scope the count.
52
+ * @returns The number of matching documents.
53
+ */
12
54
  count(p?: {
13
55
  parentId?: string;
14
56
  }): Promise<number>;
57
+ /**
58
+ * Get a Firestore document reference by ID.
59
+ *
60
+ * @param id - The document ID.
61
+ * @returns The typed Firestore document reference.
62
+ */
15
63
  ref(id: string): DocumentReference<DTO>;
64
+ /**
65
+ * Retrieve a single document by ID.
66
+ *
67
+ * @param id - The document ID.
68
+ * @returns The document data including key metadata.
69
+ * @throws {@link Error} if the document does not exist or its data is invalid.
70
+ */
16
71
  get(id: string): Promise<WithKey<DTO>>;
72
+ /**
73
+ * Check whether a document exists by ID.
74
+ *
75
+ * @param id - The document ID.
76
+ * @returns `true` if the document exists, `false` otherwise.
77
+ */
17
78
  exists(id: string): Promise<boolean>;
79
+ /**
80
+ * Create a new document with an auto-generated short UUID.
81
+ *
82
+ * @param doc - The document data to persist.
83
+ * @returns The persisted document including its generated key metadata.
84
+ */
18
85
  create(doc: DTO): Promise<WithKey<DTO>>;
86
+ /**
87
+ * Update an existing document by merging partial data.
88
+ *
89
+ * @param id - The document ID to update.
90
+ * @param doc - The partial document data to merge.
91
+ * @returns The updated document including its key metadata.
92
+ */
19
93
  update(id: string, doc: Partial<DTO>): Promise<WithKey<DTO>>;
94
+ /**
95
+ * Delete one or more documents by their IDs.
96
+ *
97
+ * @param ids - The document IDs to delete.
98
+ */
20
99
  delete(...ids: string[]): Promise<void>;
100
+ /**
101
+ * Delete all documents that belong to a given parent.
102
+ *
103
+ * @param parentId - The parent document ID whose children should be deleted.
104
+ */
21
105
  deleteByParent(parentId: string): Promise<void>;
106
+ /**
107
+ * Build a Firestore query scoped to a specific parent document.
108
+ *
109
+ * @param parentId - The parent document ID to filter by.
110
+ * @returns A Firestore query filtering documents where `parentId` matches.
111
+ */
22
112
  refByParent(parentId: string): Query<DTO, FirebaseFirestore.DocumentData>;
23
113
  }
24
114
  //# sourceMappingURL=Store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Store.d.ts","sourceRoot":"","sources":["../../src/store/Store.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,KAAK,EACL,aAAa,EACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,OAAO,EACR,MAAM,uCAAuC,CAAC;AAE/C,qBAAa,KAAK,CAAC,GAAG,SAAS,YAAY;aAIvB,cAAc,EAAE,MAAM;aACtB,SAAS,EAAE,MAAM;IACjC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,sBAAsB,CAAC,GAAG,CAAC;IAL5D,SAAS,CAAC,GAAG,CAAC,EAAE,mBAAmB,CAAC,GAAG,CAAC,CAAC;gBAGvB,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,sBAAsB,CAAC,GAAG,CAAC,YAAA;IAGrD,EAAE,IAAI,mBAAmB,CAAC,GAAG,CAAC;IAaxB,KAAK,CAAC,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;cAc/C,aAAa,CAC3B,CAAC,CAAC,EAAE,cAAc,GACjB,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAcjB,KAAK,CAAC,CAAC,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IASvD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC;IAIjC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAWtC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIpC,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAOvC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAM5D,MAAM,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKrD,WAAW,CAAC,QAAQ,EAAE,MAAM;CAGpC"}
1
+ {"version":3,"file":"Store.d.ts","sourceRoot":"","sources":["../../src/store/Store.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,KAAK,EACL,aAAa,EACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,OAAO,EACR,MAAM,uCAAuC,CAAC;AAE/C;;;;;;;;GAQG;AACH,qBAAa,KAAK,CAAC,GAAG,SAAS,YAAY;aAWvB,cAAc,EAAE,MAAM;aACtB,SAAS,EAAE,MAAM;IACjC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,sBAAsB,CAAC,GAAG,CAAC;IAZ5D,SAAS,CAAC,GAAG,CAAC,EAAE,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAEzC;;;;;;OAMG;gBAEe,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,sBAAsB,CAAC,GAAG,CAAC,YAAA;IAG5D;;;;OAIG;IACI,EAAE,IAAI,mBAAmB,CAAC,GAAG,CAAC;IAarC;;;;;OAKG;IACU,KAAK,CAAC,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;IAc/D;;;;;;;;OAQG;cACa,aAAa,CAC3B,CAAC,CAAC,EAAE,cAAc,GACjB,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAc9B;;;;;OAKG;IACU,KAAK,CAAC,CAAC,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAS9D;;;;;OAKG;IACI,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC;IAI9C;;;;;;OAMG;IACU,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAWnD;;;;;OAKG;IACU,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIjD;;;;;OAKG;IACU,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAOpD;;;;;;OAMG;IACU,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAMzE;;;;OAIG;IACU,MAAM,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD;;;;OAIG;IACU,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5D;;;;;OAKG;IACI,WAAW,CAAC,QAAQ,EAAE,MAAM;CAGpC"}
@@ -1,15 +1,36 @@
1
1
  import { db as firestore } from "../firebase/firebase.backend.js";
2
2
  import * as uuid from "short-uuid";
3
+ /**
4
+ * Firestore-backed data store for a document type.
5
+ *
6
+ * @remarks
7
+ * Provides CRUD operations and query helpers against a namespaced Firestore collection.
8
+ * The collection path is derived as `{namespace}.{collectionName}`.
9
+ *
10
+ * @typeParam DTO - The document data transfer object type.
11
+ */
3
12
  export class Store {
4
13
  collectionName;
5
14
  namespace;
6
15
  converter;
7
16
  _db;
17
+ /**
18
+ * Create a new Store instance.
19
+ *
20
+ * @param collectionName - The Firestore collection name.
21
+ * @param namespace - A namespace prefix for the collection path.
22
+ * @param converter - An optional Firestore data converter for custom serialization.
23
+ */
8
24
  constructor(collectionName, namespace, converter) {
9
25
  this.collectionName = collectionName;
10
26
  this.namespace = namespace;
11
27
  this.converter = converter;
12
28
  }
29
+ /**
30
+ * Get or lazily initialize the Firestore collection reference.
31
+ *
32
+ * @returns The typed Firestore collection reference.
33
+ */
13
34
  db() {
14
35
  if (!this._db)
15
36
  if (this.converter)
@@ -20,6 +41,12 @@ export class Store {
20
41
  this._db = firestore.collection(`${this.namespace}.${this.collectionName}`);
21
42
  return this._db;
22
43
  }
44
+ /**
45
+ * Query documents, optionally filtered by parent ID.
46
+ *
47
+ * @param p - Optional filter items; when `parentId` is set, queries by parent.
48
+ * @returns An array of documents with key metadata.
49
+ */
23
50
  async query(p) {
24
51
  const snapshot = p && p.parentId
25
52
  ? await this.refByParent(p.parentId).get()
@@ -31,6 +58,15 @@ export class Store {
31
58
  updateTime: doc.updateTime.toDate(),
32
59
  }));
33
60
  }
61
+ /**
62
+ * Execute a Firestore query and return the raw snapshot.
63
+ *
64
+ * @remarks
65
+ * Supports filtering by `parentId` or by arbitrary field-level filters.
66
+ *
67
+ * @param p - Optional filter items to apply.
68
+ * @returns The Firestore query snapshot.
69
+ */
34
70
  async querySnapshot(p) {
35
71
  if (!p)
36
72
  return this.db().get();
@@ -47,15 +83,34 @@ export class Store {
47
83
  }
48
84
  return (query ?? this.db()).get();
49
85
  }
86
+ /**
87
+ * Count documents, optionally filtered by parent ID.
88
+ *
89
+ * @param p - Optional object with a `parentId` to scope the count.
90
+ * @returns The number of matching documents.
91
+ */
50
92
  async count(p) {
51
93
  const snapshot = p && p.parentId
52
94
  ? await this.refByParent(p.parentId).count().get()
53
95
  : await this.db().count().get();
54
96
  return snapshot.data().count;
55
97
  }
98
+ /**
99
+ * Get a Firestore document reference by ID.
100
+ *
101
+ * @param id - The document ID.
102
+ * @returns The typed Firestore document reference.
103
+ */
56
104
  ref(id) {
57
105
  return this.db().doc(id);
58
106
  }
107
+ /**
108
+ * Retrieve a single document by ID.
109
+ *
110
+ * @param id - The document ID.
111
+ * @returns The document data including key metadata.
112
+ * @throws {@link Error} if the document does not exist or its data is invalid.
113
+ */
59
114
  async get(id) {
60
115
  const snapshot = await this.ref(id).get();
61
116
  if (!snapshot.exists)
@@ -68,27 +123,62 @@ export class Store {
68
123
  data.createTime = snapshot.createTime?.toDate();
69
124
  return data;
70
125
  }
126
+ /**
127
+ * Check whether a document exists by ID.
128
+ *
129
+ * @param id - The document ID.
130
+ * @returns `true` if the document exists, `false` otherwise.
131
+ */
71
132
  async exists(id) {
72
133
  return (await this.ref(id).get()).exists;
73
134
  }
135
+ /**
136
+ * Create a new document with an auto-generated short UUID.
137
+ *
138
+ * @param doc - The document data to persist.
139
+ * @returns The persisted document including its generated key metadata.
140
+ */
74
141
  async create(doc) {
75
142
  const id = uuid.generate();
76
143
  const ref = this.ref(id);
77
144
  await ref.set(doc);
78
145
  return this.get(id);
79
146
  }
147
+ /**
148
+ * Update an existing document by merging partial data.
149
+ *
150
+ * @param id - The document ID to update.
151
+ * @param doc - The partial document data to merge.
152
+ * @returns The updated document including its key metadata.
153
+ */
80
154
  async update(id, doc) {
81
155
  const entry = this.ref(id);
82
156
  await entry.update({ ...doc });
83
157
  return this.get(id);
84
158
  }
159
+ /**
160
+ * Delete one or more documents by their IDs.
161
+ *
162
+ * @param ids - The document IDs to delete.
163
+ */
85
164
  async delete(...ids) {
86
165
  await Promise.all(ids.map((id) => this.ref(id).delete()));
87
166
  }
167
+ /**
168
+ * Delete all documents that belong to a given parent.
169
+ *
170
+ * @param parentId - The parent document ID whose children should be deleted.
171
+ */
88
172
  async deleteByParent(parentId) {
89
173
  const snapshot = await this.refByParent(parentId).get();
90
174
  await this.delete(...snapshot.docs.map((doc) => doc.id));
91
175
  }
176
+ /**
177
+ * Build a Firestore query scoped to a specific parent document.
178
+ *
179
+ * @param parentId - The parent document ID to filter by.
180
+ * @returns A Firestore query filtering documents where `parentId` matches.
181
+ */
92
182
  refByParent(parentId) {
93
183
  return this.db().where("parentId", "==", parentId);
94
184
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Store.js","sourceRoot":"","sources":["../../src/store/Store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Store.js","sourceRoot":"","sources":["../../src/store/Store.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,83 @@
1
1
  import { type ZodError, type ZodObject, type ZodRawShape } from "zod";
2
2
  import type { DocumentData, ValidationResult, WithKey, WithoutKey } from "@mxpicture/gcp-functions-common/types";
3
+ /**
4
+ * Zod-based validation for document data transfer objects.
5
+ *
6
+ * @remarks
7
+ * Uses a Zod shape to build create and update schemas. Admin-managed keys
8
+ * (e.g. `id`, `createTime`, `updateTime`) are automatically stripped from the
9
+ * create schema. The update schema is a partial version of the create schema.
10
+ *
11
+ * @typeParam DTO - The document data transfer object type.
12
+ */
3
13
  export declare class Validation<DTO extends DocumentData> {
4
14
  readonly name: string;
5
15
  protected _createSchema?: ZodObject;
6
16
  protected _updateSchema?: ZodObject;
7
17
  protected _shape?: ZodRawShape;
18
+ /**
19
+ * Create a new Validation instance.
20
+ *
21
+ * @param name - A descriptive name for this validator, used in error messages.
22
+ */
8
23
  constructor(name: string);
24
+ /**
25
+ * Inject the Zod shape used to build validation schemas.
26
+ *
27
+ * @param shape - The Zod raw shape describing the document fields.
28
+ */
9
29
  useShape(shape: ZodRawShape): void;
30
+ /**
31
+ * Retrieve the injected Zod shape.
32
+ *
33
+ * @returns The Zod raw shape.
34
+ * @throws {@link Error} if no shape has been provided via {@link useShape}.
35
+ */
10
36
  protected shape(): ZodRawShape;
37
+ /**
38
+ * Derive the Zod shape for create operations by removing admin-managed keys.
39
+ *
40
+ * @returns A copy of the base shape with admin keys removed.
41
+ */
11
42
  protected shape4Create(): ZodRawShape;
43
+ /**
44
+ * Get or lazily build the Zod schema used for create validation.
45
+ *
46
+ * @returns The Zod object schema for create operations.
47
+ */
12
48
  protected createSchema(): ZodObject;
49
+ /**
50
+ * Get or lazily build the Zod schema used for update validation.
51
+ *
52
+ * @remarks
53
+ * The update schema is the partial version of the create schema,
54
+ * making all fields optional.
55
+ *
56
+ * @returns The Zod object schema for update operations.
57
+ */
13
58
  protected updateSchema(): ZodObject;
59
+ /**
60
+ * Validate a complete document for creation.
61
+ *
62
+ * @param doc - The document data to validate.
63
+ * @returns The parsed and validated document data.
64
+ * @throws {@link HttpsError} with `invalid-argument` if validation fails.
65
+ */
14
66
  validate(doc: Partial<WithoutKey<DTO>>): WithKey<DTO>;
67
+ /**
68
+ * Validate a partial document for update operations.
69
+ *
70
+ * @param doc - The partial document data to validate.
71
+ * @returns The parsed and validated partial document data.
72
+ * @throws {@link HttpsError} with `invalid-argument` if validation fails.
73
+ */
15
74
  validatePartial(doc: Partial<WithKey<DTO>>): Partial<WithKey<DTO>>;
75
+ /**
76
+ * Convert Zod validation issues into a structured validation result.
77
+ *
78
+ * @param issues - The array of Zod issues to transform.
79
+ * @returns A {@link ValidationResult} mapping field paths to their error messages.
80
+ */
16
81
  protected issuesToResult(issues: ZodError["issues"]): ValidationResult;
17
82
  }
18
83
  //# sourceMappingURL=Validation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Validation.d.ts","sourceRoot":"","sources":["../../src/validation/Validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,KAAK,CAAC;AAEzE,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,OAAO,EACP,UAAU,EACX,MAAM,uCAAuC,CAAC;AAG/C,qBAAa,UAAU,CAAC,GAAG,SAAS,YAAY;aAKX,IAAI,EAAE,MAAM;IAJ/C,SAAS,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IACpC,SAAS,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IACpC,SAAS,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;gBAEI,IAAI,EAAE,MAAM;IAExC,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAIzC,SAAS,CAAC,KAAK,IAAI,WAAW;IAQ9B,SAAS,CAAC,YAAY,IAAI,WAAW;IAOrC,SAAS,CAAC,YAAY,IAAI,SAAS;IAKnC,SAAS,CAAC,YAAY,IAAI,SAAS;IAK5B,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAWrD,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAWzE,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,gBAAgB;CAUvE"}
1
+ {"version":3,"file":"Validation.d.ts","sourceRoot":"","sources":["../../src/validation/Validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,KAAK,CAAC;AAEzE,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,OAAO,EACP,UAAU,EACX,MAAM,uCAAuC,CAAC;AAG/C;;;;;;;;;GASG;AACH,qBAAa,UAAU,CAAC,GAAG,SAAS,YAAY;aAUX,IAAI,EAAE,MAAM;IAT/C,SAAS,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IACpC,SAAS,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IACpC,SAAS,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAE/B;;;;OAIG;gBACgC,IAAI,EAAE,MAAM;IAE/C;;;;OAIG;IACI,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAIzC;;;;;OAKG;IACH,SAAS,CAAC,KAAK,IAAI,WAAW;IAQ9B;;;;OAIG;IACH,SAAS,CAAC,YAAY,IAAI,WAAW;IAOrC;;;;OAIG;IACH,SAAS,CAAC,YAAY,IAAI,SAAS;IAKnC;;;;;;;;OAQG;IACH,SAAS,CAAC,YAAY,IAAI,SAAS;IAKnC;;;;;;OAMG;IACI,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAW5D;;;;;;OAMG;IACI,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAWzE;;;;;OAKG;IACH,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,gBAAgB;CAUvE"}
@@ -1,22 +1,53 @@
1
1
  import { z } from "zod";
2
2
  import { HttpsError } from "firebase-functions/https";
3
3
  import { DOCUMENT_KEY_ADMIN_KEYS } from "@mxpicture/gcp-functions-common/helper";
4
+ /**
5
+ * Zod-based validation for document data transfer objects.
6
+ *
7
+ * @remarks
8
+ * Uses a Zod shape to build create and update schemas. Admin-managed keys
9
+ * (e.g. `id`, `createTime`, `updateTime`) are automatically stripped from the
10
+ * create schema. The update schema is a partial version of the create schema.
11
+ *
12
+ * @typeParam DTO - The document data transfer object type.
13
+ */
4
14
  export class Validation {
5
15
  name;
6
16
  _createSchema;
7
17
  _updateSchema;
8
18
  _shape;
19
+ /**
20
+ * Create a new Validation instance.
21
+ *
22
+ * @param name - A descriptive name for this validator, used in error messages.
23
+ */
9
24
  constructor(name) {
10
25
  this.name = name;
11
26
  }
27
+ /**
28
+ * Inject the Zod shape used to build validation schemas.
29
+ *
30
+ * @param shape - The Zod raw shape describing the document fields.
31
+ */
12
32
  useShape(shape) {
13
33
  this._shape = shape;
14
34
  }
35
+ /**
36
+ * Retrieve the injected Zod shape.
37
+ *
38
+ * @returns The Zod raw shape.
39
+ * @throws {@link Error} if no shape has been provided via {@link useShape}.
40
+ */
15
41
  shape() {
16
42
  if (!this._shape)
17
43
  throw new Error(`${this.name}: shape not provided. Use "useShape" method`);
18
44
  return this._shape;
19
45
  }
46
+ /**
47
+ * Derive the Zod shape for create operations by removing admin-managed keys.
48
+ *
49
+ * @returns A copy of the base shape with admin keys removed.
50
+ */
20
51
  shape4Create() {
21
52
  const shape = { ...this.shape() };
22
53
  for (const key of Object.keys(shape))
@@ -24,28 +55,62 @@ export class Validation {
24
55
  delete shape[key];
25
56
  return shape;
26
57
  }
58
+ /**
59
+ * Get or lazily build the Zod schema used for create validation.
60
+ *
61
+ * @returns The Zod object schema for create operations.
62
+ */
27
63
  createSchema() {
28
64
  if (!this._createSchema)
29
65
  this._createSchema = z.object(this.shape4Create());
30
66
  return this._createSchema;
31
67
  }
68
+ /**
69
+ * Get or lazily build the Zod schema used for update validation.
70
+ *
71
+ * @remarks
72
+ * The update schema is the partial version of the create schema,
73
+ * making all fields optional.
74
+ *
75
+ * @returns The Zod object schema for update operations.
76
+ */
32
77
  updateSchema() {
33
78
  if (!this._updateSchema)
34
79
  this._updateSchema = this.createSchema().partial();
35
80
  return this._updateSchema;
36
81
  }
82
+ /**
83
+ * Validate a complete document for creation.
84
+ *
85
+ * @param doc - The document data to validate.
86
+ * @returns The parsed and validated document data.
87
+ * @throws {@link HttpsError} with `invalid-argument` if validation fails.
88
+ */
37
89
  validate(doc) {
38
90
  const result = this.createSchema().safeParse(doc);
39
91
  if (!result.success)
40
92
  throw new HttpsError("invalid-argument", "Invalid request data", this.issuesToResult(result.error.issues));
41
93
  return result.data;
42
94
  }
95
+ /**
96
+ * Validate a partial document for update operations.
97
+ *
98
+ * @param doc - The partial document data to validate.
99
+ * @returns The parsed and validated partial document data.
100
+ * @throws {@link HttpsError} with `invalid-argument` if validation fails.
101
+ */
43
102
  validatePartial(doc) {
44
103
  const result = this.updateSchema().safeParse(doc);
45
104
  if (!result.success)
46
105
  throw new HttpsError("invalid-argument", "Invalid request data", this.issuesToResult(result.error.issues));
47
106
  return result.data;
48
107
  }
108
+ /**
109
+ * Convert Zod validation issues into a structured validation result.
110
+ *
111
+ * @param issues - The array of Zod issues to transform.
112
+ * @returns A {@link ValidationResult} mapping field paths to their error messages.
113
+ */
49
114
  issuesToResult(issues) {
50
115
  const result = { errorFields: {} };
51
116
  for (const issue of issues) {
@@ -1 +1 @@
1
- {"version":3,"file":"Validation.js","sourceRoot":"","sources":["../../src/validation/Validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAmD,MAAM,KAAK,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAOtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAEjF,MAAM,OAAO,UAAU;IAKc;IAJzB,aAAa,CAAa;IAC1B,aAAa,CAAa;IAC1B,MAAM,CAAe;IAE/B,YAAmC,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IAE5C,QAAQ,CAAC,KAAkB;QAChC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAES,KAAK;QACb,IAAI,CAAC,IAAI,CAAC,MAAM;YACd,MAAM,IAAI,KAAK,CACb,GAAG,IAAI,CAAC,IAAI,6CAA6C,CAC1D,CAAC;QACJ,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAES,YAAY;QACpB,MAAM,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;QAClC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;YAClC,IAAI,uBAAuB,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/D,OAAO,KAAK,CAAC;IACf,CAAC;IAES,YAAY;QACpB,IAAI,CAAC,IAAI,CAAC,aAAa;YAAE,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAES,YAAY;QACpB,IAAI,CAAC,IAAI,CAAC,aAAa;YAAE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,OAAO,EAAE,CAAC;QAC5E,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAEM,QAAQ,CAAC,GAA6B;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,OAAO;YACjB,MAAM,IAAI,UAAU,CAClB,kBAAkB,EAClB,sBAAsB,EACtB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CACzC,CAAC;QACJ,OAAO,MAAM,CAAC,IAAoB,CAAC;IACrC,CAAC;IAEM,eAAe,CAAC,GAA0B;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,OAAO;YACjB,MAAM,IAAI,UAAU,CAClB,kBAAkB,EAClB,sBAAsB,EACtB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CACzC,CAAC;QACJ,OAAO,MAAM,CAAC,IAA6B,CAAC;IAC9C,CAAC;IAES,cAAc,CAAC,MAA0B;QACjD,MAAM,MAAM,GAAqB,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;QAErD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAChE,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
1
+ {"version":3,"file":"Validation.js","sourceRoot":"","sources":["../../src/validation/Validation.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mxpicture/gcp-functions-backend",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "Utils for google cloud functions, publishing both CommonJS and ESM builds",
5
5
  "type": "module",
6
6
  "author": "MXPicture",
@@ -25,13 +25,15 @@
25
25
  },
26
26
  "scripts": {
27
27
  "lint": "eslint \"src/**/*.{ts,tsx}\" --ext .ts,.tsx",
28
- "build": "tsc -b ."
28
+ "build": "tsc -b .",
29
+ "docs": "typedoc",
30
+ "docs:clean": "rm -rf docs"
29
31
  },
30
32
  "publishConfig": {
31
33
  "access": "public"
32
34
  },
33
35
  "dependencies": {
34
- "@mxpicture/gcp-functions-common": "^1.1.3",
36
+ "@mxpicture/gcp-functions-common": "^1.1.5",
35
37
  "firebase-admin": "^13.7.0",
36
38
  "firebase-functions": "^7.0.6",
37
39
  "short-uuid": "^6.0.3",