@cravery/firebase 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/recipe/converters.d.ts.map +1 -1
  2. package/dist/recipe/converters.js +2 -2
  3. package/dist/recipe/converters.js.map +1 -1
  4. package/dist/recipe/index.d.ts +2 -0
  5. package/dist/recipe/index.d.ts.map +1 -1
  6. package/dist/recipe/index.js +2 -0
  7. package/dist/recipe/index.js.map +1 -1
  8. package/dist/recipe/repository.d.ts +5 -0
  9. package/dist/recipe/repository.d.ts.map +1 -1
  10. package/dist/recipe/repository.js +46 -3
  11. package/dist/recipe/repository.js.map +1 -1
  12. package/dist/recipe/stats_repository.d.ts +18 -0
  13. package/dist/recipe/stats_repository.d.ts.map +1 -0
  14. package/dist/recipe/stats_repository.js +195 -0
  15. package/dist/recipe/stats_repository.js.map +1 -0
  16. package/dist/recipe/user_recipe_repository.d.ts +26 -0
  17. package/dist/recipe/user_recipe_repository.d.ts.map +1 -0
  18. package/dist/recipe/user_recipe_repository.js +180 -0
  19. package/dist/recipe/user_recipe_repository.js.map +1 -0
  20. package/dist/utils/strip-undefined.js +2 -2
  21. package/dist/utils/strip-undefined.js.map +1 -1
  22. package/dist/utils/timestamp.d.ts +1 -1
  23. package/dist/utils/timestamp.d.ts.map +1 -1
  24. package/package.json +60 -58
  25. package/src/iam/converters.ts +38 -38
  26. package/src/iam/index.ts +1 -1
  27. package/src/index.ts +3 -3
  28. package/src/recipe/converters.ts +98 -93
  29. package/src/recipe/index.ts +5 -3
  30. package/src/recipe/repository.ts +284 -220
  31. package/src/recipe/stats_repository.ts +251 -0
  32. package/src/recipe/user_recipe_repository.ts +240 -0
  33. package/src/recipe/utils.ts +143 -143
  34. package/src/utils/index.ts +2 -2
  35. package/src/utils/strip-undefined.ts +32 -32
  36. package/src/utils/timestamp.ts +21 -21
