@dereekb/firebase 12.5.10 → 12.6.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.
@@ -1,13 +1,56 @@
1
- import { type Maybe } from '@dereekb/util';
1
+ import { type NeedsSyncBoolean, type Maybe } from '@dereekb/util';
2
2
  import { type GrantedReadRole, type GrantedUpdateRole } from '@dereekb/model';
3
- import { AbstractFirestoreDocument, type CollectionReference, type FirestoreCollection, type FirestoreContext, type FirebaseAuthUserId, type FirebaseAuthOwnershipKey, type StoragePath, type StorageSignedDownloadUrl, type StorageDownloadUrl } from '../../common';
4
- import { type StorageFileId, type StorageFileMetadata, type StorageFilePurpose } from './storagefile.id';
3
+ import { AbstractFirestoreDocument, type CollectionReference, type FirestoreCollection, type FirestoreContext, type FirebaseAuthUserId, type FirebaseAuthOwnershipKey, type StoragePath, type StorageSignedDownloadUrl, type StorageDownloadUrl, type SavedToFirestoreIfTrue, type OneWayFlatFirestoreModelKey, type FirestoreCollectionModelKey } from '../../common';
4
+ import { type StorageFileGroupId, type StorageFileGroupRelatedStorageFilePurpose, type StorageFileId, type StorageFileMetadata, type StorageFilePurpose } from './storagefile.id';
5
5
  import { type NotificationKey } from '../notification';
6
6
  export declare abstract class StorageFileFirestoreCollections {
7
7
  abstract readonly storageFileCollection: StorageFileFirestoreCollection;
8
+ abstract readonly storageFileGroupCollection: StorageFileGroupFirestoreCollection;
9
+ }
10
+ export type StorageFileTypes = typeof storageFileIdentity | typeof storageFileGroupIdentity;
11
+ /**
12
+ * StorageFile-related model that is initialized asynchronously at a later time.
13
+ *
14
+ * Examples: StorageFileGroup
15
+ */
16
+ export interface InitializedStorageFileModel {
17
+ /**
18
+ * True if this model needs to be sync'd/initialized with the original model.
19
+ *
20
+ * Is set false if/when "fi" is set true.
21
+ */
22
+ s?: Maybe<NeedsSyncBoolean>;
23
+ /**
24
+ * True if this model has been flagged invalid.
25
+ *
26
+ * This is for cases where the model cannot be properly initiialized.
27
+ *
28
+ * Typically this results in this model and related data being deleted.
29
+ */
30
+ fi?: Maybe<SavedToFirestoreIfTrue>;
8
31
  }
9
- export type StorageFileTypes = typeof storageFileIdentity;
10
32
  export declare const storageFileIdentity: import("../../common").RootFirestoreModelIdentity<"storageFile", "sf">;
33
+ /**
34
+ * The key for a StorageFile that is generated/related to a StorageFileGroup.
35
+ *
36
+ * For example, a StorageFile id for the Zip file generated by a StorageFileGroup with id "123" and the zip purpose "sfg_zip" would be "sfg_zip_sf123".
37
+ */
38
+ export type StorageFileGroupCreatedStorageFileKey<P extends StorageFileGroupRelatedStorageFilePurpose> = FirestoreCollectionModelKey<typeof storageFileIdentity, `${P}_${OneWayFlatFirestoreModelKey}`>;
39
+ /**
40
+ * Creates a StorageFileGroupCreatedStorageFileKey from the input StorageFileGroupId and purpose.
41
+ */
42
+ export declare function storageFileGroupCreatedStorageFileKey<P extends StorageFileGroupRelatedStorageFilePurpose>(purpose: P, storageFileGroupId: StorageFileGroupId): StorageFileGroupCreatedStorageFileKey<P>;
43
+ /**
44
+ * Creates a StorageFileGroupCreatedStorageFileKey from the input StorageFileGroupId and pre-configured purpose.
45
+ */
46
+ export type StorageFileGroupCreateStorageFileKeyFactory<P extends StorageFileGroupRelatedStorageFilePurpose> = (storageFileGroupId: StorageFileGroupId) => StorageFileGroupCreatedStorageFileKey<P>;
47
+ /**
48
+ * Creates a factory function for generating StorageFileGroupCreatedStorageFileKey values using the input purpose.
49
+ *
50
+ * @param purpose The purpose of the StorageFileGroupCreatedStorageFileKey.
51
+ * @returns A factory function that takes a StorageFileGroupId and returns a StorageFileGroupCreatedStorageFileKey.
52
+ */
53
+ export declare function storageFileGroupCreateStorageFileKeyFactory<P extends StorageFileGroupRelatedStorageFilePurpose>(purpose: P): StorageFileGroupCreateStorageFileKeyFactory<P>;
11
54
  /**
12
55
  * This key is used in the CustomStorageMetadata of a Firebase Storage file that is associated with a StorageFile to link the file to the StorageFile.
13
56
  */
