@travetto/model-firestore 7.1.4 → 8.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -36,7 +36,7 @@ export class Init {
36
36
  }
37
37
  ```
38
38
 
39
- where the [FirestoreModelConfig](https://github.com/travetto/travetto/tree/main/module/model-firestore/src/config.ts#L6) is defined by:
39
+ where the [FirestoreModelConfig](https://github.com/travetto/travetto/tree/main/module/model-firestore/src/config.ts#L7) is defined by:
40
40
 
41
41
  **Code: Structure of FirestoreModelConfig**
42
42
  ```typescript
@@ -50,7 +50,8 @@ export class FirestoreModelConfig {
50
50
  modifyStorage?: boolean;
51
51
  credentials?: FirestoreModelConfigCredentials;
52
52
 
53
- async postConstruct(): Promise<void> {
53
+ @PostConstruct()
54
+ async finalizeConfig(): Promise<void> {
54
55
  if (!this.databaseURL && !Runtime.production) {
55
56
  this.projectId ??= 'trv-local-dev';
56
57
  this.emulator ??= 'localhost:7000'; // From docker
@@ -59,9 +60,8 @@ export class FirestoreModelConfig {
59
60
  process.env.FIRESTORE_EMULATOR_HOST = this.emulator;
60
61
  }
61
62
  if (this.credentialsFile && !this.credentials) {
62
- this.credentials = FirestoreModelConfigCredentials.from(
63
- await RuntimeResources.readJSON(this.credentialsFile)
64
- );
63
+ const bytes = await RuntimeResources.readBinaryArray(this.credentialsFile);
64
+ this.credentials = FirestoreModelConfigCredentials.from(JSONUtil.fromBinaryArray(bytes));
65
65
  await SchemaValidator.validate(FirestoreModelConfigCredentials, this.credentials);
66
66
  }
67
67
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/model-firestore",
3
- "version": "7.1.4",
3
+ "version": "8.0.0-alpha.1",
4
4
  "description": "Firestore backing for the travetto model module.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -25,13 +25,13 @@
25
25
  "directory": "module/model-firestore"
26
26
  },
27
27
  "dependencies": {
28
- "@google-cloud/firestore": "^8.1.0",
29
- "@travetto/config": "^7.1.4",
30
- "@travetto/model": "^7.1.4",
31
- "@travetto/runtime": "^7.1.4"
28
+ "@google-cloud/firestore": "^8.3.0",
29
+ "@travetto/config": "^8.0.0-alpha.1",
30
+ "@travetto/model": "^8.0.0-alpha.1",
31
+ "@travetto/runtime": "^8.0.0-alpha.1"
32
32
  },
33
33
  "peerDependencies": {
34
- "@travetto/cli": "^7.1.4"
34
+ "@travetto/cli": "^8.0.0-alpha.1"
35
35
  },
36
36
  "peerDependenciesMeta": {
37
37
  "@travetto/cli": {
package/src/config.ts CHANGED
@@ -1,6 +1,7 @@
1
- import { Runtime, RuntimeResources } from '@travetto/runtime';
1
+ import { JSONUtil, Runtime, RuntimeResources } from '@travetto/runtime';
2
2
  import { Config } from '@travetto/config';
3
3
  import { Schema, SchemaValidator } from '@travetto/schema';
4
+ import { PostConstruct } from '@travetto/di';
4
5
 
5
6
  @Schema()
6
7
  class FirestoreModelConfigCredentials {
@@ -19,7 +20,8 @@ export class FirestoreModelConfig {
19
20
  modifyStorage?: boolean;
20
21
  credentials?: FirestoreModelConfigCredentials;
21
22
 
22
- async postConstruct(): Promise<void> {
23
+ @PostConstruct()
24
+ async finalizeConfig(): Promise<void> {
23
25
  if (!this.databaseURL && !Runtime.production) {
24
26
  this.projectId ??= 'trv-local-dev';
25
27
  this.emulator ??= 'localhost:7000'; // From docker
@@ -28,9 +30,8 @@ export class FirestoreModelConfig {
28
30
  process.env.FIRESTORE_EMULATOR_HOST = this.emulator;
29
31
  }
30
32
  if (this.credentialsFile && !this.credentials) {
31
- this.credentials = FirestoreModelConfigCredentials.from(
32
- await RuntimeResources.readJSON(this.credentialsFile)
33
- );
33
+ const bytes = await RuntimeResources.readBinaryArray(this.credentialsFile);
34
+ this.credentials = FirestoreModelConfigCredentials.from(JSONUtil.fromBinaryArray(bytes));
34
35
  await SchemaValidator.validate(FirestoreModelConfigCredentials, this.credentials);
35
36
  }
36
37
  }
package/src/service.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { type DocumentData, FieldValue, Firestore, type PartialWithFieldValue, type Query } from '@google-cloud/firestore';
1
+ import { type DocumentData, FieldValue, Firestore, type Query } from '@google-cloud/firestore';
2
2
 
3
3
  import { JSONUtil, ShutdownManager, type Class, type DeepPartial } from '@travetto/runtime';
4
- import { Injectable } from '@travetto/di';
4
+ import { Injectable, PostConstruct } from '@travetto/di';
5
5
  import {
6
6
  type ModelCrudSupport, ModelRegistryIndex, type ModelStorageSupport,
7
7
  type ModelIndexedSupport, type ModelType, NotFoundError, type OptionalId,
@@ -10,10 +10,9 @@ import {
10
10
 
11
11
  import type { FirestoreModelConfig } from './config.ts';
12
12
 
13
- const clone = structuredClone;
14
-
15
- const toSimpleObject = <T>(input: T, missingValue: unknown = null): PartialWithFieldValue<DocumentData> =>
16
- JSONUtil.parseSafe(JSON.stringify(input, (_, value) => value ?? null), (_, value) => value ?? missingValue);
13
+ const clone = JSONUtil.clone;
14
+ const setMissingValues = <T>(input: T, missingValue: unknown): T =>
15
+ JSONUtil.clone(input, { replacer: (_, value) => value ?? null, reviver: (_, value) => value ?? missingValue });
17
16
 
18
17
  /**
19
18
  * A model service backed by Firestore
@@ -39,8 +38,9 @@ export class FirestoreModelService implements ModelCrudSupport, ModelStorageSupp
39
38
  return this.client.collection(this.#resolveTable(cls));
40
39
  }
41
40
 
42
- async postConstruct(): Promise<void> {
43
- this.client = new Firestore(this.config);
41
+ @PostConstruct()
42
+ async initializeClient(): Promise<void> {
43
+ this.client = new Firestore({ ...this.config, useBigInt: true });
44
44
  ShutdownManager.signal.addEventListener('abort', () => this.client.terminate());
45
45
  }
46
46
 
@@ -66,21 +66,21 @@ export class FirestoreModelService implements ModelCrudSupport, ModelStorageSupp
66
66
 
67
67
  async create<T extends ModelType>(cls: Class<T>, item: OptionalId<T>): Promise<T> {
68
68
  const prepped = await ModelCrudUtil.preStore(cls, item, this);
69
- await this.#getCollection(cls).doc(prepped.id).create(clone(prepped));
69
+ await this.#getCollection(cls).doc(prepped.id).create(clone<DocumentData>(prepped));
70
70
  return prepped;
71
71
  }
72
72
 
73
73
  async update<T extends ModelType>(cls: Class<T>, item: T): Promise<T> {
74
74
  ModelCrudUtil.ensureNotSubType(cls);
75
75
  const prepped = await ModelCrudUtil.preStore(cls, item, this);
76
- await this.#getCollection(cls).doc(item.id).update(clone<DocumentData>(prepped));
76
+ await this.#getCollection(cls).doc(item.id).set(clone<DocumentData>(prepped), { merge: false });
77
77
  return prepped;
78
78
  }
79
79
 
80
80
  async upsert<T extends ModelType>(cls: Class<T>, item: OptionalId<T>): Promise<T> {
81
81
  ModelCrudUtil.ensureNotSubType(cls);
82
82
  const prepped = await ModelCrudUtil.preStore(cls, item, this);
83
- await this.#getCollection(cls).doc(prepped.id).set(clone(prepped));
83
+ await this.#getCollection(cls).doc(prepped.id).set(clone<DocumentData>(prepped));
84
84
  return prepped;
85
85
  }
86
86
 
@@ -88,7 +88,7 @@ export class FirestoreModelService implements ModelCrudSupport, ModelStorageSupp
88
88
  ModelCrudUtil.ensureNotSubType(cls);
89
89
  const id = item.id;
90
90
  const full = await ModelCrudUtil.naivePartialUpdate(cls, () => this.get(cls, id), item, view);
91
- const cleaned = toSimpleObject(full, FieldValue.delete());
91
+ const cleaned = setMissingValues(full, FieldValue.delete());
92
92
  await this.#getCollection(cls).doc(id).set(cleaned, { mergeFields: Object.keys(full) });
93
93
  return this.get(cls, id);
94
94
  }