@@ -1,143 +1,143 @@
1
- import { Recipe, RecipeContent, RecipeMeta } from "@cravery/core";
2
-
3
- export function mergeRecipe(meta: RecipeMeta, content: RecipeContent): Recipe {
4
- const equipment = meta.equipment?.map((equipMeta, index) => {
5
- const equipContent = content.equipment?.[index];
6
- if (!equipContent) {
7
- throw new Error(`Missing equipment content at index ${index}`);
8
- }
9
- return {
10
- ...equipMeta,
11
- ...equipContent,
12
- };
13
- });
14
-
15
- const ingredientSections = meta.ingredientSections.map(
16
- (sectionMeta, sectionIndex) => ({
17
- slug: sectionMeta.slug,
18
- title: content.ingredientSections[sectionIndex]?.title,
19
- ingredients: sectionMeta.ingredients.map((ingredMeta, ingredIndex) => ({
20
- ...ingredMeta,
21
- ...(content.ingredientSections[sectionIndex]?.ingredients[
22
- ingredIndex
23
- ] || {}),
24
- })),
25
- }),
26
- );
27
-
28
- const instructions = meta.instructions.map((instrMeta, index) => ({
29
- ...instrMeta,
30
- ...(content.instructions[index] || {}),
31
- }));
32
-
33
- return {
34
- id: meta.id,
35
- allergens: meta.allergens,
36
- confidence: meta.confidence,
37
- createdAt: meta.createdAt,
38
- createdBy: meta.createdBy,
39
- cuisine: meta.cuisine,
40
- deletedAt: meta.deletedAt,
41
- dietaryTags: meta.dietaryTags,
42
- difficulty: meta.difficulty,
43
- imageUrl: meta.imageUrl,
44
- mealTypes: meta.mealTypes,
45
- nutrition: meta.nutrition,
46
- originalLocale: meta.originalLocale,
47
- servings: meta.servings,
48
- source: meta.source,
49
- sourceUrl: meta.sourceUrl,
50
- spiciness: meta.spiciness,
51
- status: meta.status,
52
- time: meta.time,
53
- updatedAt: meta.updatedAt,
54
- equipment,
55
- ingredientSections,
56
- instructions,
57
- description: content.description,
58
- locale: content.locale,
59
- tips: content.tips,
60
- title: content.title,
61
- };
62
- }
63
-
64
- export function splitRecipe(recipe: Recipe): {
65
- meta: Omit<RecipeMeta, "id">;
66
- content: RecipeContent;
67
- } {
68
- const {
69
- id,
70
- description,
71
- equipment,
72
- ingredientSections,
73
- instructions,
74
- locale,
75
- tips,
76
- title,
77
- ...metaFields
78
- } = recipe;
79
-
80
- const equipmentMeta = equipment?.map(({ required, slug }) => ({
81
- required,
82
- slug,
83
- }));
84
- const equipmentContent = equipment?.map(({ name, notes, slug }) => ({
85
- name,
86
- notes,
87
- slug,
88
- }));
89
-
90
- const ingredientSectionsMeta = ingredientSections.map(
91
- ({ ingredients, slug }) => ({
92
- slug,
93
- ingredients: ingredients.map(({ quantity, required, slug, unit }) => ({
94
- quantity,
95
- required,
96
- slug,
97
- unit,
98
- })),
99
- }),
100
- );
101
- const ingredientSectionsContent = ingredientSections.map(
102
- ({ ingredients, slug, title }) => ({
103
- slug,
104
- title,
105
- ingredients: ingredients.map(({ name, notes, slug }) => ({
106
- name,
107
- notes,
108
- slug,
109
- })),
110
- }),
111
- );
112
-
113
- const instructionsMeta = instructions.map(
114
- ({ duration, step, temperature }) => ({
115
- duration,
116
- step,
117
- temperature,
118
- }),
119
- );
120
- const instructionsContent = instructions.map(({ step, text }) => ({
121
- step,
122
- text,
123
- }));
124
-
125
- const content: RecipeContent = {
126
- description,
127
- equipment: equipmentContent,
128
- ingredientSections: ingredientSectionsContent,
129
- instructions: instructionsContent,
130
- locale,
131
- tips,
132
- title,
133
- };
134
-
135
- const meta = {
136
- ...metaFields,
137
- equipment: equipmentMeta,
138
- ingredientSections: ingredientSectionsMeta,
139
- instructions: instructionsMeta,
140
- };
141
-
142
- return { meta, content };
143
- }
1
+ import { Recipe, RecipeContent, RecipeMeta } from "@cravery/core";
2
+
3
+ export function mergeRecipe(meta: RecipeMeta, content: RecipeContent): Recipe {
4
+ const equipment = meta.equipment?.map((equipMeta, index) => {
5
+ const equipContent = content.equipment?.[index];
6
+ if (!equipContent) {
7
+ throw new Error(`Missing equipment content at index ${index}`);
8
+ }
9
+ return {
10
+ ...equipMeta,
11
+ ...equipContent,
12
+ };
13
+ });
14
+
15
+ const ingredientSections = meta.ingredientSections.map(
16
+ (sectionMeta, sectionIndex) => ({
17
+ slug: sectionMeta.slug,
18
+ title: content.ingredientSections[sectionIndex]?.title,
19
+ ingredients: sectionMeta.ingredients.map((ingredMeta, ingredIndex) => ({
20
+ ...ingredMeta,
21
+ ...(content.ingredientSections[sectionIndex]?.ingredients[
22
+ ingredIndex
23
+ ] || {}),
24
+ })),
25
+ }),
26
+ );
27
+
28
+ const instructions = meta.instructions.map((instrMeta, index) => ({
29
+ ...instrMeta,
30
+ ...(content.instructions[index] || {}),
31
+ }));
32
+
33
+ return {
34
+ id: meta.id,
35
+ allergens: meta.allergens,
36
+ confidence: meta.confidence,
37
+ createdAt: meta.createdAt,
38
+ createdBy: meta.createdBy,
39
+ cuisine: meta.cuisine,
40
+ deletedAt: meta.deletedAt,
41
+ dietaryTags: meta.dietaryTags,
42
+ difficulty: meta.difficulty,
43
+ imageUrl: meta.imageUrl,
44
+ mealTypes: meta.mealTypes,
45
+ nutrition: meta.nutrition,
46
+ originalLocale: meta.originalLocale,
47
+ servings: meta.servings,
48
+ source: meta.source,
49
+ sourceUrl: meta.sourceUrl,
50
+ spiciness: meta.spiciness,
51
+ status: meta.status,
52
+ time: meta.time,
53
+ updatedAt: meta.updatedAt,
54
+ equipment,
55
+ ingredientSections,
56
+ instructions,
57
+ description: content.description,
58
+ locale: content.locale,
59
+ tips: content.tips,
60
+ title: content.title,
61
+ };
62
+ }
63
+
64
+ export function splitRecipe(recipe: Recipe): {
65
+ meta: Omit<RecipeMeta, "id">;
66
+ content: RecipeContent;
67
+ } {
68
+ const {
69
+ id,
70
+ description,
71
+ equipment,
72
+ ingredientSections,
73
+ instructions,
74
+ locale,
75
+ tips,
76
+ title,
77
+ ...metaFields
78
+ } = recipe;
79
+
80
+ const equipmentMeta = equipment?.map(({ required, slug }) => ({
81
+ required,
82
+ slug,
83
+ }));
84
+ const equipmentContent = equipment?.map(({ name, notes, slug }) => ({
85
+ name,
86
+ notes,
87
+ slug,
88
+ }));
89
+
90
+ const ingredientSectionsMeta = ingredientSections.map(
91
+ ({ ingredients, slug }) => ({
92
+ slug,
93
+ ingredients: ingredients.map(({ quantity, required, slug, unit }) => ({
94
+ quantity,
95
+ required,
96
+ slug,
97
+ unit,
98
+ })),
99
+ }),
100
+ );
101
+ const ingredientSectionsContent = ingredientSections.map(
102
+ ({ ingredients, slug, title }) => ({
103
+ slug,
104
+ title,
105
+ ingredients: ingredients.map(({ name, notes, slug }) => ({
106
+ name,
107
+ notes,
108
+ slug,
109
+ })),
110
+ }),
111
+ );
112
+
113
+ const instructionsMeta = instructions.map(
114
+ ({ duration, step, temperature }) => ({
115
+ duration,
116
+ step,
117
+ temperature,
118
+ }),
119
+ );
120
+ const instructionsContent = instructions.map(({ step, text }) => ({
121
+ step,
122
+ text,
123
+ }));
124
+
125
+ const content: RecipeContent = {
126
+ description,
127
+ equipment: equipmentContent,
128
+ ingredientSections: ingredientSectionsContent,
129
+ instructions: instructionsContent,
130
+ locale,
131
+ tips,
132
+ title,
133
+ };
134
+
135
+ const meta = {
136
+ ...metaFields,
137
+ equipment: equipmentMeta,
138
+ ingredientSections: ingredientSectionsMeta,
139
+ instructions: instructionsMeta,
140
+ };
141
+
142
+ return { meta, content };
143
+ }
@@ -1,2 +1,2 @@
1
- export * from "./strip-undefined";
2
- export * from "./timestamp";
1
+ export * from "./strip-undefined";
2
+ export * from "./timestamp";
@@ -1,32 +1,32 @@
1
- /**
2
- * Recursively removes undefined values from an object or array.
3
- * This is necessary because Firestore rejects undefined values.
4
- *
5
- * @param obj - The object or array to clean
6
- * @returns A new object/array with undefined values removed
7
- *
8
- * @example
9
- * stripUndefined({ a: 1, b: undefined, c: { d: undefined, e: 2 } })
10
- * // Returns: { a: 1, c: { e: 2 } }
11
- */
12
- export function stripUndefined<T>(obj: T): T {
13
- if (obj === null || obj === undefined) {
14
- return obj;
15
- }
16
-
17
- if (Array.isArray(obj)) {
18
- return obj.map(item => stripUndefined(item)) as T;
19
- }
20
-
21
- if (typeof obj === 'object') {
22
- const cleaned: any = {};
23
- for (const [key, value] of Object.entries(obj)) {
24
- if (value !== undefined) {
25
- cleaned[key] = stripUndefined(value);
26
- }
27
- }
28
- return cleaned as T;
29
- }
30
-
31
- return obj;
32
- }
1
+ /**
2
+ * Recursively removes undefined values from an object or array.
3
+ * This is necessary because Firestore rejects undefined values.
4
+ *
5
+ * @param obj - The object or array to clean
6
+ * @returns A new object/array with undefined values removed
7
+ *
8
+ * @example
9
+ * stripUndefined({ a: 1, b: undefined, c: { d: undefined, e: 2 } })
10
+ * // Returns: { a: 1, c: { e: 2 } }
11
+ */
12
+ export function stripUndefined<T>(obj: T): T {
13
+ if (obj === null || obj === undefined) {
14
+ return obj;
15
+ }
16
+
17
+ if (Array.isArray(obj)) {
18
+ return obj.map((item) => stripUndefined(item)) as T;
19
+ }
20
+
21
+ if (typeof obj === "object") {
22
+ const cleaned: any = {};
23
+ for (const [key, value] of Object.entries(obj)) {
24
+ if (value !== undefined) {
25
+ cleaned[key] = stripUndefined(value);
26
+ }
27
+ }
28
+ return cleaned as T;
29
+ }
30
+
31
+ return obj;
32
+ }
@@ -1,21 +1,21 @@
1
- import { Timestamp as FirestoreTimestamp } from "firebase-admin/firestore";
2
- import type { Timestamp } from "@cravery/core/types";
3
-
4
- export function toTimestamp(timestamp: FirestoreTimestamp): Timestamp {
5
- return {
6
- seconds: timestamp.seconds,
7
- nanoseconds: timestamp.nanoseconds,
8
- };
9
- }
10
-
11
- export function fromTimestamp(timestamp: Timestamp): FirestoreTimestamp {
12
- return FirestoreTimestamp.fromMillis(
13
- timestamp.seconds * 1000 + timestamp.nanoseconds / 1000000,
14
- );
15
- }
16
-
17
- export function toOptionalTimestamp(
18
- timestamp?: FirestoreTimestamp,
19
- ): Timestamp | undefined {
20
- return timestamp ? toTimestamp(timestamp) : undefined;
21
- }
1
+ import { Timestamp as FirestoreTimestamp } from "firebase-admin/firestore";
2
+ import type { Timestamp } from "@cravery/core";
3
+
4
+ export function toTimestamp(timestamp: FirestoreTimestamp): Timestamp {
5
+ return {
6
+ seconds: timestamp.seconds,
7
+ nanoseconds: timestamp.nanoseconds,
8
+ };
9
+ }
10
+
11
+ export function fromTimestamp(timestamp: Timestamp): FirestoreTimestamp {
12
+ return FirestoreTimestamp.fromMillis(
13
+ timestamp.seconds * 1000 + timestamp.nanoseconds / 1000000,
14
+ );
15
+ }
16
+
17
+ export function toOptionalTimestamp(
18
+ timestamp?: FirestoreTimestamp,
19
+ ): Timestamp | undefined {
20
+ return timestamp ? toTimestamp(timestamp) : undefined;
21
+ }