@ewanc26/supporters 0.1.1 → 0.1.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/store.d.ts +12 -3
- package/dist/store.js +24 -7
- package/package.json +1 -1
package/dist/store.d.ts
CHANGED
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Required environment variables:
|
|
13
13
|
* ATPROTO_DID — your DID, e.g. did:plc:abc123
|
|
14
|
-
* ATPROTO_PDS_URL — your PDS URL, e.g. https://pds.ewancroft.uk
|
|
15
14
|
* ATPROTO_APP_PASSWORD — an app password from your PDS settings
|
|
15
|
+
*
|
|
16
|
+
* The PDS URL is resolved automatically from the DID via Slingshot.
|
|
16
17
|
*/
|
|
17
18
|
import type { KofiSupporter, KofiEventType } from './types.js';
|
|
18
19
|
/** The shape of a raw record stored in the PDS. */
|
|
@@ -20,6 +21,9 @@ export interface KofiEventRecord {
|
|
|
20
21
|
name: string;
|
|
21
22
|
type: KofiEventType;
|
|
22
23
|
tier?: string;
|
|
24
|
+
isSubscriptionPayment?: true;
|
|
25
|
+
isFirstSubscriptionPayment?: true;
|
|
26
|
+
shopItems?: string[];
|
|
23
27
|
}
|
|
24
28
|
/**
|
|
25
29
|
* Read all event records from the PDS and aggregate into KofiSupporter objects.
|
|
@@ -28,6 +32,11 @@ export interface KofiEventRecord {
|
|
|
28
32
|
export declare function readStore(): Promise<KofiSupporter[]>;
|
|
29
33
|
/**
|
|
30
34
|
* Write a single Ko-fi event as a new record.
|
|
31
|
-
* rkey is a TID generated
|
|
35
|
+
* rkey is a TID generated from the event timestamp.
|
|
36
|
+
* Timestamp is normalised to UTC before encoding.
|
|
32
37
|
*/
|
|
33
|
-
export declare function appendEvent(name: string, type: KofiEventType, tier: string | null, timestamp: string
|
|
38
|
+
export declare function appendEvent(name: string, type: KofiEventType, tier: string | null, timestamp: string, opts?: {
|
|
39
|
+
isSubscriptionPayment?: boolean;
|
|
40
|
+
isFirstSubscriptionPayment?: boolean;
|
|
41
|
+
shopItems?: string[];
|
|
42
|
+
}): Promise<void>;
|
package/dist/store.js
CHANGED
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Required environment variables:
|
|
13
13
|
* ATPROTO_DID — your DID, e.g. did:plc:abc123
|
|
14
|
-
* ATPROTO_PDS_URL — your PDS URL, e.g. https://pds.ewancroft.uk
|
|
15
14
|
* ATPROTO_APP_PASSWORD — an app password from your PDS settings
|
|
15
|
+
*
|
|
16
|
+
* The PDS URL is resolved automatically from the DID via Slingshot.
|
|
16
17
|
*/
|
|
17
18
|
import { AtpAgent } from '@atproto/api';
|
|
18
19
|
import { generateTID } from '@ewanc26/tid';
|
|
@@ -26,11 +27,21 @@ function requireEnv(key) {
|
|
|
26
27
|
function dedupe(arr, extra) {
|
|
27
28
|
return Array.from(new Set([...arr, extra]));
|
|
28
29
|
}
|
|
30
|
+
/** Resolve the PDS URL for a DID via the AT Protocol identity endpoint. */
|
|
31
|
+
async function resolvePdsUrl(did) {
|
|
32
|
+
const res = await fetch(`https://slingshot.microcosm.blue/xrpc/com.bad-example.identity.resolveMiniDoc?identifier=${encodeURIComponent(did)}`);
|
|
33
|
+
if (!res.ok)
|
|
34
|
+
throw new Error(`Failed to resolve PDS for ${did}: ${res.status}`);
|
|
35
|
+
const data = await res.json();
|
|
36
|
+
if (!data.pds)
|
|
37
|
+
throw new Error(`No PDS found in identity document for ${did}`);
|
|
38
|
+
return data.pds;
|
|
39
|
+
}
|
|
29
40
|
/** Authenticated agent for write operations. */
|
|
30
41
|
async function authedAgent() {
|
|
31
42
|
const did = requireEnv('ATPROTO_DID');
|
|
32
|
-
const pdsUrl = requireEnv('ATPROTO_PDS_URL');
|
|
33
43
|
const password = requireEnv('ATPROTO_APP_PASSWORD');
|
|
44
|
+
const pdsUrl = await resolvePdsUrl(did);
|
|
34
45
|
const agent = new AtpAgent({ service: pdsUrl });
|
|
35
46
|
await agent.login({ identifier: did, password });
|
|
36
47
|
return { agent, did };
|
|
@@ -41,7 +52,7 @@ async function authedAgent() {
|
|
|
41
52
|
*/
|
|
42
53
|
export async function readStore() {
|
|
43
54
|
const did = requireEnv('ATPROTO_DID');
|
|
44
|
-
const pdsUrl =
|
|
55
|
+
const pdsUrl = await resolvePdsUrl(did);
|
|
45
56
|
const agent = new AtpAgent({ service: pdsUrl });
|
|
46
57
|
const events = [];
|
|
47
58
|
let cursor;
|
|
@@ -76,19 +87,25 @@ function aggregateEvents(events) {
|
|
|
76
87
|
}
|
|
77
88
|
/**
|
|
78
89
|
* Write a single Ko-fi event as a new record.
|
|
79
|
-
* rkey is a TID generated
|
|
90
|
+
* rkey is a TID generated from the event timestamp.
|
|
91
|
+
* Timestamp is normalised to UTC before encoding.
|
|
80
92
|
*/
|
|
81
|
-
export async function appendEvent(name, type, tier, timestamp) {
|
|
93
|
+
export async function appendEvent(name, type, tier, timestamp, opts) {
|
|
82
94
|
const { agent, did } = await authedAgent();
|
|
95
|
+
// Ko-fi timestamps have no timezone; normalise to UTC
|
|
96
|
+
const ts = timestamp.endsWith('Z') ? timestamp : timestamp + 'Z';
|
|
83
97
|
const record = {
|
|
84
98
|
name,
|
|
85
99
|
type,
|
|
86
|
-
...(tier ? { tier } : {})
|
|
100
|
+
...(tier ? { tier } : {}),
|
|
101
|
+
...(opts?.isSubscriptionPayment ? { isSubscriptionPayment: true } : {}),
|
|
102
|
+
...(opts?.isFirstSubscriptionPayment ? { isFirstSubscriptionPayment: true } : {}),
|
|
103
|
+
...(opts?.shopItems?.length ? { shopItems: opts.shopItems } : {})
|
|
87
104
|
};
|
|
88
105
|
await agent.com.atproto.repo.putRecord({
|
|
89
106
|
repo: did,
|
|
90
107
|
collection: COLLECTION,
|
|
91
|
-
rkey: generateTID(
|
|
108
|
+
rkey: generateTID(ts),
|
|
92
109
|
record: record
|
|
93
110
|
});
|
|
94
111
|
}
|
package/package.json
CHANGED