@better-giving/endowment 2.0.6 → 3.0.2
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/cloudsearch.d.mts +1 -1
- package/dist/cloudsearch.mjs +3 -3
- package/dist/db.d.mts +138 -115
- package/dist/db.mjs +355 -4
- package/dist/index.d.mts +2 -20
- package/dist/index.mjs +2 -1
- package/dist/interfaces.d.mts +41 -0
- package/dist/interfaces.mjs +1 -0
- package/dist/media.d.mts +11 -0
- package/dist/media.mjs +48 -0
- package/dist/npo.d.mts +4 -0
- package/dist/npo.mjs +41 -0
- package/dist/schema.d.mts +42 -43
- package/dist/schema.mjs +36 -40
- package/package.json +7 -2
- package/src/cloudsearch.mts +3 -2
- package/src/db.mts +414 -124
- package/src/index.mts +2 -45
- package/src/interfaces.mts +73 -0
- package/src/media.mts +67 -0
- package/src/npo.mts +47 -0
- package/src/schema.mts +57 -89
package/dist/cloudsearch.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ToDoc, ToHitFields, ToUpdate } from "@better-giving/types/cloudsearch";
|
|
2
|
+
import type { Environment } from "@better-giving/types/list";
|
|
2
3
|
import { type InferInput, type InferOutput } from "valibot";
|
|
3
|
-
import { type Environment } from "./schema.mjs";
|
|
4
4
|
export declare const cloudsearchEndowFields: import("valibot").ObjectSchema<{
|
|
5
5
|
readonly contributions_total: import("valibot").NumberSchema<undefined>;
|
|
6
6
|
readonly contributions_count: import("valibot").NumberSchema<undefined>;
|
package/dist/cloudsearch.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { $int_gte1, org_designation, unsdg_num } from "@better-giving/schemas";
|
|
2
|
-
import { array, boolean,
|
|
3
|
-
import { $, csvStrs,
|
|
2
|
+
import { array, boolean, keyof, mapItems, number, object, optional, pick, pipe, } from "valibot";
|
|
3
|
+
import { $, csvStrs, npo } from "./schema.mjs";
|
|
4
4
|
const boolCsv = pipe(csvStrs, mapItems((x) => x === "true"), array(boolean()));
|
|
5
5
|
export const cloudsearchEndowFields = object({
|
|
6
6
|
contributions_total: number(),
|
|
7
7
|
contributions_count: number(),
|
|
8
8
|
});
|
|
9
9
|
export const cloudsearchEndow = object({
|
|
10
|
-
...pick(
|
|
10
|
+
...pick(npo, [
|
|
11
11
|
"card_img",
|
|
12
12
|
"name",
|
|
13
13
|
"tagline",
|
package/dist/db.d.mts
CHANGED
|
@@ -1,120 +1,143 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
export declare
|
|
5
|
-
readonly
|
|
6
|
-
readonly
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
SK: Environment;
|
|
12
|
-
}
|
|
13
|
-
interface NonKeyAttributes {
|
|
14
|
-
count: number;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
export declare namespace Endow {
|
|
18
|
-
type Keys = {
|
|
19
|
-
PK: `Endow#${number}`;
|
|
20
|
-
SK: Environment;
|
|
1
|
+
import { Db } from "@better-giving/db";
|
|
2
|
+
import type { IMedia, IMediaPage, INpoReferredBy, INpoWithRegNum, INpoWithRid, TBinFlag, TNpoDbKeys, TNpoDbProjectedTo } from "./interfaces.mjs";
|
|
3
|
+
import type { IMediaSearchObj, IMilestone, IMilestoneUpdate, INpo, INpoUpdate, IProgram, IProgramDb, IProgramNew, IProgramUpdate, TMediaType } from "./schema.mjs";
|
|
4
|
+
export declare class NpoDb extends Db {
|
|
5
|
+
static readonly name = "endowments_v3";
|
|
6
|
+
static readonly slug_env_gsi: "slug-env-gsi";
|
|
7
|
+
static readonly regnum_env_gsi: "regnum-env-gsi";
|
|
8
|
+
key_npo(id: number): {
|
|
9
|
+
PK: string;
|
|
10
|
+
SK: import("@better-giving/types/list").Environment;
|
|
21
11
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
/** expiry / date onboarded */
|
|
26
|
-
gsi1SK?: string;
|
|
27
|
-
/** Rid#referral_id */
|
|
28
|
-
gsi2PK?: `Rid#${string}`;
|
|
29
|
-
gsi2SK?: `Rid#${string}`;
|
|
30
|
-
/** will only be present for unclaimed NPOs */
|
|
31
|
-
updated_at_auto?: string;
|
|
32
|
-
/** in USD @deprecated */
|
|
33
|
-
payout_minimum?: number;
|
|
34
|
-
/** @deprecated */
|
|
35
|
-
splitLiqPct?: number;
|
|
36
|
-
/** @deprecated */
|
|
37
|
-
splitFixed?: boolean;
|
|
38
|
-
/** @deprecated */
|
|
39
|
-
sfCompounded?: boolean;
|
|
12
|
+
get key_count(): {
|
|
13
|
+
PK: string;
|
|
14
|
+
SK: import("@better-giving/types/list").Environment;
|
|
40
15
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
16
|
+
key_npo_program(id: string, npo: number): {
|
|
17
|
+
PK: string;
|
|
18
|
+
SK: string;
|
|
19
|
+
};
|
|
20
|
+
key_prog_milestone(id: string, prog: string): {
|
|
21
|
+
PK: string;
|
|
22
|
+
SK: string;
|
|
23
|
+
};
|
|
24
|
+
key_npo_med(ksuid: string, npo: number): {
|
|
25
|
+
PK: string;
|
|
26
|
+
SK: string;
|
|
27
|
+
};
|
|
28
|
+
gsi1_npo(id: string): {
|
|
29
|
+
gsi1PK: string;
|
|
30
|
+
gsi1SK: import("@better-giving/types/list").Environment;
|
|
31
|
+
};
|
|
32
|
+
gsi2_npo(id: string): {
|
|
33
|
+
gsi2PK: string;
|
|
34
|
+
gsi2SK: string;
|
|
35
|
+
};
|
|
36
|
+
gsi1_npo_med(id: string, npo: number, featured: TBinFlag, type: TMediaType): {
|
|
37
|
+
gsi1PK: string;
|
|
38
|
+
gsi1SK: string;
|
|
39
|
+
};
|
|
40
|
+
npo_media(npo: number, opts: IMediaSearchObj): Promise<IMediaPage>;
|
|
41
|
+
npo_referred_by(id: string): Promise<INpoReferredBy[]>;
|
|
42
|
+
npo_with_rid(id: string): Promise<INpoWithRid | undefined>;
|
|
43
|
+
npo_with_regnum(regnum: string, country?: string): Promise<INpoWithRegNum | undefined>;
|
|
44
|
+
npo_record(data: INpo): {
|
|
45
|
+
gsi2PK?: string | undefined;
|
|
46
|
+
gsi2SK?: string | undefined;
|
|
47
|
+
gsi1PK?: string | undefined;
|
|
48
|
+
gsi1SK?: import("@better-giving/types/list").Environment | undefined;
|
|
49
|
+
active_in_countries: string[];
|
|
50
|
+
sdgs: (2 | 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17)[];
|
|
51
|
+
id: number;
|
|
52
|
+
env: "staging" | "production";
|
|
53
|
+
registration_number: string;
|
|
54
|
+
name: string;
|
|
55
|
+
endow_designation: "Charity" | "Religious Organization" | "University" | "Hospital" | "Other";
|
|
56
|
+
hq_country: string;
|
|
57
|
+
social_media_urls: {
|
|
58
|
+
facebook?: string | undefined;
|
|
59
|
+
twitter?: string | undefined;
|
|
60
|
+
linkedin?: string | undefined;
|
|
61
|
+
discord?: string | undefined;
|
|
62
|
+
instagram?: string | undefined;
|
|
63
|
+
youtube?: string | undefined;
|
|
64
|
+
tiktok?: string | undefined;
|
|
65
|
+
};
|
|
66
|
+
claimed: boolean;
|
|
67
|
+
kyc_donors_only: boolean;
|
|
68
|
+
fiscal_sponsored: boolean;
|
|
69
|
+
url?: string | undefined;
|
|
70
|
+
slug?: string | undefined;
|
|
71
|
+
overview?: string | undefined;
|
|
72
|
+
tagline?: string | undefined;
|
|
73
|
+
image?: string | undefined;
|
|
74
|
+
logo?: string | undefined;
|
|
75
|
+
card_img?: string | undefined;
|
|
76
|
+
street_address?: string | undefined;
|
|
77
|
+
receiptMsg?: string | undefined;
|
|
78
|
+
hide_bg_tip?: boolean | undefined;
|
|
79
|
+
published?: boolean | undefined;
|
|
80
|
+
progDonationsAllowed?: boolean | undefined;
|
|
81
|
+
allocation?: {
|
|
82
|
+
cash: number;
|
|
83
|
+
liq: number;
|
|
84
|
+
lock: number;
|
|
85
|
+
} | undefined;
|
|
86
|
+
donateMethods?: ("stripe" | "crypto" | "daf" | "stocks")[] | undefined;
|
|
87
|
+
increments?: {
|
|
88
|
+
value: string;
|
|
89
|
+
label: string;
|
|
90
|
+
}[] | undefined;
|
|
91
|
+
fund_opt_in?: boolean | undefined;
|
|
92
|
+
target?: string | undefined;
|
|
93
|
+
referral_id?: string | undefined;
|
|
94
|
+
referrer?: string | undefined;
|
|
95
|
+
referrer_expiry?: string | undefined;
|
|
96
|
+
w_form?: string | undefined;
|
|
97
|
+
payout_minimum?: number | undefined;
|
|
98
|
+
PK: string;
|
|
99
|
+
SK: import("@better-giving/types/list").Environment;
|
|
100
|
+
};
|
|
101
|
+
npo_prog_record(npo: number, data: IProgramDb): {
|
|
102
|
+
id: string;
|
|
103
|
+
title: string;
|
|
104
|
+
description: string;
|
|
105
|
+
banner?: string | undefined;
|
|
106
|
+
targetRaise?: number | null | undefined;
|
|
107
|
+
totalDonations?: number | undefined;
|
|
108
|
+
PK: string;
|
|
109
|
+
SK: string;
|
|
110
|
+
};
|
|
111
|
+
prog_milestone_record(prog: string, data: IMilestone): {
|
|
112
|
+
id: string;
|
|
113
|
+
date: string;
|
|
114
|
+
title: string;
|
|
115
|
+
description: string;
|
|
116
|
+
media?: string | undefined;
|
|
117
|
+
PK: string;
|
|
118
|
+
SK: string;
|
|
119
|
+
};
|
|
120
|
+
npo_med_record(npo_id: number, { featured /** not saved as attribute */, ...d }: IMedia): {
|
|
121
|
+
id: string;
|
|
122
|
+
type: Extract<TMediaType, "video">;
|
|
88
123
|
dateCreated: string;
|
|
89
|
-
}
|
|
90
|
-
interface VideoAttributes extends NonKeyAttributes {
|
|
91
|
-
type: Extract<MediaType, "video">;
|
|
92
124
|
url: string;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
export declare namespace Gsi2 {
|
|
113
|
-
namespace Rid {
|
|
114
|
-
interface Keys extends Required<Pick<Endow.NonKeyAttributes, "gsi1PK" | "gsi1SK">> {
|
|
115
|
-
}
|
|
116
|
-
interface DbRecord extends Ensure<Endow.DbRecord, "gsi1PK" | "gsi1SK" | "referral_id"> {
|
|
117
|
-
}
|
|
118
|
-
}
|
|
125
|
+
gsi1PK: string;
|
|
126
|
+
gsi1SK: string;
|
|
127
|
+
PK: string;
|
|
128
|
+
SK: string;
|
|
129
|
+
};
|
|
130
|
+
npo_med_put(npo: number, url: string): Promise<string>;
|
|
131
|
+
npo_med(npo: number, mid: string): Promise<IMedia | undefined>;
|
|
132
|
+
npo_med_delete(npo: number, mid: string): Promise<import("@aws-sdk/lib-dynamodb").DeleteCommandOutput>;
|
|
133
|
+
npo<T extends TNpoDbKeys[]>(id: string | number, fields?: T): Promise<TNpoDbProjectedTo<T> | undefined>;
|
|
134
|
+
npo_update(id: number, { target, slug, social_media_urls, ...update }: INpoUpdate): Promise<import("@aws-sdk/lib-dynamodb").UpdateCommandOutput>;
|
|
135
|
+
prog_milestones(id: string): Promise<IMilestone[]>;
|
|
136
|
+
prog_milestone_delete(pid: string, mid: string): Promise<import("@aws-sdk/lib-dynamodb").DeleteCommandOutput>;
|
|
137
|
+
prog_milestone_update(pid: string, mid: string, update: IMilestoneUpdate): Promise<Record<string, any> | undefined>;
|
|
138
|
+
npo_program(id: string, npo_id: number): Promise<IProgram | undefined>;
|
|
139
|
+
npo_programs(id: number): Promise<IProgramDb[]>;
|
|
140
|
+
npo_program_put(npo: number, content: IProgramNew): Promise<string>;
|
|
141
|
+
npo_prog_del(npo: number, prog: string): Promise<import("@aws-sdk/lib-dynamodb").TransactWriteCommandOutput>;
|
|
142
|
+
npo_prog_update(npo: number, prog: string, update: IProgramUpdate): Promise<Record<string, any> | undefined>;
|
|
119
143
|
}
|
|
120
|
-
export type DbRecord = Endow.DbRecord | Program.DbRecord;
|
package/dist/db.mjs
CHANGED
|
@@ -1,4 +1,355 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
1
|
+
import { DeleteCommand, GetCommand, PutCommand, QueryCommand, TransactWriteCommand, UpdateCommand, } from "@aws-sdk/lib-dynamodb";
|
|
2
|
+
import { Db, Txs, UpdateBuilder } from "@better-giving/db";
|
|
3
|
+
import KSUID from "ksuid";
|
|
4
|
+
import { med_key_filter, med_sk, to_imedia } from "./media.mjs";
|
|
5
|
+
import { projection } from "./npo.mjs";
|
|
6
|
+
export class NpoDb extends Db {
|
|
7
|
+
static name = "endowments_v3";
|
|
8
|
+
static slug_env_gsi = "slug-env-gsi";
|
|
9
|
+
static regnum_env_gsi = "regnum-env-gsi";
|
|
10
|
+
key_npo(id) {
|
|
11
|
+
return {
|
|
12
|
+
PK: `Endow#${id}`,
|
|
13
|
+
SK: this.env,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
get key_count() {
|
|
17
|
+
return {
|
|
18
|
+
PK: "Count",
|
|
19
|
+
SK: this.env,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
key_npo_program(id, npo) {
|
|
23
|
+
return {
|
|
24
|
+
PK: `Endow#${npo}#${this.env}`,
|
|
25
|
+
SK: `Prog#${id}`,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
key_prog_milestone(id, prog) {
|
|
29
|
+
return {
|
|
30
|
+
PK: `Prog#${prog}#${this.env}`,
|
|
31
|
+
SK: `Mile#${id}`,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
key_npo_med(ksuid, npo) {
|
|
35
|
+
return {
|
|
36
|
+
PK: `Endow#${npo}#${this.env}`,
|
|
37
|
+
SK: `Media#${ksuid}`,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
gsi1_npo(id) {
|
|
41
|
+
return {
|
|
42
|
+
gsi1PK: `ReferredBy#${id}`,
|
|
43
|
+
gsi1SK: this.env,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
gsi2_npo(id) {
|
|
47
|
+
return {
|
|
48
|
+
gsi2PK: `Rid#${id}`,
|
|
49
|
+
gsi2SK: `Rid#${id}`,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
gsi1_npo_med(id, npo, featured, type) {
|
|
53
|
+
return {
|
|
54
|
+
gsi1PK: this.key_npo_med(id, npo).PK,
|
|
55
|
+
gsi1SK: med_sk(id, type, featured),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
async npo_media(npo, opts) {
|
|
59
|
+
const PK = this.key_npo_med("ksuid-sk", npo).PK;
|
|
60
|
+
const [expression, values] = med_key_filter(PK, opts);
|
|
61
|
+
const cmd = new QueryCommand({
|
|
62
|
+
TableName: NpoDb.name,
|
|
63
|
+
IndexName: "gsi1",
|
|
64
|
+
Limit: opts.limit,
|
|
65
|
+
KeyConditionExpression: expression,
|
|
66
|
+
ExpressionAttributeValues: values,
|
|
67
|
+
ExclusiveStartKey: this.key_to_obj(opts.next),
|
|
68
|
+
});
|
|
69
|
+
const res = await this.client.send(cmd);
|
|
70
|
+
const page = this.to_page(res, to_imedia);
|
|
71
|
+
return page;
|
|
72
|
+
}
|
|
73
|
+
async npo_referred_by(id) {
|
|
74
|
+
const cmd = new QueryCommand({
|
|
75
|
+
TableName: NpoDb.name,
|
|
76
|
+
IndexName: "gsi1",
|
|
77
|
+
KeyConditionExpression: "#pk = :pk",
|
|
78
|
+
ExpressionAttributeValues: {
|
|
79
|
+
":pk": this.gsi1_npo(id).gsi1PK,
|
|
80
|
+
},
|
|
81
|
+
ExpressionAttributeNames: { "#pk": "gsi1PK" },
|
|
82
|
+
});
|
|
83
|
+
const { Items = [] } = await this.client.send(cmd);
|
|
84
|
+
return Items.map((x) => this.sans_keys(x));
|
|
85
|
+
}
|
|
86
|
+
async npo_with_rid(id) {
|
|
87
|
+
const cmd = new QueryCommand({
|
|
88
|
+
TableName: NpoDb.name,
|
|
89
|
+
IndexName: "gsi2",
|
|
90
|
+
KeyConditionExpression: "gsi2PK = :pk",
|
|
91
|
+
ExpressionAttributeValues: {
|
|
92
|
+
":pk": this.gsi2_npo(id).gsi2PK,
|
|
93
|
+
},
|
|
94
|
+
Limit: 1,
|
|
95
|
+
});
|
|
96
|
+
const { Items = [] } = await this.client.send(cmd);
|
|
97
|
+
const i = Items[0];
|
|
98
|
+
return i && this.sans_keys(i);
|
|
99
|
+
}
|
|
100
|
+
async npo_with_regnum(regnum, country = "United States") {
|
|
101
|
+
const cmd = new QueryCommand({
|
|
102
|
+
TableName: NpoDb.name,
|
|
103
|
+
IndexName: NpoDb.regnum_env_gsi,
|
|
104
|
+
Limit: 1,
|
|
105
|
+
KeyConditionExpression: "#rn = :rn AND #env = :env",
|
|
106
|
+
FilterExpression: "#country = :country",
|
|
107
|
+
ExpressionAttributeNames: {
|
|
108
|
+
"#rn": "registration_number",
|
|
109
|
+
"#env": "env",
|
|
110
|
+
"#country": "hq_country",
|
|
111
|
+
},
|
|
112
|
+
ExpressionAttributeValues: {
|
|
113
|
+
":rn": regnum,
|
|
114
|
+
":env": this.env,
|
|
115
|
+
":country": country,
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
const { Items = [] } = await this.client.send(cmd);
|
|
119
|
+
const i = Items[0];
|
|
120
|
+
return i && this.sans_keys(i);
|
|
121
|
+
}
|
|
122
|
+
npo_record(data) {
|
|
123
|
+
return {
|
|
124
|
+
...this.key_npo(data.id),
|
|
125
|
+
...data,
|
|
126
|
+
...(data.referrer ? this.gsi1_npo(data.referrer) : {}),
|
|
127
|
+
...(data.referral_id ? this.gsi2_npo(data.referral_id) : {}),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
npo_prog_record(npo, data) {
|
|
131
|
+
return {
|
|
132
|
+
...this.key_npo_program(data.id, npo),
|
|
133
|
+
...data,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
prog_milestone_record(prog, data) {
|
|
137
|
+
return {
|
|
138
|
+
...this.key_prog_milestone(data.id, prog),
|
|
139
|
+
...data,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
npo_med_record(npo_id, { featured /** not saved as attribute */, ...d }) {
|
|
143
|
+
return {
|
|
144
|
+
...this.key_npo_med(d.id, npo_id),
|
|
145
|
+
...this.gsi1_npo_med(d.id, npo_id, featured ? "1" : "0", d.type),
|
|
146
|
+
...d,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
async npo_med_put(npo, url) {
|
|
150
|
+
const ksuid = KSUID.randomSync();
|
|
151
|
+
const mid = ksuid.string;
|
|
152
|
+
const item = this.npo_med_record(npo, {
|
|
153
|
+
id: mid,
|
|
154
|
+
url,
|
|
155
|
+
type: "video",
|
|
156
|
+
dateCreated: ksuid.date.toISOString(),
|
|
157
|
+
featured: false,
|
|
158
|
+
});
|
|
159
|
+
const command = new PutCommand({
|
|
160
|
+
TableName: NpoDb.name,
|
|
161
|
+
Item: item,
|
|
162
|
+
});
|
|
163
|
+
await this.client.send(command);
|
|
164
|
+
return mid;
|
|
165
|
+
}
|
|
166
|
+
async npo_med(npo, mid) {
|
|
167
|
+
const cmd = new GetCommand({
|
|
168
|
+
TableName: NpoDb.name,
|
|
169
|
+
Key: this.key_npo_med(mid, npo),
|
|
170
|
+
});
|
|
171
|
+
const { Item: i } = await this.client.send(cmd);
|
|
172
|
+
return i && to_imedia(i);
|
|
173
|
+
}
|
|
174
|
+
async npo_med_delete(npo, mid) {
|
|
175
|
+
const cmd = new DeleteCommand({
|
|
176
|
+
TableName: NpoDb.name,
|
|
177
|
+
Key: this.key_npo_med(mid, npo),
|
|
178
|
+
});
|
|
179
|
+
return this.client.send(cmd);
|
|
180
|
+
}
|
|
181
|
+
async npo(id, fields) {
|
|
182
|
+
const { names, expression } = projection(fields);
|
|
183
|
+
if (typeof id === "string") {
|
|
184
|
+
const cmd = new QueryCommand({
|
|
185
|
+
TableName: NpoDb.name,
|
|
186
|
+
IndexName: NpoDb.slug_env_gsi,
|
|
187
|
+
KeyConditionExpression: "#slug = :slug and #env = :env",
|
|
188
|
+
ExpressionAttributeValues: {
|
|
189
|
+
":slug": id,
|
|
190
|
+
":env": this.env,
|
|
191
|
+
},
|
|
192
|
+
ProjectionExpression: expression,
|
|
193
|
+
ExpressionAttributeNames: {
|
|
194
|
+
...names,
|
|
195
|
+
"#env": "env",
|
|
196
|
+
"#slug": "slug",
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
const [x] = await this.client.send(cmd).then(({ Items: x = [] }) => x);
|
|
200
|
+
return x ? this.sans_keys(x) : undefined;
|
|
201
|
+
}
|
|
202
|
+
const cmd = new GetCommand({
|
|
203
|
+
TableName: NpoDb.name,
|
|
204
|
+
Key: this.key_npo(id),
|
|
205
|
+
ProjectionExpression: expression,
|
|
206
|
+
ExpressionAttributeNames: names,
|
|
207
|
+
});
|
|
208
|
+
const { Item: i } = await this.client.send(cmd);
|
|
209
|
+
return i ? this.sans_keys(i) : undefined;
|
|
210
|
+
}
|
|
211
|
+
async npo_update(id, { target, slug, social_media_urls, ...update }) {
|
|
212
|
+
const updates = new UpdateBuilder();
|
|
213
|
+
if (slug)
|
|
214
|
+
updates.set("slug", slug);
|
|
215
|
+
if (slug === "")
|
|
216
|
+
updates.remove("slug");
|
|
217
|
+
if (target || target === "0") {
|
|
218
|
+
updates.set("target", target);
|
|
219
|
+
}
|
|
220
|
+
if (social_media_urls) {
|
|
221
|
+
for (const [k, v] of Object.entries(social_media_urls)) {
|
|
222
|
+
if (v === undefined)
|
|
223
|
+
continue;
|
|
224
|
+
updates.set(`social_media_urls.${k}`, v);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
for (const [k, v] of Object.entries(update)) {
|
|
228
|
+
if (v === undefined)
|
|
229
|
+
continue;
|
|
230
|
+
updates.set(k, v);
|
|
231
|
+
}
|
|
232
|
+
const cmd = new UpdateCommand({
|
|
233
|
+
TableName: NpoDb.name,
|
|
234
|
+
Key: this.key_npo(id),
|
|
235
|
+
ReturnValues: "ALL_NEW",
|
|
236
|
+
...updates.collect(),
|
|
237
|
+
});
|
|
238
|
+
return this.client.send(cmd);
|
|
239
|
+
}
|
|
240
|
+
async prog_milestones(id) {
|
|
241
|
+
const command = new QueryCommand({
|
|
242
|
+
TableName: NpoDb.name,
|
|
243
|
+
KeyConditionExpression: `PK = :PK`,
|
|
244
|
+
ExpressionAttributeValues: {
|
|
245
|
+
":PK": this.key_prog_milestone("not-used", id).PK,
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
return this.client
|
|
249
|
+
.send(command)
|
|
250
|
+
.then(({ Items: x = [] }) => x.map((i) => this.sans_keys(i)));
|
|
251
|
+
}
|
|
252
|
+
async prog_milestone_delete(pid, mid) {
|
|
253
|
+
const cmd = new DeleteCommand({
|
|
254
|
+
TableName: NpoDb.name,
|
|
255
|
+
Key: this.key_prog_milestone(mid, pid),
|
|
256
|
+
});
|
|
257
|
+
return this.client.send(cmd);
|
|
258
|
+
}
|
|
259
|
+
async prog_milestone_update(pid, mid, update) {
|
|
260
|
+
const upd8 = new UpdateBuilder();
|
|
261
|
+
for (const [key, value] of Object.entries(update)) {
|
|
262
|
+
upd8.set(key, value);
|
|
263
|
+
}
|
|
264
|
+
const cmd = new UpdateCommand({
|
|
265
|
+
TableName: NpoDb.name,
|
|
266
|
+
Key: this.key_prog_milestone(mid, pid),
|
|
267
|
+
...upd8.collect(),
|
|
268
|
+
ReturnValues: "ALL_NEW",
|
|
269
|
+
});
|
|
270
|
+
return this.client.send(cmd).then((res) => res.Attributes);
|
|
271
|
+
}
|
|
272
|
+
async npo_program(id, npo_id) {
|
|
273
|
+
const cmd = new GetCommand({
|
|
274
|
+
TableName: NpoDb.name,
|
|
275
|
+
Key: this.key_npo_program(id, npo_id),
|
|
276
|
+
});
|
|
277
|
+
const { Item: p } = await this.client.send(cmd);
|
|
278
|
+
if (!p)
|
|
279
|
+
return undefined;
|
|
280
|
+
const milestones = await this.prog_milestones(id);
|
|
281
|
+
return {
|
|
282
|
+
...this.sans_keys(p),
|
|
283
|
+
milestones: milestones.toSorted((a, b) => a.date.localeCompare(b.date)),
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
async npo_programs(id) {
|
|
287
|
+
const cmd = new QueryCommand({
|
|
288
|
+
TableName: NpoDb.name,
|
|
289
|
+
KeyConditionExpression: `PK = :PK and begins_with(SK, :SK)`,
|
|
290
|
+
ExpressionAttributeValues: {
|
|
291
|
+
":PK": this.key_npo_program("not-used", id).PK,
|
|
292
|
+
":SK": "Prog#",
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
const { Items: x = [] } = await this.client.send(cmd);
|
|
296
|
+
return x.map((i) => this.sans_keys(i));
|
|
297
|
+
}
|
|
298
|
+
async npo_program_put(npo, content) {
|
|
299
|
+
const pid = crypto.randomUUID();
|
|
300
|
+
const { milestones, ...prog } = content;
|
|
301
|
+
const txs = new Txs();
|
|
302
|
+
const db_prog = this.npo_prog_record(npo, {
|
|
303
|
+
...prog,
|
|
304
|
+
id: pid,
|
|
305
|
+
totalDonations: 0,
|
|
306
|
+
});
|
|
307
|
+
txs.put({
|
|
308
|
+
TableName: NpoDb.name,
|
|
309
|
+
Item: db_prog,
|
|
310
|
+
});
|
|
311
|
+
for (const m of milestones || []) {
|
|
312
|
+
const mid = crypto.randomUUID();
|
|
313
|
+
txs.put({
|
|
314
|
+
TableName: NpoDb.name,
|
|
315
|
+
Item: this.prog_milestone_record(pid, { ...m, id: mid }),
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
const cmd = new TransactWriteCommand({
|
|
319
|
+
TransactItems: txs.all,
|
|
320
|
+
});
|
|
321
|
+
await this.client.send(cmd);
|
|
322
|
+
return pid;
|
|
323
|
+
}
|
|
324
|
+
async npo_prog_del(npo, prog) {
|
|
325
|
+
const milestones = await this.prog_milestones(prog);
|
|
326
|
+
const txs = new Txs();
|
|
327
|
+
txs.del({
|
|
328
|
+
TableName: NpoDb.name,
|
|
329
|
+
Key: this.key_npo_program(prog, npo),
|
|
330
|
+
});
|
|
331
|
+
for (const m of milestones) {
|
|
332
|
+
txs.del({
|
|
333
|
+
TableName: NpoDb.name,
|
|
334
|
+
Key: this.key_prog_milestone(m.id, prog),
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
const cmd = new TransactWriteCommand({
|
|
338
|
+
TransactItems: txs.all,
|
|
339
|
+
});
|
|
340
|
+
return this.client.send(cmd);
|
|
341
|
+
}
|
|
342
|
+
async npo_prog_update(npo, prog, update) {
|
|
343
|
+
const upd8 = new UpdateBuilder();
|
|
344
|
+
for (const [key, value] of Object.entries(update)) {
|
|
345
|
+
upd8.set(key, value);
|
|
346
|
+
}
|
|
347
|
+
const cmd = new UpdateCommand({
|
|
348
|
+
TableName: NpoDb.name,
|
|
349
|
+
Key: this.key_npo_program(prog, npo),
|
|
350
|
+
...upd8.collect(),
|
|
351
|
+
ReturnValues: "ALL_NEW",
|
|
352
|
+
});
|
|
353
|
+
return this.client.send(cmd).then((res) => res.Attributes);
|
|
354
|
+
}
|
|
355
|
+
}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import type { Media } from "./db.mjs";
|
|
4
|
-
import type { Milestone, Program as ProgramShape } from "./schema.mjs";
|
|
5
|
-
export type { Allocation, DonateMethodId, EndowDesignation, Endowment as Endow, EndowFields, EndowQueryParams, EndowUpdate, Environment, Increment, MediaQueryParams, MediaQueryParamsObj, MediaType, MediaUpdate, Milestone, MilestoneUpdate, NewMilestone, NewProgram, ProgramUpdate, SocialMediaURLs, UnSdgNum, } from "./schema.mjs";
|
|
1
|
+
export * from "./interfaces.mjs";
|
|
2
|
+
export { NpoDb } from "./db.mjs";
|
|
6
3
|
export type { CloudsearchEndow as EndowItem, CloudsearchEndowsQueryParams as EndowsQueryParams, CloudsearchEndowsQueryParamsParsed as EndowsQueryParamsParsed, } from "./cloudsearch.mjs";
|
|
7
|
-
/** client responsible on T depending on keys projected */
|
|
8
|
-
export interface EndowsPage<T extends keyof EndowItem = keyof EndowItem> {
|
|
9
|
-
items: Pick<EndowItem, T>[];
|
|
10
|
-
page: number;
|
|
11
|
-
pages: number;
|
|
12
|
-
}
|
|
13
|
-
export interface Program extends ProgramShape {
|
|
14
|
-
milestones: Milestone[];
|
|
15
|
-
}
|
|
16
|
-
/** web-app format */
|
|
17
|
-
export interface IMedia extends Omit<Media.DbRecord, "PK" | "SK" | "gsi1PK" | "gsi1SK"> {
|
|
18
|
-
featured: boolean;
|
|
19
|
-
}
|
|
20
|
-
export interface MediaPage extends IPageKeyed<IMedia> {
|
|
21
|
-
}
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from "./interfaces.mjs";
|
|
2
|
+
export { NpoDb } from "./db.mjs";
|