@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 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 at call time.
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): Promise<void>;
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 = requireEnv('ATPROTO_PDS_URL');
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 at call time.
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(timestamp),
108
+ rkey: generateTID(ts),
92
109
  record: record
93
110
  });
94
111
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ewanc26/supporters",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "SvelteKit component library for displaying Ko-fi supporters, backed by an ATProto PDS.",
5
5
  "author": "Ewan Croft",
6
6
  "license": "AGPL-3.0-only",