@@ -36,7 +79,14 @@ export declare enum StorageFileCreationType {
36
79
  /**
37
80
  * The StorageFile was initialized from an uploaded file.
38
81
  */
39
- INIT_FROM_UPLOAD = 2
82
+ INIT_FROM_UPLOAD = 2,
83
+ /**
84
+ * This StorageFile was created by/for a StorageFileGroup.
85
+ *
86
+ * When creating a StorageFile via createStorageFileDocumentPairFactory(), this flag changes the behavior to use a parent
87
+ * StorageFileGroup to derive the created StorageFile's identifier.
88
+ */
89
+ FOR_STORAGE_FILE_GROUP = 3
40
90
  }
41
91
  /**
42
92
  * The current file state.
@@ -135,13 +185,19 @@ export type StorageFilePublicDownloadUrl = StorageDownloadUrl;
135
185
  */
136
186
  export type StorageFileSignedDownloadUrl = StorageSignedDownloadUrl;
137
187
  /**
138
- * A global storage file in the system.
188
+ * A download URL for a StorageFile.
189
+ *
190
+ * This can be a public download URL or a signed download URL.
191
+ */
192
+ export type StorageFileDownloadUrl = StorageFilePublicDownloadUrl | StorageFileSignedDownloadUrl;
193
+ /**
194
+ * A StorageFile in the system, which references a file in Google Cloud Storage.
139
195
  *
140
196
  * Contains file metadata and ownership information, along with other arbitrary metadata.
141
197
  */
142
198
  export interface StorageFile<M extends StorageFileMetadata = StorageFileMetadata> extends StoragePath {
143
199
  /**
144
- * Created at date
200
+ * Created at date.
145
201
  */
146
202
  cat: Date;
147
203
  /**
@@ -206,6 +262,23 @@ export interface StorageFile<M extends StorageFileMetadata = StorageFileMetadata
206
262
  * Is the main trigger for determining a StorageFile should be deleted.
207
263
  */
208
264
  sdat?: Maybe<Date>;
265
+ /**
266
+ * StorageFileGroup id(s) that this StorageFile should be associated with.
267
+ *
268
+ * These StorageFileGroup do not need to exist, and will be created when synchronization occurs.
269
+ *
270
+ * These groups by design should typically be pre-determined at the time the StorageFile is created and remain unchanged; timely removal of data from groups is not part of the design spec.
271
+ *
272
+ * When a StorageFile is updated to remove groups, the removal is eventually propogated to the StorageFileGroup(s) that it was associated with,
273
+ * but there is no gurantee about timeliness when this will happen. StorageFiles, when deleted, are removed from StorageFileGroups immediately, which are flagged for another regeneration automatically.
274
+ *
275
+ * In cases where you need to have the StorageFileGroup be updated promptly, you should manually handle those cases.
276
+ */
277
+ g: StorageFileGroupId[];
278
+ /**
279
+ * If true, this file should be re-synced with each StorageFileGroup that it references.
280
+ */
281
+ gs?: Maybe<NeedsSyncBoolean>;
209
282
  }
