@better-giving/endowment 5.0.0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/schema.mjs CHANGED
@@ -2,6 +2,8 @@ import { $, $int_gte1, $req, MAX_NUM_INCREMENTS, donate_method_id, env, https_ur
2
2
  export { $, $req, $req_num_gt0, donate_method_id, env, https_url, int_gte1, $int_gte1, org_designation, slug, unsdg_num, } from "@better-giving/schemas";
3
3
  import * as v from "valibot";
4
4
  export const min_payout_amount = 50;
5
+ /** used for text to give */
6
+ export const keyword = v.pipe($, v.nonEmpty("required"), v.toLowerCase(), v.maxLength(10, ({ requirement: r }) => `max ${r} characters`), v.regex(/^[a-z]+$/, "must be letters only"));
5
7
  export const csv = v.lazy((x) => {
6
8
  if (!x)
7
9
  return $;
@@ -31,6 +33,7 @@ export const npo = v.object({
31
33
  id: int_gte1,
32
34
  env,
33
35
  slug: v.optional(slug),
36
+ keyword: v.optional(keyword),
34
37
  registration_number: reg_number,
35
38
  name: $req,
36
39
  endow_designation: org_designation,
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@better-giving/endowment",
3
- "version": "5.0.0",
3
+ "version": "6.1.0",
4
4
  "dependencies": {
5
5
  "ksuid": "3.0.0"
6
6
  },
7
7
  "peerDependencies": {
8
- "@better-giving/schemas": "2.1.0",
9
- "@better-giving/types": "1.1.8",
10
- "@better-giving/db": "2.0.7",
11
- "@aws-sdk/lib-dynamodb": "3.485.0",
12
- "valibot": "1.2.0"
8
+ "@better-giving/schemas": "^2.0.0",
9
+ "@better-giving/types": "^1.0.0",
10
+ "@better-giving/db": "^2.0.0",
11
+ "@aws-sdk/lib-dynamodb": "^3.900.0",
12
+ "valibot": "^1.0.0"
13
13
  },
14
14
  "devDependencies": {
15
- "@better-giving/config": "1.1.2"
15
+ "@better-giving/config": "^1.0.0"
16
16
  },
17
17
  "files": [
18
18
  "src",
package/src/db.mts CHANGED
@@ -23,6 +23,7 @@ import type {
23
23
  IMediaDb,
24
24
  IMediaPage,
25
25
  INpoReferredBy,
26
+ INpoWithKeyword,
26
27
  INpoWithRegNum,
27
28
  INpoWithRid,
28
29
  TBinFlag,
@@ -50,6 +51,7 @@ export class NpoDb extends Db {
50
51
  static readonly table = "endowments_v3";
51
52
  static readonly slug_env_gsi = "slug-env-gsi" as const;
52
53
  static readonly regnum_env_gsi = "regnum-env-gsi" as const;
54
+ static readonly keyword_env_gsi = "keyword-env-gsi" as const;
53
55
  key_npo(id: number) {
54
56
  return {
55
57
  PK: `Endow#${id}`,
@@ -83,14 +85,14 @@ export class NpoDb extends Db {
83
85
  };
84
86
  }
85
87
 
86
- gsi1_npo(id: string) {
88
+ gsi1_npo_ref_by_key(id: string) {
87
89
  return {
88
90
  gsi1PK: `ReferredBy#${id}`,
89
91
  gsi1SK: this.env,
90
92
  };
91
93
  }
92
94
 
93
- gsi2_npo(id: string) {
95
+ gsi2_npo_w_rid_key(id: string) {
94
96
  return {
95
97
  gsi2PK: `Rid#${id}`,
96
98
  gsi2SK: `Rid#${id}`,
@@ -164,7 +166,7 @@ export class NpoDb extends Db {
164
166
  IndexName: "gsi1",
165
167
  KeyConditionExpression: "#pk = :pk",
166
168
  ExpressionAttributeValues: {
167
- ":pk": this.gsi1_npo(id).gsi1PK,
169
+ ":pk": this.gsi1_npo_ref_by_key(id).gsi1PK,
168
170
  },
169
171
  ExpressionAttributeNames: { "#pk": "gsi1PK" },
170
172
  });
@@ -178,7 +180,7 @@ export class NpoDb extends Db {
178
180
  IndexName: "gsi2",
179
181
  KeyConditionExpression: "gsi2PK = :pk",
180
182
  ExpressionAttributeValues: {
181
- ":pk": this.gsi2_npo(id).gsi2PK,
183
+ ":pk": this.gsi2_npo_w_rid_key(id).gsi2PK,
182
184
  },
183
185
  Limit: 1,
184
186
  });
@@ -186,6 +188,29 @@ export class NpoDb extends Db {
186
188
  const i = Items[0];
187
189
  return i && this.sans_keys(i);
188
190
  }
191
+ async npo_with_keyword(
192
+ keyword: string,
193
+ env = this.env
194
+ ): Promise<INpoWithKeyword | undefined> {
195
+ const cmd = new QueryCommand({
196
+ TableName: NpoDb.table,
197
+ IndexName: NpoDb.keyword_env_gsi,
198
+ KeyConditionExpression: "#kw = :kw AND #env = :env",
199
+ ExpressionAttributeNames: {
200
+ "#kw": "keyword" satisfies TNpoDbKeys,
201
+ "#env": "env" satisfies TNpoDbKeys,
202
+ },
203
+ ExpressionAttributeValues: {
204
+ ":kw": keyword,
205
+ ":env": env,
206
+ },
207
+ Limit: 1,
208
+ });
209
+
210
+ const { Items = [] } = await this.client.send(cmd);
211
+ const i = Items[0];
212
+ return i && this.sans_keys(i);
213
+ }
189
214
 
190
215
  async npo_with_regnum(
191
216
  regnum: string,
@@ -219,8 +244,8 @@ export class NpoDb extends Db {
219
244
  return {
220
245
  ...this.key_npo(data.id),
221
246
  ...data,
222
- ...(data.referrer ? this.gsi1_npo(data.referrer) : {}),
223
- ...(data.referral_id ? this.gsi2_npo(data.referral_id) : {}),
247
+ ...(data.referrer ? this.gsi1_npo_ref_by_key(data.referrer) : {}),
248
+ ...(data.referral_id ? this.gsi2_npo_w_rid_key(data.referral_id) : {}),
224
249
  };
225
250
  }
226
251
 
@@ -27,6 +27,7 @@ export interface INpoReferredBy
27
27
  extends Ensure<INpo, "referrer" | "referrer_expiry"> {}
28
28
 
29
29
  export interface INpoWithRid extends Ensure<INpo, "referral_id"> {}
30
+ export interface INpoWithKeyword extends Ensure<INpo, "keyword"> {}
30
31
 
31
32
  export interface INpoWithRegNum
32
33
  extends Pick<
package/src/npo.mts CHANGED
@@ -20,6 +20,7 @@ export const npo_fields: { [K in keyof Required<INpo>]: "" } = {
20
20
  tagline: "",
21
21
  url: "",
22
22
  slug: "",
23
+ keyword: "",
23
24
  claimed: "",
24
25
  card_img: "",
25
26
  progDonationsAllowed: "",
package/src/schema.mts CHANGED
@@ -30,6 +30,15 @@ import * as v from "valibot";
30
30
 
31
31
  export const min_payout_amount = 50;
32
32
 
33
+ /** used for text to give */
34
+ export const keyword = v.pipe(
35
+ $,
36
+ v.nonEmpty("required"),
37
+ v.toLowerCase(),
38
+ v.maxLength(10, ({ requirement: r }) => `max ${r} characters`),
39
+ v.regex(/^[a-z]+$/, "must be letters only")
40
+ );
41
+
33
42
  export const csv = v.lazy((x) => {
34
43
  if (!x) return $;
35
44
  return v.pipe($, v.regex(/^[^,]+(?:,[^,]+)*$/, "invalid csv"));
@@ -80,6 +89,7 @@ export const npo = v.object({
80
89
  id: int_gte1,
81
90
  env,
82
91
  slug: v.optional(slug),
92
+ keyword: v.optional(keyword),
83
93
  registration_number: reg_number,
84
94
  name: $req,
85
95
  endow_designation: org_designation,