210
283
  /**
211
284
  * Granted roles for creating a download link to the StorageFile's file.
@@ -213,7 +286,7 @@ export interface StorageFile<M extends StorageFileMetadata = StorageFileMetadata
213
286
  * The admin_download role allows specifying additional parameters and longer expiration times.
214
287
  */
215
288
  export type StorageFileDownloadRole = 'download' | 'admin_download';
216
- export type StorageFileRoles = StorageFileDownloadRole | 'process' | GrantedUpdateRole | GrantedReadRole;
289
+ export type StorageFileRoles = StorageFileDownloadRole | 'forceSyncWithGroups' | 'syncWithGroups' | 'process' | GrantedUpdateRole | GrantedReadRole;
217
290
  export declare class StorageFileDocument extends AbstractFirestoreDocument<StorageFile, StorageFileDocument, typeof storageFileIdentity> {
218
291
  get modelIdentity(): import("../../common").RootFirestoreModelIdentity<"storageFile", "sf">;
219
292
  }
@@ -221,3 +294,75 @@ export declare const storageFileConverter: import("../../common").SnapshotConver
221
294
  export declare function storageFileCollectionReference(context: FirestoreContext): CollectionReference<StorageFile>;
222
295
  export type StorageFileFirestoreCollection = FirestoreCollection<StorageFile, StorageFileDocument>;
223
296
  export declare function storageFileFirestoreCollection(firestoreContext: FirestoreContext): StorageFileFirestoreCollection;
297
+ export declare const storageFileGroupIdentity: import("../../common").RootFirestoreModelIdentity<"storageFileGroup", "sfg">;
298
+ /**
299
+ * Current embedded state
300
+ */
301
+ export interface StorageFileGroupEmbeddedFile {
302
+ /**
303
+ * StorageFile id
304
+ */
305
+ s: StorageFileId;
306
+ /**
307
+ * The time number it was added to the group.
308
+ */
309
+ sat: Date;
310
+ /**
311
+ * The first time the StorageFile's file was added to the zip, if applicable.
312
+ */
313
+ zat?: Maybe<Date>;
314
+ }
315
+ export declare const storageFileGroupEmbeddedFile: import("../../common").FirestoreSubObjectFieldMapFunctionsConfig<StorageFileGroupEmbeddedFile, Partial<import("@dereekb/util").ReplaceType<StorageFileGroupEmbeddedFile, import("@dereekb/util").MaybeMap<object>, any>>>;
316
+ /**
317
+ * A group of StorageFiles.
318
+ *
319
+ * Contains file metadata and ownership information, along with other arbitrary metadata.
320
+ */
321
+ export interface StorageFileGroup extends InitializedStorageFileModel {
322
+ /**
323
+ * List of embedded files in this group currently.
324
+ */
325
+ f: StorageFileGroupEmbeddedFile[];
326
+ /**
327
+ * Created at date.
328
+ */
329
+ cat: Date;
330
+ /**
331
+ * Ownership key, if applicable.
332
+ */
333
+ o?: Maybe<FirebaseAuthOwnershipKey>;
334
+ /**
335
+ * True if a zip file should be generated for this group.
336
+ *
337
+ * This should remain true while a zip file
338
+ */
339
+ z?: Maybe<SavedToFirestoreIfTrue>;
340
+ /**
341
+ * StorageFile that contains the zip file for this group.
342
+ */
343
+ zsf?: Maybe<StorageFileId>;
344
+ /**
345
+ * The last date the zip file was regenerated for this group.
346
+ */
347
+ zat?: Maybe<Date>;
348
+ /**
349
+ * True if this StorageFileGroup should flag regeneration of output StorageFiles/content.
350
+ */
351
+ re?: Maybe<SavedToFirestoreIfTrue>;
352
+ /**
353
+ * True if this StorageFileGroup should clean up file references.
354
+ *
355
+ * This cleanup process will occur during the next regeneration.
356
+ */
357
+ c?: Maybe<SavedToFirestoreIfTrue>;
358
+ }
359
+ export type StorageFileGroupContentFlagsData = Pick<StorageFileGroup, 'z'>;
360
+ export type StorageFileGroupRoles = 'regenerate' | GrantedReadRole;
361
+ export declare class StorageFileGroupDocument extends AbstractFirestoreDocument<StorageFileGroup, StorageFileGroupDocument, typeof storageFileGroupIdentity> {
362
+ get modelIdentity(): import("../../common").RootFirestoreModelIdentity<"storageFileGroup", "sfg">;
363
+ get storageFileGroupRelatedModelKey(): string;
364
+ }
365
+ export declare const storageFileGroupConverter: import("../../common").SnapshotConverterFunctions<StorageFileGroup, Partial<import("@dereekb/util").ReplaceType<StorageFileGroup, import("@dereekb/util").MaybeMap<object>, any>>>;
366
+ export declare function storageFileGroupCollectionReference(context: FirestoreContext): CollectionReference<StorageFileGroup>;
367
+ export type StorageFileGroupFirestoreCollection = FirestoreCollection<StorageFileGroup, StorageFileGroupDocument>;
368
+ export declare function storageFileGroupFirestoreCollection(firestoreContext: FirestoreContext): StorageFileGroupFirestoreCollection;
@@ -0,0 +1,9 @@
1
+ import { type SlashPathFile, type SlashPathFolder, type SlashPath, type Maybe } from '@dereekb/util';
2
+ import { type StorageFileGroupId } from './storagefile.id';
3
+ /**
4
+ * All StorageFileGroup generated files are stored under this root folder.
5
+ */
6
+ export declare const STORAGE_FILE_GROUP_ROOT_FOLDER_PATH: SlashPathFolder;
7
+ export declare function storageFileGroupFolderPath(storageFileGroupId: StorageFileGroupId, ...subPath: Maybe<SlashPath>[]): SlashPathFolder;
8
+ export declare const STORAGE_FILE_GROUP_ZIP_FILE_PATH: SlashPathFile;
9
+ export declare function storageFileGroupZipFileStoragePath(storageFileGroupId: StorageFileGroupId): SlashPath;
@@ -0,0 +1,26 @@
1
+ import { type SlashPathTypedFile } from '@dereekb/util';
2
+ import { type StorageFileGroupId, type StorageFilePurpose } from './storagefile.id';
3
+ import { type StorageFileProcessingSubtask, type StorageFileProcessingSubtaskMetadata } from './storagefile.task';
4
+ import { type StorageFileGroupCreatedStorageFileKey } from './storagefile';
5
+ /**
6
+ * StorageFilePurpose for a StorageFileGroup's generated zip file.
7
+ */
8
+ export declare const STORAGE_FILE_GROUP_ZIP_STORAGE_FILE_PURPOSE: StorageFilePurpose;
9
+ /**
10
+ * The predictable StorageFileKey for the StorageFileGroup's generated zip file StorageFile.
11
+ */
12
+ export type StorageFileGroupZipStorageFileKey = StorageFileGroupCreatedStorageFileKey<typeof STORAGE_FILE_GROUP_ZIP_STORAGE_FILE_PURPOSE>;
13
+ /**
14
+ * Creates a StorageFileGroupZipStorageFileKey from the input StorageFileGroupId.
15
+ */
16
+ export declare const storageFileGroupZipStorageFileKey: import("./storagefile").StorageFileGroupCreateStorageFileKeyFactory<string>;
17
+ /**
18
+ * Metadata for the StorageFileGroupZipStorageFile.
19
+ */
20
+ export interface StorageFileGroupZipStorageFileMetadata {
21
+ readonly sfg: StorageFileGroupId;
22
+ }
23
+ export declare const STORAGE_FILE_GROUP_ZIP_STORAGE_FILE_PURPOSE_CREATE_ZIP_SUBTASK: StorageFileProcessingSubtask;
24
+ export type StorageFileGroupZipStorageFileProcessingSubtask = typeof STORAGE_FILE_GROUP_ZIP_STORAGE_FILE_PURPOSE_CREATE_ZIP_SUBTASK;
25
+ export type StorageFileGroupZipStorageFileProcessingSubtaskMetadata = StorageFileProcessingSubtaskMetadata;
26
+ export declare const STORAGE_FILE_GROUP_ZIP_INFO_JSON_FILE_NAME: SlashPathTypedFile;
@@ -1,4 +1,4 @@
1
- import { type FirestoreModelId, type FirestoreModelKey } from '../../common';
1
+ import { type FlatFirestoreModelKey, inferKeyFromTwoWayFlatFirestoreModelKey, twoWayFlatFirestoreModelKey, type FirestoreModelId, type FirestoreModelKey } from '../../common';
2
2
  export type StorageFileId = FirestoreModelId;
3
3
  export type StorageFileKey = FirestoreModelKey;
4
4
  /**
@@ -12,9 +12,30 @@ export type StorageFileKey = FirestoreModelKey;
12
12
  * Can be used for querying.
13
13
  */
14
14
  export type StorageFilePurpose = string;
15
+ /**
16
+ * A StorageFilePurpose that is related to a StorageFileGroup.
17
+ *
18
+ * Should only have the characters characters "a-z", "0-9", and/or "_", as it is used as part of a FirestoreModelId for StorageFileGroupCreatedStorageFileKey.
19
+ */
20
+ export type StorageFileGroupRelatedStorageFilePurpose = StorageFilePurpose;
15
21
  /**
16
22
  * Arbitrary metadata to attach to the storage file.
17
23
  *
18
24
  * Is serialized directly to/from Firestore, so be mindful of what is stored.
19
25
  */
20
26
  export type StorageFileMetadata = Readonly<Record<string, any>>;
27
+ /**
28
+ * The StorgaeFileGroupId is a two way flat firestore model key of the object that it represents.
29
+ *
30
+ * This identifier is used by StorageFile's to group files together based around some other model or common identifier.
31
+ */
32
+ export type StorageFileGroupId = FlatFirestoreModelKey;
33
+ export type StorageFileGroupKey = FirestoreModelKey;
34
+ /**
35
+ * Creates a StorgaeFileGroupId from the input FirestoreModelKey.
36
+ *
37
+ * @param modelKey
38
+ * @returns
39
+ */
40
+ export declare const storageFileGroupIdForModel: typeof twoWayFlatFirestoreModelKey;
41
+ export declare const inferStorageFileGroupRelatedModelKey: typeof inferKeyFromTwoWayFlatFirestoreModelKey;
@@ -15,3 +15,25 @@ export interface StorageFilePurposeAndUserQueryInput {
15
15
  readonly user: FirebaseAuthUserId;
16
16
  }
17
17
  export declare function storageFilePurposeAndUserQuery(input: StorageFilePurposeAndUserQueryInput): FirestoreQueryConstraint[];
18
+ export declare function storageFileFlaggedForSyncWithGroupsQuery(): FirestoreQueryConstraint[];
19
+ /**
20
+ * Query for storageFileGroups that are flagged for initialization.
21
+ *
22
+ * @param now
23
+ * @returns
24
+ */
25
+ export declare function storageFileGroupsFlaggedForNeedsInitializationQuery(): FirestoreQueryConstraint[];
26
+ /**
27
+ * Query for storageFileGroups that are flagged for content regeneration.
28
+ *
29
+ * @param now
30
+ * @returns
31
+ */
32
+ export declare function storageFileGroupsFlaggedForContentRegenerationQuery(): FirestoreQueryConstraint[];
33
+ /**
34
+ * Query for storageFileGroups that are flagged as invalid.
35
+ *
36
+ * @param now
37
+ * @returns
38
+ */
39
+ export declare function storageFileGroupsFlaggedInvalidQuery(): FirestoreQueryConstraint[];
@@ -0,0 +1,55 @@
1
+ import { type Maybe } from '@dereekb/util';
2
+ import { type FirestoreModelKey, type FirestoreDocumentAccessor } from '../../common';
3
+ import { type StorageFileGroupDocument, type StorageFileGroup, type StorageFileGroupEmbeddedFile } from './storagefile';
4
+ import { type StorageFileId } from './storagefile.id';
5
+ export interface StorageFileGroupDocumentReferencePair {
6
+ /**
7
+ * StorageFileGroupDocument to update.
8
+ *
9
+ * If not provided, please provide the storageFileGroupRelatedModelKey. If neither value is provided, an error will be thrown.
10
+ */
11
+ readonly storageFileGroupDocument?: Maybe<StorageFileGroupDocument>;
12
+ /**
13
+ * Key of the model the storage file group is expected to be associated with. Used if StorageFileGroupDocument is not provided already.
14
+ */
15
+ readonly storageFileGroupRelatedModelKey?: Maybe<FirestoreModelKey>;
16
+ }
17
+ export declare function loadStorageFileGroupDocumentForReferencePair(input: StorageFileGroupDocumentReferencePair, accessor: FirestoreDocumentAccessor<StorageFileGroup, StorageFileGroupDocument>): StorageFileGroupDocument;
18
+ export interface CalculateStorageFileGroupEmbeddedFileUpdateInput {
19
+ readonly storageFileGroup: Pick<StorageFileGroup, 'f' | 're' | 'z' | 'zat'>;
20
+ readonly insert?: Maybe<(Pick<StorageFileGroupEmbeddedFile, 's'> & Partial<Omit<StorageFileGroupEmbeddedFile, 's'>>)[]>;
21
+ readonly remove?: Maybe<StorageFileId[]>;
22
+ /**
23
+ * Whether or not to allow recalculating the regenerate flag even if the current "re" value is true.
24
+ *
25
+ * Regenerate will always be true if any files are removed.
26
+ *
27
+ * Defaults to false.
28
+ */
29
+ readonly allowRecalculateRegenerateFlag?: Maybe<boolean>;
30
+ }
31
+ export declare function calculateStorageFileGroupEmbeddedFileUpdate(input: CalculateStorageFileGroupEmbeddedFileUpdateInput): Pick<StorageFileGroup, 'f' | 're'>;
32
+ export interface CalculateStorageFileGroupRegenerationInput {
33
+ readonly storageFileGroup: Pick<StorageFileGroup, 'f' | 'z' | 'zat'>;
34
+ /**
35
+ * If true, will force regenerating applicable derived files, even if all content is up to date.
36
+ */
37
+ readonly force?: Maybe<boolean>;
38
+ }
39
+ export interface CalculateStorageFileGroupRegenerationResult {
40
+ /**
41
+ * Whether or not the zip file needs to be regenerated.
42
+ */
43
+ readonly regenerateZip?: Maybe<boolean>;
44
+ /**
45
+ * Whether or not any derived StorageFile needs to be regenerated.
46
+ */
47
+ readonly flagRegenerate: boolean;
48
+ }
49
+ /**
50
+ * Calculates the regeneration flags for a StorageFileGroup.
51
+ *
52
+ * @param input CalculateStorageFileGroupRegenerationInput
53
+ * @returns CalculateStorageFileGroupRegenerationResult
54
+ */
55
+ export declare function calculateStorageFileGroupRegeneration(input: CalculateStorageFileGroupRegenerationInput): CalculateStorageFileGroupRegenerationResult;
package/test/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ## [12.6.1](https://github.com/dereekb/dbx-components/compare/v12.6.0-dev...v12.6.1) (2025-12-07)
6
+
7
+
8
+
9
+ # [12.6.0](https://github.com/dereekb/dbx-components/compare/v12.5.10-dev...v12.6.0) (2025-12-02)
10
+
11
+
12
+
5
13
  ## [12.5.10](https://github.com/dereekb/dbx-components/compare/v12.5.9-dev...v12.5.10) (2025-11-21)
6
14
 
7
15
 
package/test/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dereekb/firebase/test",
3
- "version": "12.5.10",
3
+ "version": "12.6.1",
4
4
  "type": "commonjs",
5
5
  "peerDependencies": {
6
6
  "@dereekb/util": "*",