atmo.rsvp
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

update contrail to 0.4.2

Florian 269e69f7 7fc5e5d8

+1068 -2713
+1 -1
README.md
··· 30 30 optionally if you want all current events to be displayed run this: (will take a few minutes) 31 31 32 32 ``` 33 - pnpm run sync 33 + pnpm backfill 34 34 ``` 35 35 36 36 start dev server:
+2 -2
lex.config.js
··· 1 1 import { defineLexiconConfig } from "@atcute/lex-cli"; 2 2 3 3 export default defineLexiconConfig({ 4 - files: ["lexicons/**/*.json", "lexicons-pulled/**/*.json", "lexicons-generated/**/*.json"], 4 + files: ["lexicons/custom/**/*.json", "lexicons/pulled/**/*.json", "lexicons/generated/**/*.json"], 5 5 outdir: "src/lexicon-types/", 6 6 imports: ["@atcute/atproto"], 7 7 pull: { 8 - outdir: "lexicons-pulled/", 8 + outdir: "lexicons/pulled/", 9 9 sources: [ 10 10 { 11 11 type: "atproto",
+20 -20
lexicons-generated/rsvp/atmo/event/getRecord.json lexicons/generated/rsvp/atmo/event/getRecord.json
··· 22 22 }, 23 23 "spaceUri": { 24 24 "type": "string", 25 - "format": "at-uri", 26 - "description": "If set, fetch from this permissioned space (requires service-auth JWT or a read-grant invite token)." 25 + "description": "If set, fetch from this permissioned space (requires service-auth JWT or a read-grant invite token). `ats://` URI." 27 26 }, 28 27 "inviteToken": { 29 28 "type": "string", ··· 43 42 "type": "object", 44 43 "required": [ 45 44 "uri", 45 + "value", 46 46 "did", 47 47 "collection", 48 48 "rkey", ··· 53 53 "type": "string", 54 54 "format": "at-uri" 55 55 }, 56 + "cid": { 57 + "type": "string", 58 + "format": "cid" 59 + }, 60 + "value": { 61 + "type": "ref", 62 + "ref": "community.lexicon.calendar.event#main" 63 + }, 56 64 "did": { 57 65 "type": "string", 58 66 "format": "did" ··· 64 72 "rkey": { 65 73 "type": "string" 66 74 }, 67 - "cid": { 68 - "type": "string" 69 - }, 70 - "record": { 71 - "type": "ref", 72 - "ref": "community.lexicon.calendar.event#main" 73 - }, 74 75 "time_us": { 75 76 "type": "integer" 76 77 }, 77 78 "space": { 78 79 "type": "string", 79 - "format": "at-uri", 80 - "description": "Present when the record was read from a permissioned space; its value is the space URI." 80 + "description": "Present when the record was read from a permissioned space; its value is the `ats://` space URI." 81 81 }, 82 82 "rsvpsCount": { 83 83 "type": "integer", ··· 147 147 }, 148 148 "space": { 149 149 "type": "string", 150 - "format": "at-uri", 151 - "description": "Present when the record was read from a permissioned space." 150 + "description": "Present when the record was read from a permissioned space; `ats://` URI." 152 151 } 153 152 } 154 153 }, ··· 202 201 "type": "string", 203 202 "format": "at-uri" 204 203 }, 204 + "cid": { 205 + "type": "string", 206 + "format": "cid" 207 + }, 208 + "value": { 209 + "type": "ref", 210 + "ref": "#appBskyActorProfile" 211 + }, 205 212 "collection": { 206 213 "type": "string", 207 214 "format": "nsid" 208 215 }, 209 216 "rkey": { 210 217 "type": "string" 211 - }, 212 - "cid": { 213 - "type": "string" 214 - }, 215 - "record": { 216 - "type": "ref", 217 - "ref": "#appBskyActorProfile" 218 218 } 219 219 } 220 220 },
+38 -37
lexicons-generated/rsvp/atmo/event/listRecords.json lexicons/generated/rsvp/atmo/event/listRecords.json
··· 28 28 }, 29 29 "spaceUri": { 30 30 "type": "string", 31 - "format": "at-uri", 32 - "description": "If set, query records inside this permissioned space (requires service-auth JWT or a read-grant invite token)." 31 + "description": "If set, query records inside this permissioned space (requires service-auth JWT or a read-grant invite token). `ats://` URI." 33 32 }, 34 33 "byUser": { 35 34 "type": "string", ··· 52 51 "type": "string", 53 52 "description": "Filter by name" 54 53 }, 55 - "endsAtMin": { 54 + "status": { 56 55 "type": "string", 57 - "description": "Minimum value for endsAt" 56 + "description": "Filter by status" 58 57 }, 59 - "endsAtMax": { 58 + "description": { 60 59 "type": "string", 61 - "description": "Maximum value for endsAt" 60 + "description": "Filter by description" 62 61 }, 63 - "status": { 62 + "preferencesShowInDiscovery": { 64 63 "type": "string", 65 - "description": "Filter by status" 64 + "description": "Filter by preferences.showInDiscovery" 66 65 }, 67 66 "startsAtMin": { 68 67 "type": "string", ··· 72 71 "type": "string", 73 72 "description": "Maximum value for startsAt" 74 73 }, 75 - "createdAtMin": { 74 + "endsAtMin": { 76 75 "type": "string", 77 - "description": "Minimum value for createdAt" 76 + "description": "Minimum value for endsAt" 78 77 }, 79 - "createdAtMax": { 78 + "endsAtMax": { 80 79 "type": "string", 81 - "description": "Maximum value for createdAt" 80 + "description": "Maximum value for endsAt" 82 81 }, 83 - "description": { 82 + "createdAtMin": { 84 83 "type": "string", 85 - "description": "Filter by description" 84 + "description": "Minimum value for createdAt" 86 85 }, 87 - "preferencesShowInDiscovery": { 86 + "createdAtMax": { 88 87 "type": "string", 89 - "description": "Filter by preferences.showInDiscovery" 88 + "description": "Maximum value for createdAt" 90 89 }, 91 90 "rsvpsCountMin": { 92 91 "type": "integer", ··· 115 114 "knownValues": [ 116 115 "mode", 117 116 "name", 118 - "endsAt", 119 117 "status", 120 - "startsAt", 121 - "createdAt", 122 118 "description", 123 119 "preferencesShowInDiscovery", 120 + "startsAt", 121 + "endsAt", 122 + "createdAt", 124 123 "rsvpsCount", 125 124 "rsvpsInterestedCount", 126 125 "rsvpsGoingCount", ··· 171 170 "type": "object", 172 171 "required": [ 173 172 "uri", 173 + "cid", 174 + "value", 174 175 "did", 175 176 "collection", 176 177 "rkey", ··· 181 182 "type": "string", 182 183 "format": "at-uri" 183 184 }, 185 + "cid": { 186 + "type": "string", 187 + "format": "cid" 188 + }, 189 + "value": { 190 + "type": "ref", 191 + "ref": "community.lexicon.calendar.event#main" 192 + }, 184 193 "did": { 185 194 "type": "string", 186 195 "format": "did" ··· 192 201 "rkey": { 193 202 "type": "string" 194 203 }, 195 - "cid": { 196 - "type": "string" 197 - }, 198 - "record": { 199 - "type": "ref", 200 - "ref": "community.lexicon.calendar.event#main" 201 - }, 202 204 "time_us": { 203 205 "type": "integer" 204 206 }, 205 207 "space": { 206 208 "type": "string", 207 - "format": "at-uri", 208 - "description": "Present when the record was read from a permissioned space; its value is the space URI." 209 + "description": "Present when the record was read from a permissioned space; its value is the `ats://` space URI." 209 210 }, 210 211 "rsvpsCount": { 211 212 "type": "integer", ··· 266 267 }, 267 268 "space": { 268 269 "type": "string", 269 - "format": "at-uri", 270 - "description": "Present when the record was read from a permissioned space." 270 + "description": "Present when the record was read from a permissioned space; `ats://` URI." 271 271 } 272 272 } 273 273 }, ··· 321 321 "type": "string", 322 322 "format": "at-uri" 323 323 }, 324 + "cid": { 325 + "type": "string", 326 + "format": "cid" 327 + }, 328 + "value": { 329 + "type": "ref", 330 + "ref": "#appBskyActorProfile" 331 + }, 324 332 "collection": { 325 333 "type": "string", 326 334 "format": "nsid" 327 335 }, 328 336 "rkey": { 329 337 "type": "string" 330 - }, 331 - "cid": { 332 - "type": "string" 333 - }, 334 - "record": { 335 - "type": "ref", 336 - "ref": "#appBskyActorProfile" 337 338 } 338 339 } 339 340 },
lexicons-generated/rsvp/atmo/getCursor.json lexicons/generated/rsvp/atmo/getCursor.json
lexicons-generated/rsvp/atmo/getOverview.json lexicons/generated/rsvp/atmo/getOverview.json
+8 -7
lexicons-generated/rsvp/atmo/getProfile.json lexicons/generated/rsvp/atmo/getProfile.json
··· 54 54 "type": "string", 55 55 "format": "at-uri" 56 56 }, 57 + "cid": { 58 + "type": "string", 59 + "format": "cid" 60 + }, 61 + "value": { 62 + "type": "ref", 63 + "ref": "#appBskyActorProfile" 64 + }, 57 65 "collection": { 58 66 "type": "string", 59 67 "format": "nsid" 60 68 }, 61 69 "rkey": { 62 70 "type": "string" 63 - }, 64 - "cid": { 65 - "type": "string" 66 - }, 67 - "record": { 68 - "type": "ref", 69 - "ref": "#appBskyActorProfile" 70 71 } 71 72 } 72 73 },
lexicons-generated/rsvp/atmo/notifyOfUpdate.json lexicons/generated/rsvp/atmo/notifyOfUpdate.json
+9 -6
lexicons-generated/rsvp/atmo/permissionSet.json lexicons/generated/rsvp/atmo/authFull.json
··· 1 1 { 2 2 "lexicon": 1, 3 - "id": "rsvp.atmo.permissionSet", 3 + "id": "rsvp.atmo.authFull", 4 4 "defs": { 5 5 "main": { 6 6 "type": "permission-set", ··· 17 17 "rsvp.atmo.getCursor", 18 18 "rsvp.atmo.getOverview", 19 19 "rsvp.atmo.getProfile", 20 + "rsvp.atmo.invite.create", 21 + "rsvp.atmo.invite.list", 22 + "rsvp.atmo.invite.redeem", 23 + "rsvp.atmo.invite.revoke", 20 24 "rsvp.atmo.notifyOfUpdate", 21 25 "rsvp.atmo.rsvp.getRecord", 22 26 "rsvp.atmo.rsvp.listRecords", 23 27 "rsvp.atmo.space.addMember", 24 28 "rsvp.atmo.space.createSpace", 25 29 "rsvp.atmo.space.deleteRecord", 30 + "rsvp.atmo.space.getBlob", 26 31 "rsvp.atmo.space.getRecord", 27 32 "rsvp.atmo.space.getSpace", 28 - "rsvp.atmo.space.invite.create", 29 - "rsvp.atmo.space.invite.list", 30 - "rsvp.atmo.space.invite.redeem", 31 - "rsvp.atmo.space.invite.revoke", 32 33 "rsvp.atmo.space.leaveSpace", 34 + "rsvp.atmo.space.listBlobs", 33 35 "rsvp.atmo.space.listMembers", 34 36 "rsvp.atmo.space.listRecords", 35 37 "rsvp.atmo.space.listSpaces", 36 38 "rsvp.atmo.space.putRecord", 37 39 "rsvp.atmo.space.removeMember", 38 - "rsvp.atmo.space.whoami" 40 + "rsvp.atmo.space.uploadBlob", 41 + "rsvp.atmo.spaceExt.whoami" 39 42 ] 40 43 } 41 44 ]
+20 -20
lexicons-generated/rsvp/atmo/rsvp/getRecord.json lexicons/generated/rsvp/atmo/rsvp/getRecord.json
··· 22 22 }, 23 23 "spaceUri": { 24 24 "type": "string", 25 - "format": "at-uri", 26 - "description": "If set, fetch from this permissioned space (requires service-auth JWT or a read-grant invite token)." 25 + "description": "If set, fetch from this permissioned space (requires service-auth JWT or a read-grant invite token). `ats://` URI." 27 26 }, 28 27 "inviteToken": { 29 28 "type": "string", ··· 41 40 "type": "object", 42 41 "required": [ 43 42 "uri", 43 + "value", 44 44 "did", 45 45 "collection", 46 46 "rkey", ··· 51 51 "type": "string", 52 52 "format": "at-uri" 53 53 }, 54 + "cid": { 55 + "type": "string", 56 + "format": "cid" 57 + }, 58 + "value": { 59 + "type": "ref", 60 + "ref": "community.lexicon.calendar.rsvp#main" 61 + }, 54 62 "did": { 55 63 "type": "string", 56 64 "format": "did" ··· 62 70 "rkey": { 63 71 "type": "string" 64 72 }, 65 - "cid": { 66 - "type": "string" 67 - }, 68 - "record": { 69 - "type": "ref", 70 - "ref": "community.lexicon.calendar.rsvp#main" 71 - }, 72 73 "time_us": { 73 74 "type": "integer" 74 75 }, 75 76 "space": { 76 77 "type": "string", 77 - "format": "at-uri", 78 - "description": "Present when the record was read from a permissioned space; its value is the space URI." 78 + "description": "Present when the record was read from a permissioned space; its value is the `ats://` space URI." 79 79 }, 80 80 "event": { 81 81 "type": "ref", ··· 129 129 }, 130 130 "space": { 131 131 "type": "string", 132 - "format": "at-uri", 133 - "description": "Present when the record was read from a permissioned space." 132 + "description": "Present when the record was read from a permissioned space; `ats://` URI." 134 133 } 135 134 } 136 135 }, ··· 151 150 "type": "string", 152 151 "format": "at-uri" 153 152 }, 153 + "cid": { 154 + "type": "string", 155 + "format": "cid" 156 + }, 157 + "value": { 158 + "type": "ref", 159 + "ref": "#appBskyActorProfile" 160 + }, 154 161 "collection": { 155 162 "type": "string", 156 163 "format": "nsid" 157 164 }, 158 165 "rkey": { 159 166 "type": "string" 160 - }, 161 - "cid": { 162 - "type": "string" 163 - }, 164 - "record": { 165 - "type": "ref", 166 - "ref": "#appBskyActorProfile" 167 167 } 168 168 } 169 169 },
+31 -21
lexicons-generated/rsvp/atmo/rsvp/listRecords.json lexicons/generated/rsvp/atmo/rsvp/listRecords.json
··· 28 28 }, 29 29 "spaceUri": { 30 30 "type": "string", 31 - "format": "at-uri", 32 - "description": "If set, query records inside this permissioned space (requires service-auth JWT or a read-grant invite token)." 31 + "description": "If set, query records inside this permissioned space (requires service-auth JWT or a read-grant invite token). `ats://` URI." 33 32 }, 34 33 "byUser": { 35 34 "type": "string", ··· 48 47 "type": "string", 49 48 "description": "Filter by subject.uri" 50 49 }, 50 + "createdAtMin": { 51 + "type": "string", 52 + "description": "Minimum value for createdAt" 53 + }, 54 + "createdAtMax": { 55 + "type": "string", 56 + "description": "Maximum value for createdAt" 57 + }, 51 58 "hydrateEvent": { 52 59 "type": "boolean", 53 60 "description": "Embed the referenced event record" ··· 56 63 "type": "string", 57 64 "knownValues": [ 58 65 "status", 59 - "subjectUri" 66 + "subjectUri", 67 + "createdAt" 60 68 ], 61 69 "description": "Field to sort by (default: time_us)" 62 70 }, ··· 103 111 "type": "object", 104 112 "required": [ 105 113 "uri", 114 + "cid", 115 + "value", 106 116 "did", 107 117 "collection", 108 118 "rkey", ··· 113 123 "type": "string", 114 124 "format": "at-uri" 115 125 }, 126 + "cid": { 127 + "type": "string", 128 + "format": "cid" 129 + }, 130 + "value": { 131 + "type": "ref", 132 + "ref": "community.lexicon.calendar.rsvp#main" 133 + }, 116 134 "did": { 117 135 "type": "string", 118 136 "format": "did" ··· 124 142 "rkey": { 125 143 "type": "string" 126 144 }, 127 - "cid": { 128 - "type": "string" 129 - }, 130 - "record": { 131 - "type": "ref", 132 - "ref": "community.lexicon.calendar.rsvp#main" 133 - }, 134 145 "time_us": { 135 146 "type": "integer" 136 147 }, 137 148 "space": { 138 149 "type": "string", 139 - "format": "at-uri", 140 - "description": "Present when the record was read from a permissioned space; its value is the space URI." 150 + "description": "Present when the record was read from a permissioned space; its value is the `ats://` space URI." 141 151 }, 142 152 "event": { 143 153 "type": "ref", ··· 182 192 }, 183 193 "space": { 184 194 "type": "string", 185 - "format": "at-uri", 186 - "description": "Present when the record was read from a permissioned space." 195 + "description": "Present when the record was read from a permissioned space; `ats://` URI." 187 196 } 188 197 } 189 198 }, ··· 204 213 "type": "string", 205 214 "format": "at-uri" 206 215 }, 216 + "cid": { 217 + "type": "string", 218 + "format": "cid" 219 + }, 220 + "value": { 221 + "type": "ref", 222 + "ref": "#appBskyActorProfile" 223 + }, 207 224 "collection": { 208 225 "type": "string", 209 226 "format": "nsid" 210 227 }, 211 228 "rkey": { 212 229 "type": "string" 213 - }, 214 - "cid": { 215 - "type": "string" 216 - }, 217 - "record": { 218 - "type": "ref", 219 - "ref": "#appBskyActorProfile" 220 230 } 221 231 } 222 232 },
+1 -10
lexicons-generated/rsvp/atmo/space/addMember.json lexicons/generated/rsvp/atmo/space/addMember.json
··· 15 15 ], 16 16 "properties": { 17 17 "spaceUri": { 18 - "type": "string", 19 - "format": "at-uri" 18 + "type": "string" 20 19 }, 21 20 "did": { 22 21 "type": "string", 23 22 "format": "did" 24 - }, 25 - "perms": { 26 - "type": "string", 27 - "knownValues": [ 28 - "read", 29 - "write" 30 - ], 31 - "default": "write" 32 23 } 33 24 } 34 25 }
-4
lexicons-generated/rsvp/atmo/space/createSpace.json lexicons/generated/rsvp/atmo/space/createSpace.json
··· 19 19 "type": "string", 20 20 "description": "Space key. Auto-generated (TID) if omitted." 21 21 }, 22 - "memberListRef": { 23 - "type": "string", 24 - "format": "at-uri" 25 - }, 26 22 "appPolicyRef": { 27 23 "type": "string", 28 24 "format": "at-uri"
+32 -27
lexicons-generated/rsvp/atmo/space/defs.json lexicons/generated/rsvp/atmo/space/defs.json
··· 15 15 ], 16 16 "properties": { 17 17 "uri": { 18 - "type": "string", 19 - "format": "at-uri" 18 + "type": "string" 20 19 }, 21 20 "ownerDid": { 22 21 "type": "string", ··· 32 31 "serviceDid": { 33 32 "type": "string" 34 33 }, 35 - "memberListRef": { 36 - "type": "string", 37 - "format": "at-uri" 38 - }, 39 34 "appPolicyRef": { 40 35 "type": "string", 41 36 "format": "at-uri" ··· 54 49 "type": "object", 55 50 "required": [ 56 51 "did", 57 - "perms", 58 52 "addedAt" 59 53 ], 60 54 "properties": { ··· 62 56 "type": "string", 63 57 "format": "did" 64 58 }, 65 - "perms": { 66 - "type": "string", 67 - "knownValues": [ 68 - "read", 69 - "write" 70 - ], 71 - "description": "'write' implies 'read'. Space owner is always implicit write." 72 - }, 73 59 "addedAt": { 74 60 "type": "integer" 75 61 }, ··· 91 77 ], 92 78 "properties": { 93 79 "spaceUri": { 94 - "type": "string", 95 - "format": "at-uri" 80 + "type": "string" 96 81 }, 97 82 "collection": { 98 83 "type": "string", ··· 140 125 } 141 126 } 142 127 }, 128 + "blobInfo": { 129 + "type": "object", 130 + "required": [ 131 + "cid", 132 + "mimeType", 133 + "size", 134 + "authorDid", 135 + "createdAt" 136 + ], 137 + "properties": { 138 + "cid": { 139 + "type": "string", 140 + "format": "cid" 141 + }, 142 + "mimeType": { 143 + "type": "string" 144 + }, 145 + "size": { 146 + "type": "integer" 147 + }, 148 + "authorDid": { 149 + "type": "string", 150 + "format": "did" 151 + }, 152 + "createdAt": { 153 + "type": "integer" 154 + } 155 + } 156 + }, 143 157 "inviteView": { 144 158 "type": "object", 145 159 "required": [ 146 160 "tokenHash", 147 161 "spaceUri", 148 162 "kind", 149 - "perms", 150 163 "usedCount", 151 164 "createdBy", 152 165 "createdAt" ··· 156 169 "type": "string" 157 170 }, 158 171 "spaceUri": { 159 - "type": "string", 160 - "format": "at-uri" 172 + "type": "string" 161 173 }, 162 174 "kind": { 163 175 "type": "string", ··· 165 177 "join", 166 178 "read", 167 179 "read-join" 168 - ] 169 - }, 170 - "perms": { 171 - "type": "string", 172 - "knownValues": [ 173 - "read", 174 - "write" 175 180 ] 176 181 }, 177 182 "expiresAt": {
+1 -2
lexicons-generated/rsvp/atmo/space/deleteRecord.json lexicons/generated/rsvp/atmo/space/deleteRecord.json
··· 16 16 ], 17 17 "properties": { 18 18 "spaceUri": { 19 - "type": "string", 20 - "format": "at-uri" 19 + "type": "string" 21 20 }, 22 21 "collection": { 23 22 "type": "string",
+1 -2
lexicons-generated/rsvp/atmo/space/getRecord.json lexicons/generated/rsvp/atmo/space/getRecord.json
··· 15 15 ], 16 16 "properties": { 17 17 "spaceUri": { 18 - "type": "string", 19 - "format": "at-uri" 18 + "type": "string" 20 19 }, 21 20 "collection": { 22 21 "type": "string",
+1 -2
lexicons-generated/rsvp/atmo/space/getSpace.json lexicons/generated/rsvp/atmo/space/getSpace.json
··· 12 12 ], 13 13 "properties": { 14 14 "uri": { 15 - "type": "string", 16 - "format": "at-uri" 15 + "type": "string" 17 16 }, 18 17 "inviteToken": { 19 18 "type": "string",
+15 -13
lexicons-generated/rsvp/atmo/space/invite/create.json lexicons/generated/rsvp/atmo/invite/create.json
··· 1 1 { 2 2 "lexicon": 1, 3 - "id": "rsvp.atmo.space.invite.create", 3 + "id": "rsvp.atmo.invite.create", 4 4 "defs": { 5 5 "main": { 6 6 "type": "procedure", 7 - "description": "Create an invite for a space. Caller must be the space owner. Returns the raw token once; only the hash is stored.", 7 + "description": "Create an invite for a space. The service dispatches on space ownership: user-owned spaces take `kind` (default `join`); community-owned spaces take `accessLevel`. Exactly one of `kind` / `accessLevel` must be set. Returns the raw token once; only the hash is stored.", 8 8 "input": { 9 9 "encoding": "application/json", 10 10 "schema": { ··· 14 14 ], 15 15 "properties": { 16 16 "spaceUri": { 17 - "type": "string", 18 - "format": "at-uri" 17 + "type": "string" 19 18 }, 20 19 "kind": { 21 20 "type": "string", ··· 24 23 "read", 25 24 "read-join" 26 25 ], 27 - "default": "join", 28 - "description": "join: redeem to become a member. read: bearer-only read access, no membership. read-join: anonymous read + signed-in redeem to join." 26 + "description": "For user-owned spaces. join: redeem to become a member. read: bearer-only read access, no membership. read-join: anonymous read + signed-in redeem to join." 29 27 }, 30 - "perms": { 28 + "accessLevel": { 31 29 "type": "string", 32 30 "knownValues": [ 33 - "read", 34 - "write" 31 + "member", 32 + "manager", 33 + "admin", 34 + "owner" 35 35 ], 36 - "default": "write" 36 + "description": "For community-owned spaces. The access level granted on redemption — the creator's own level caps what they can grant." 37 37 }, 38 38 "expiresAt": { 39 39 "type": "integer", ··· 41 41 }, 42 42 "maxUses": { 43 43 "type": "integer", 44 - "minimum": 1, 45 - "description": "Caps join redemptions only — read-token reads are unlimited. Omit for unlimited joins." 44 + "minimum": 1 46 45 }, 47 46 "note": { 48 47 "type": "string", ··· 66 65 }, 67 66 "invite": { 68 67 "type": "ref", 69 - "ref": "rsvp.atmo.space.defs#inviteView" 68 + "ref": "rsvp.atmo.invite.defs#inviteView" 70 69 } 71 70 } 72 71 } ··· 77 76 }, 78 77 { 79 78 "name": "Forbidden" 79 + }, 80 + { 81 + "name": "InvalidRequest" 80 82 } 81 83 ] 82 84 }
+4 -5
lexicons-generated/rsvp/atmo/space/invite/list.json lexicons/generated/rsvp/atmo/invite/list.json
··· 1 1 { 2 2 "lexicon": 1, 3 - "id": "rsvp.atmo.space.invite.list", 3 + "id": "rsvp.atmo.invite.list", 4 4 "defs": { 5 5 "main": { 6 6 "type": "query", 7 - "description": "List invites for a space. Owner only.", 7 + "description": "List invites for a space. User-owned spaces: owner-only. Community-owned spaces: manager+.", 8 8 "parameters": { 9 9 "type": "params", 10 10 "required": [ ··· 12 12 ], 13 13 "properties": { 14 14 "spaceUri": { 15 - "type": "string", 16 - "format": "at-uri" 15 + "type": "string" 17 16 }, 18 17 "includeRevoked": { 19 18 "type": "boolean", ··· 33 32 "type": "array", 34 33 "items": { 35 34 "type": "ref", 36 - "ref": "rsvp.atmo.space.defs#inviteView" 35 + "ref": "rsvp.atmo.invite.defs#inviteView" 37 36 } 38 37 } 39 38 }
-52
lexicons-generated/rsvp/atmo/space/invite/redeem.json
··· 1 - { 2 - "lexicon": 1, 3 - "id": "rsvp.atmo.space.invite.redeem", 4 - "defs": { 5 - "main": { 6 - "type": "procedure", 7 - "description": "Redeem an invite token. The JWT issuer becomes a member of the space with the invite's perms.", 8 - "input": { 9 - "encoding": "application/json", 10 - "schema": { 11 - "type": "object", 12 - "required": [ 13 - "token" 14 - ], 15 - "properties": { 16 - "token": { 17 - "type": "string" 18 - } 19 - } 20 - } 21 - }, 22 - "output": { 23 - "encoding": "application/json", 24 - "schema": { 25 - "type": "object", 26 - "required": [ 27 - "spaceUri", 28 - "perms" 29 - ], 30 - "properties": { 31 - "spaceUri": { 32 - "type": "string", 33 - "format": "at-uri" 34 - }, 35 - "perms": { 36 - "type": "string", 37 - "knownValues": [ 38 - "read", 39 - "write" 40 - ] 41 - } 42 - } 43 - } 44 - }, 45 - "errors": [ 46 - { 47 - "name": "InvalidInvite" 48 - } 49 - ] 50 - } 51 - } 52 - }
+3 -4
lexicons-generated/rsvp/atmo/space/invite/revoke.json lexicons/generated/rsvp/atmo/invite/revoke.json
··· 1 1 { 2 2 "lexicon": 1, 3 - "id": "rsvp.atmo.space.invite.revoke", 3 + "id": "rsvp.atmo.invite.revoke", 4 4 "defs": { 5 5 "main": { 6 6 "type": "procedure", 7 - "description": "Revoke an invite. Owner only. Invites are identified by their tokenHash (visible in list output).", 7 + "description": "Revoke an invite by tokenHash. User-owned spaces: owner-only. Community-owned spaces: invite creator OR manager+ on the target space.", 8 8 "input": { 9 9 "encoding": "application/json", 10 10 "schema": { 11 11 "type": "object", 12 12 "required": [ 13 - "spaceUri", 14 13 "tokenHash" 15 14 ], 16 15 "properties": { 17 16 "spaceUri": { 18 17 "type": "string", 19 - "format": "at-uri" 18 + "description": "Optional — ownership is inferred from the invite row; required for user-owned spaces for a sanity check." 20 19 }, 21 20 "tokenHash": { 22 21 "type": "string"
+1 -2
lexicons-generated/rsvp/atmo/space/leaveSpace.json lexicons/generated/rsvp/atmo/space/leaveSpace.json
··· 14 14 ], 15 15 "properties": { 16 16 "spaceUri": { 17 - "type": "string", 18 - "format": "at-uri" 17 + "type": "string" 19 18 } 20 19 } 21 20 }
+1 -2
lexicons-generated/rsvp/atmo/space/listMembers.json lexicons/generated/rsvp/atmo/space/listMembers.json
··· 12 12 ], 13 13 "properties": { 14 14 "spaceUri": { 15 - "type": "string", 16 - "format": "at-uri" 15 + "type": "string" 17 16 } 18 17 } 19 18 },
+1 -2
lexicons-generated/rsvp/atmo/space/listRecords.json lexicons/generated/rsvp/atmo/space/listRecords.json
··· 13 13 ], 14 14 "properties": { 15 15 "spaceUri": { 16 - "type": "string", 17 - "format": "at-uri" 16 + "type": "string" 18 17 }, 19 18 "collection": { 20 19 "type": "string",
+6 -1
lexicons-generated/rsvp/atmo/space/listSpaces.json lexicons/generated/rsvp/atmo/space/listSpaces.json
··· 4 4 "defs": { 5 5 "main": { 6 6 "type": "query", 7 - "description": "List spaces the caller has access to. Default scope is 'member' (spaces the caller is a member of, including owned); 'owner' lists only spaces the caller owns.", 7 + "description": "List spaces the caller has access to. Default scope is 'member' (spaces the caller is a member of, including owned); 'owner' lists only spaces the caller owns. When scope='member', the optional 'owner' param narrows to spaces owned by that DID — useful for listing all channels in a specific community the caller can access.", 8 8 "parameters": { 9 9 "type": "params", 10 10 "properties": { ··· 19 19 "type": { 20 20 "type": "string", 21 21 "format": "nsid" 22 + }, 23 + "owner": { 24 + "type": "string", 25 + "format": "did", 26 + "description": "With scope=member, filter to spaces owned by this DID. Ignored when scope=owner." 22 27 }, 23 28 "cursor": { 24 29 "type": "string"
+1 -2
lexicons-generated/rsvp/atmo/space/putRecord.json lexicons/generated/rsvp/atmo/space/putRecord.json
··· 16 16 ], 17 17 "properties": { 18 18 "spaceUri": { 19 - "type": "string", 20 - "format": "at-uri" 19 + "type": "string" 21 20 }, 22 21 "collection": { 23 22 "type": "string",
+1 -2
lexicons-generated/rsvp/atmo/space/removeMember.json lexicons/generated/rsvp/atmo/space/removeMember.json
··· 15 15 ], 16 16 "properties": { 17 17 "spaceUri": { 18 - "type": "string", 19 - "format": "at-uri" 18 + "type": "string" 20 19 }, 21 20 "did": { 22 21 "type": "string",
-53
lexicons-generated/rsvp/atmo/space/whoami.json
··· 1 - { 2 - "lexicon": 1, 3 - "id": "rsvp.atmo.space.whoami", 4 - "defs": { 5 - "main": { 6 - "type": "query", 7 - "description": "Report the caller's relationship to a space: whether they are the owner, a member, and at what permission level. Useful for clients to avoid a listMembers roundtrip.", 8 - "parameters": { 9 - "type": "params", 10 - "required": [ 11 - "spaceUri" 12 - ], 13 - "properties": { 14 - "spaceUri": { 15 - "type": "string", 16 - "format": "at-uri" 17 - } 18 - } 19 - }, 20 - "output": { 21 - "encoding": "application/json", 22 - "schema": { 23 - "type": "object", 24 - "required": [ 25 - "isOwner", 26 - "isMember" 27 - ], 28 - "properties": { 29 - "isOwner": { 30 - "type": "boolean" 31 - }, 32 - "isMember": { 33 - "type": "boolean" 34 - }, 35 - "perms": { 36 - "type": "string", 37 - "knownValues": [ 38 - "read", 39 - "write" 40 - ], 41 - "description": "Present only when the caller is a member or the owner." 42 - } 43 - } 44 - } 45 - }, 46 - "errors": [ 47 - { 48 - "name": "NotFound" 49 - } 50 - ] 51 - } 52 - } 53 - }
lexicons-pulled/README.md lexicons/pulled/README.md
lexicons-pulled/app/bsky/actor/profile.json lexicons/pulled/app/bsky/actor/profile.json
lexicons-pulled/community/lexicon/calendar/event.json lexicons/pulled/community/lexicon/calendar/event.json
lexicons-pulled/community/lexicon/calendar/rsvp.json lexicons/pulled/community/lexicon/calendar/rsvp.json
lexicons-pulled/community/lexicon/location/address.json lexicons/pulled/community/lexicon/location/address.json
lexicons-pulled/community/lexicon/location/fsq.json lexicons/pulled/community/lexicon/location/fsq.json
lexicons-pulled/community/lexicon/location/geo.json lexicons/pulled/community/lexicon/location/geo.json
lexicons-pulled/community/lexicon/location/hthree.json lexicons/pulled/community/lexicon/location/hthree.json
+43
lexicons/generated/index.ts
··· 1 + // Auto-generated by @atmo-dev/contrail-lexicons. Do not edit. 2 + // Pass `lexicons` to `createWorker(config, { lexicons })` to expose them 3 + // at `/xrpc/<namespace>.lexicons` for consumer apps to typegen against. 4 + 5 + import _0 from "../pulled/app/bsky/actor/profile.json"; 6 + import _1 from "../pulled/community/lexicon/calendar/event.json"; 7 + import _2 from "../pulled/community/lexicon/calendar/rsvp.json"; 8 + import _3 from "../pulled/community/lexicon/location/address.json"; 9 + import _4 from "../pulled/community/lexicon/location/fsq.json"; 10 + import _5 from "../pulled/community/lexicon/location/geo.json"; 11 + import _6 from "../pulled/community/lexicon/location/hthree.json"; 12 + import _7 from "./rsvp/atmo/authFull.json"; 13 + import _8 from "./rsvp/atmo/event/getRecord.json"; 14 + import _9 from "./rsvp/atmo/event/listRecords.json"; 15 + import _10 from "./rsvp/atmo/getCursor.json"; 16 + import _11 from "./rsvp/atmo/getOverview.json"; 17 + import _12 from "./rsvp/atmo/getProfile.json"; 18 + import _13 from "./rsvp/atmo/invite/create.json"; 19 + import _14 from "./rsvp/atmo/invite/defs.json"; 20 + import _15 from "./rsvp/atmo/invite/list.json"; 21 + import _16 from "./rsvp/atmo/invite/redeem.json"; 22 + import _17 from "./rsvp/atmo/invite/revoke.json"; 23 + import _18 from "./rsvp/atmo/notifyOfUpdate.json"; 24 + import _19 from "./rsvp/atmo/rsvp/getRecord.json"; 25 + import _20 from "./rsvp/atmo/rsvp/listRecords.json"; 26 + import _21 from "./rsvp/atmo/space/addMember.json"; 27 + import _22 from "./rsvp/atmo/space/createSpace.json"; 28 + import _23 from "./rsvp/atmo/space/defs.json"; 29 + import _24 from "./rsvp/atmo/space/deleteRecord.json"; 30 + import _25 from "./rsvp/atmo/space/getBlob.json"; 31 + import _26 from "./rsvp/atmo/space/getRecord.json"; 32 + import _27 from "./rsvp/atmo/space/getSpace.json"; 33 + import _28 from "./rsvp/atmo/space/leaveSpace.json"; 34 + import _29 from "./rsvp/atmo/space/listBlobs.json"; 35 + import _30 from "./rsvp/atmo/space/listMembers.json"; 36 + import _31 from "./rsvp/atmo/space/listRecords.json"; 37 + import _32 from "./rsvp/atmo/space/listSpaces.json"; 38 + import _33 from "./rsvp/atmo/space/putRecord.json"; 39 + import _34 from "./rsvp/atmo/space/removeMember.json"; 40 + import _35 from "./rsvp/atmo/space/uploadBlob.json"; 41 + import _36 from "./rsvp/atmo/spaceExt/whoami.json"; 42 + 43 + export const lexicons: object[] = [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36];
+72
lexicons/generated/rsvp/atmo/invite/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "rsvp.atmo.invite.defs", 4 + "defs": { 5 + "inviteView": { 6 + "type": "object", 7 + "description": "An invite row as exposed to clients. Either `kind` (user-owned space) or `accessLevel` (community-owned space) is set, never both.", 8 + "required": [ 9 + "tokenHash", 10 + "spaceUri", 11 + "createdBy", 12 + "createdAt", 13 + "usedCount" 14 + ], 15 + "properties": { 16 + "tokenHash": { 17 + "type": "string", 18 + "description": "Stable identifier for list/revoke operations." 19 + }, 20 + "spaceUri": { 21 + "type": "string" 22 + }, 23 + "kind": { 24 + "type": "string", 25 + "knownValues": [ 26 + "join", 27 + "read", 28 + "read-join" 29 + ], 30 + "description": "Set for user-owned spaces. Absent for community-owned." 31 + }, 32 + "accessLevel": { 33 + "type": "string", 34 + "knownValues": [ 35 + "member", 36 + "manager", 37 + "admin", 38 + "owner" 39 + ], 40 + "description": "Set for community-owned spaces. Absent for user-owned." 41 + }, 42 + "createdBy": { 43 + "type": "string", 44 + "format": "did" 45 + }, 46 + "createdAt": { 47 + "type": "integer", 48 + "description": "Unix ms." 49 + }, 50 + "expiresAt": { 51 + "type": "integer", 52 + "description": "Unix ms. Omitted for no expiry." 53 + }, 54 + "maxUses": { 55 + "type": "integer", 56 + "minimum": 1 57 + }, 58 + "usedCount": { 59 + "type": "integer" 60 + }, 61 + "revokedAt": { 62 + "type": "integer", 63 + "description": "Unix ms. Omitted if not revoked." 64 + }, 65 + "note": { 66 + "type": "string", 67 + "maxLength": 500 68 + } 69 + } 70 + } 71 + } 72 + }
+59
lexicons/generated/rsvp/atmo/invite/redeem.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "rsvp.atmo.invite.redeem", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Redeem an invite token. User-owned spaces: caller becomes a member. Community-owned spaces: caller is granted the invite's access level.", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": [ 13 + "token" 14 + ], 15 + "properties": { 16 + "token": { 17 + "type": "string" 18 + } 19 + } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "required": [ 27 + "spaceUri" 28 + ], 29 + "properties": { 30 + "spaceUri": { 31 + "type": "string" 32 + }, 33 + "kind": { 34 + "type": "string", 35 + "description": "Set for user-owned spaces — echoes the invite kind consumed." 36 + }, 37 + "accessLevel": { 38 + "type": "string", 39 + "description": "Set for community-owned spaces — the level granted." 40 + }, 41 + "communityDid": { 42 + "type": "string", 43 + "format": "did", 44 + "description": "Set for community-owned spaces." 45 + } 46 + } 47 + } 48 + }, 49 + "errors": [ 50 + { 51 + "name": "InvalidInvite" 52 + }, 53 + { 54 + "name": "NotFound" 55 + } 56 + ] 57 + } 58 + } 59 + }
+41
lexicons/generated/rsvp/atmo/space/getBlob.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "rsvp.atmo.space.getBlob", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Read a blob from a space. Requires read access via a service-auth JWT or a read-grant invite token.", 8 + "parameters": { 9 + "type": "params", 10 + "required": [ 11 + "spaceUri", 12 + "cid" 13 + ], 14 + "properties": { 15 + "spaceUri": { 16 + "type": "string" 17 + }, 18 + "cid": { 19 + "type": "string", 20 + "format": "cid" 21 + }, 22 + "inviteToken": { 23 + "type": "string", 24 + "description": "Read-grant invite token for anonymous bearer access." 25 + } 26 + } 27 + }, 28 + "output": { 29 + "encoding": "*/*" 30 + }, 31 + "errors": [ 32 + { 33 + "name": "NotFound" 34 + }, 35 + { 36 + "name": "Forbidden" 37 + } 38 + ] 39 + } 40 + } 41 + }
+56
lexicons/generated/rsvp/atmo/space/listBlobs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "rsvp.atmo.space.listBlobs", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "List blob metadata for a space. Members only.", 8 + "parameters": { 9 + "type": "params", 10 + "required": [ 11 + "spaceUri" 12 + ], 13 + "properties": { 14 + "spaceUri": { 15 + "type": "string" 16 + }, 17 + "byUser": { 18 + "type": "string", 19 + "format": "did", 20 + "description": "Only blobs uploaded by this DID." 21 + }, 22 + "limit": { 23 + "type": "integer", 24 + "minimum": 1, 25 + "maximum": 200, 26 + "default": 50 27 + }, 28 + "cursor": { 29 + "type": "string" 30 + } 31 + } 32 + }, 33 + "output": { 34 + "encoding": "application/json", 35 + "schema": { 36 + "type": "object", 37 + "required": [ 38 + "blobs" 39 + ], 40 + "properties": { 41 + "blobs": { 42 + "type": "array", 43 + "items": { 44 + "type": "ref", 45 + "ref": "rsvp.atmo.space.defs#blobInfo" 46 + } 47 + }, 48 + "cursor": { 49 + "type": "string" 50 + } 51 + } 52 + } 53 + } 54 + } 55 + } 56 + }
+49
lexicons/generated/rsvp/atmo/space/uploadBlob.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "rsvp.atmo.space.uploadBlob", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Upload a blob into a space. Returns a standard atproto BlobRef that records in this space can then reference. The record will be rejected at putRecord time if it references a blob that was not uploaded to the same space.", 8 + "parameters": { 9 + "type": "params", 10 + "required": [ 11 + "spaceUri" 12 + ], 13 + "properties": { 14 + "spaceUri": { 15 + "type": "string" 16 + } 17 + } 18 + }, 19 + "input": { 20 + "encoding": "*/*" 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "required": [ 27 + "blob" 28 + ], 29 + "properties": { 30 + "blob": { 31 + "type": "blob" 32 + } 33 + } 34 + } 35 + }, 36 + "errors": [ 37 + { 38 + "name": "Forbidden" 39 + }, 40 + { 41 + "name": "BlobTooLarge" 42 + }, 43 + { 44 + "name": "InvalidMimeType" 45 + } 46 + ] 47 + } 48 + } 49 + }
+54
lexicons/generated/rsvp/atmo/spaceExt/whoami.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "rsvp.atmo.spaceExt.whoami", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Caller's relationship to a space. For user-owned spaces membership is binary (`isMember`). For community-owned spaces `accessLevel` is also returned, resolved through the community's access-level ladder (including delegated grants).", 8 + "parameters": { 9 + "type": "params", 10 + "required": [ 11 + "spaceUri" 12 + ], 13 + "properties": { 14 + "spaceUri": { 15 + "type": "string" 16 + } 17 + } 18 + }, 19 + "output": { 20 + "encoding": "application/json", 21 + "schema": { 22 + "type": "object", 23 + "required": [ 24 + "isOwner", 25 + "isMember" 26 + ], 27 + "properties": { 28 + "isOwner": { 29 + "type": "boolean" 30 + }, 31 + "isMember": { 32 + "type": "boolean" 33 + }, 34 + "accessLevel": { 35 + "type": "string", 36 + "knownValues": [ 37 + "member", 38 + "manager", 39 + "admin", 40 + "owner" 41 + ], 42 + "description": "Only set for community-owned spaces. Null when the caller has no resolvable access." 43 + } 44 + } 45 + } 46 + }, 47 + "errors": [ 48 + { 49 + "name": "NotFound" 50 + } 51 + ] 52 + } 53 + } 54 + }
+8 -8
package.json
··· 5 5 "type": "module", 6 6 "scripts": { 7 7 "dev": "vite dev", 8 - "build": "vite build && tsx scripts/append-scheduled.ts", 9 - "generate": "tsx scripts/generate.ts", 10 - "generate:pull": "tsx scripts/generate.ts && lex-cli pull && tsx scripts/generate.ts && lex-cli pull && lex-cli generate", 8 + "build": "vite build && contrail append-scheduled", 9 + "generate": "contrail-lex generate", 10 + "generate:pull": "contrail-lex all", 11 11 "preview": "vite preview", 12 12 "prepare": "svelte-kit sync || echo ''", 13 - "sync": "tsx scripts/sync.ts", 14 - "sync:remote": "tsx scripts/sync.ts --remote", 13 + "backfill": "contrail backfill", 14 + "backfill:remote": "contrail backfill --remote", 15 15 "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", 16 16 "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", 17 17 "format": "prettier --write .", ··· 20 20 "env:generate-secret": "npx tsx src/lib/atproto/scripts/generate-secret.ts", 21 21 "env:setup-dev": "npx tsx src/lib/atproto/scripts/setup-dev.ts", 22 22 "tunnel": "npx tsx src/lib/atproto/scripts/tunnel.ts", 23 - "lexicons": "lex-cli pull && lex-cli generate", 24 - "publish-lexicons": "tsx --env-file=.env scripts/publish-lexicons.ts" 23 + "publish-lexicons": "contrail-lex publish" 25 24 }, 26 25 "devDependencies": { 27 26 "@atcute/atproto": "^3.1.10", ··· 32 31 "@atcute/lexicons": "^1.2.9", 33 32 "@atcute/oauth-node-client": "^1.1.0", 34 33 "@atcute/tid": "^1.1.2", 34 + "@atmo-dev/contrail-lexicons": "^0.4.3", 35 35 "@cloudflare/workers-types": "^4.20260317.1", 36 36 "@eslint/compat": "^2.0.3", 37 37 "@eslint/js": "^10.0.1", ··· 61 61 "dependencies": { 62 62 "@atcute/bluesky-richtext-parser": "^2.1.1", 63 63 "@atcute/jetstream": "^1.1.2", 64 - "@atmo-dev/contrail": "^0.1.1", 64 + "@atmo-dev/contrail": "^0.4.2", 65 65 "@ethercorps/sveltekit-og": "^4.2.1", 66 66 "@foxui/colors": "^0.8.5", 67 67 "@foxui/core": "^0.9.1",
+37 -5
pnpm-lock.yaml
··· 15 15 specifier: ^1.1.2 16 16 version: 1.1.2 17 17 '@atmo-dev/contrail': 18 - specifier: ^0.1.1 19 - version: 0.1.1 18 + specifier: ^0.4.2 19 + version: 0.4.2(wrangler@4.77.0(@cloudflare/workers-types@4.20260317.1)) 20 20 '@ethercorps/sveltekit-og': 21 21 specifier: ^4.2.1 22 22 version: 4.2.1(@sveltejs/kit@2.55.0(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.0)(vite@8.0.3(@types/node@25.0.10)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.0)(typescript@6.0.2)(vite@8.0.3(@types/node@25.0.10)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0))) ··· 99 99 '@atcute/tid': 100 100 specifier: ^1.1.2 101 101 version: 1.1.2 102 + '@atmo-dev/contrail-lexicons': 103 + specifier: ^0.4.3 104 + version: 0.4.3(wrangler@4.77.0(@cloudflare/workers-types@4.20260317.1)) 102 105 '@cloudflare/workers-types': 103 106 specifier: ^4.20260317.1 104 107 version: 4.20260317.1 ··· 270 273 '@atcute/xrpc-server@0.1.12': 271 274 resolution: {integrity: sha512-70KIerQlljp5+s6t0u6YNN9klEboQUZa2hhoi/hmXIO1cIKEORettTMctnyjfcCJaSfAuj42dxPu51GTZBlm8w==} 272 275 273 - '@atmo-dev/contrail@0.1.1': 274 - resolution: {integrity: sha512-7BdLYjHHGC2EKlT/p3KszJAE6Pv1FPPuLVG+eYRpXSTF6iwrk/FVA0Dep7lTowbLlo5mQBpbEpo2CrQtUZAPfQ==} 276 + '@atmo-dev/contrail-lexicons@0.4.3': 277 + resolution: {integrity: sha512-j9eEiiOWj9usOqEK0hFoVcl/NSMM29X0S/vO7SlmE5jEF2UoWwXAxIr81uZ3HODtlWn5ztgWS7Ls8a6GGIU/lw==} 278 + hasBin: true 279 + 280 + '@atmo-dev/contrail@0.4.2': 281 + resolution: {integrity: sha512-ixPuxovCMnXQtjhxFhGzlDLxFt3r5FfozrQ0e9ABOjujqzP7nYpfCT1ltPJxSt2nHQJ43IUnVqqkPvV9GO0AaA==} 282 + hasBin: true 275 283 peerDependencies: 276 284 pg: ^8.0.0 285 + wrangler: ^4.0.0 277 286 peerDependenciesMeta: 278 287 pg: 288 + optional: true 289 + wrangler: 279 290 optional: true 280 291 281 292 '@badrap/valita@0.4.6': ··· 1672 1683 resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} 1673 1684 engines: {node: 18 || 20 || >=22} 1674 1685 1686 + cac@7.0.0: 1687 + resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} 1688 + engines: {node: '>=20.19.0'} 1689 + 1675 1690 camelize@1.0.1: 1676 1691 resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} 1677 1692 ··· 3150 3165 '@badrap/valita': 0.4.6 3151 3166 nanoid: 5.1.7 3152 3167 3153 - '@atmo-dev/contrail@0.1.1': 3168 + '@atmo-dev/contrail-lexicons@0.4.3(wrangler@4.77.0(@cloudflare/workers-types@4.20260317.1))': 3169 + dependencies: 3170 + '@atcute/lex-cli': 2.5.3 3171 + '@atmo-dev/contrail': 0.4.2(wrangler@4.77.0(@cloudflare/workers-types@4.20260317.1)) 3172 + transitivePeerDependencies: 3173 + - pg 3174 + - react 3175 + - wrangler 3176 + 3177 + '@atmo-dev/contrail@0.4.2(wrangler@4.77.0(@cloudflare/workers-types@4.20260317.1))': 3154 3178 dependencies: 3155 3179 '@atcute/atproto': 3.1.10 3180 + '@atcute/cbor': 2.3.2 3181 + '@atcute/cid': 2.4.1 3156 3182 '@atcute/client': 4.2.1 3157 3183 '@atcute/identity': 1.1.4 3158 3184 '@atcute/identity-resolver': 1.2.2(@atcute/identity@1.1.4) 3159 3185 '@atcute/jetstream': 1.1.2 3160 3186 '@atcute/lexicons': 1.2.9 3161 3187 '@atcute/xrpc-server': 0.1.12 3188 + cac: 7.0.0 3162 3189 hono: 4.12.14 3190 + jiti: 2.6.1 3191 + optionalDependencies: 3192 + wrangler: 4.77.0(@cloudflare/workers-types@4.20260317.1) 3163 3193 transitivePeerDependencies: 3164 3194 - react 3165 3195 ··· 4411 4441 brace-expansion@5.0.5: 4412 4442 dependencies: 4413 4443 balanced-match: 4.0.4 4444 + 4445 + cac@7.0.0: {} 4414 4446 4415 4447 camelize@1.0.1: {} 4416 4448
-29
scripts/append-scheduled.ts
··· 1 - /** 2 - * Post-build script: appends a `scheduled` handler to the SvelteKit worker output. 3 - * 4 - * SvelteKit's adapter-cloudflare doesn't support the `scheduled` export natively 5 - * (see https://github.com/sveltejs/kit/issues/4841). This script patches the 6 - * generated _worker.js to add one that self-calls the /api/cron endpoint. 7 - */ 8 - import { readFileSync, writeFileSync } from 'fs'; 9 - import { join, dirname } from 'path'; 10 - import { fileURLToPath } from 'url'; 11 - 12 - const root = join(dirname(fileURLToPath(import.meta.url)), '..'); 13 - const workerPath = join(root, '.svelte-kit', 'cloudflare', '_worker.js'); 14 - 15 - let code = readFileSync(workerPath, 'utf-8'); 16 - 17 - code += ` 18 - // --- Appended by scripts/append-scheduled.ts --- 19 - worker_default.scheduled = async function (event, env, ctx) { 20 - const req = new Request('http://localhost/api/cron', { 21 - method: 'POST', 22 - headers: { 'X-Cron-Secret': env.CRON_SECRET || '' } 23 - }); 24 - ctx.waitUntil(this.fetch(req, env, ctx)); 25 - }; 26 - `; 27 - 28 - writeFileSync(workerPath, code); 29 - console.log('Appended scheduled handler to _worker.js');
-13
scripts/generate.ts
··· 1 - import { join, dirname } from 'path'; 2 - import { fileURLToPath } from 'url'; 3 - import { config } from '../src/lib/contrail/config'; 4 - import { generateLexicons } from '@atmo-dev/contrail/generate'; 5 - 6 - const ROOT_DIR = join(dirname(fileURLToPath(import.meta.url)), '..'); 7 - 8 - generateLexicons({ 9 - config, 10 - rootDir: ROOT_DIR, 11 - outputDir: join(ROOT_DIR, 'lexicons-generated'), 12 - writeRuntimeFiles: true 13 - });
-40
scripts/publish-lexicons.ts
··· 1 - /** 2 - * Publish atmo-events' generated lexicons to the specified account's PDS. 3 - * 4 - * Usage: 5 - * LEXICON_ACCOUNT_IDENTIFIER=you.bsky.social \ 6 - * LEXICON_ACCOUNT_PASSWORD=xxxx-xxxx-xxxx-xxxx \ 7 - * pnpm publish-lexicons 8 - * 9 - * pnpm publish-lexicons <identifier> <app-password> 10 - */ 11 - 12 - import { join, dirname } from 'node:path'; 13 - import { fileURLToPath } from 'node:url'; 14 - import { publishLexicons } from '@atmo-dev/contrail/publish'; 15 - 16 - const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..'); 17 - 18 - async function main(): Promise<void> { 19 - const identifier = process.argv[2] ?? process.env.LEXICON_ACCOUNT_IDENTIFIER; 20 - const password = process.argv[3] ?? process.env.LEXICON_ACCOUNT_PASSWORD; 21 - 22 - if (!identifier || !password) { 23 - console.error( 24 - 'Usage: pnpm publish-lexicons <handle-or-did> <app-password>\n' + 25 - ' (or set LEXICON_ACCOUNT_IDENTIFIER and LEXICON_ACCOUNT_PASSWORD env vars)\n' 26 - ); 27 - process.exit(1); 28 - } 29 - 30 - await publishLexicons({ 31 - generatedDir: join(ROOT, 'lexicons-generated'), 32 - identifier, 33 - password 34 - }); 35 - } 36 - 37 - main().catch((err) => { 38 - console.error(err); 39 - process.exit(1); 40 - });
-68
scripts/sync.ts
··· 1 - /** 2 - * Discover users from relays and backfill their records from PDS. 3 - * 4 - * Usage: 5 - * pnpm sync # local D1 6 - * pnpm sync:remote # prod D1 7 - */ 8 - import { Contrail } from '@atmo-dev/contrail'; 9 - import { config } from '../src/lib/contrail/config'; 10 - import { getPlatformProxy } from 'wrangler'; 11 - 12 - function elapsed(start: number): string { 13 - const ms = Date.now() - start; 14 - if (ms < 1000) return `${ms}ms`; 15 - if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`; 16 - const mins = Math.floor(ms / 60_000); 17 - const secs = ((ms % 60_000) / 1000).toFixed(0); 18 - return `${mins}m ${secs}s`; 19 - } 20 - 21 - async function main() { 22 - const remote = process.argv.includes('--remote'); 23 - const syncStart = Date.now(); 24 - 25 - console.log(`=== Sync (${remote ? 'remote/prod' : 'local'} D1) ===\n`); 26 - 27 - const { env, dispose } = await getPlatformProxy<{ DB: D1Database }>({ 28 - environment: remote ? 'production' : undefined 29 - }); 30 - 31 - const contrail = new Contrail({ ...config, db: env.DB }); 32 - 33 - try { 34 - await contrail.init(); 35 - 36 - console.log('--- Discovery ---'); 37 - const discoveryStart = Date.now(); 38 - const discovered = await contrail.discover(); 39 - console.log(` Done: ${discovered.length} users in ${elapsed(discoveryStart)}\n`); 40 - 41 - console.log('--- Backfill ---'); 42 - const backfillStart = Date.now(); 43 - const total = await contrail.backfill({ 44 - concurrency: 100, 45 - onProgress: ({ records, usersComplete, usersTotal, usersFailed }) => { 46 - const secs = (Date.now() - backfillStart) / 1000; 47 - const rate = secs > 0 ? Math.round(records / secs) : 0; 48 - const failStr = usersFailed > 0 ? ` | ${usersFailed} failed` : ''; 49 - process.stdout.write( 50 - `\r ${records} records | ${usersComplete}/${usersTotal} users | ${rate}/s | ${elapsed(backfillStart)}${failStr} ` 51 - ); 52 - } 53 - }); 54 - process.stdout.write('\n'); 55 - console.log(` Done: ${total} records in ${elapsed(backfillStart)}\n`); 56 - 57 - console.log(`=== Finished in ${elapsed(syncStart)} ===`); 58 - console.log(` Discovered: ${discovered.length} users`); 59 - console.log(` Backfilled: ${total} records`); 60 - } finally { 61 - await dispose(); 62 - } 63 - } 64 - 65 - main().catch((err) => { 66 - console.error(err); 67 - process.exit(1); 68 - });
-66
scripts/vod-processing/config.ts
··· 1 - import { resolve, dirname } from 'node:path'; 2 - import { fileURLToPath } from 'node:url'; 3 - 4 - const __dirname = dirname(fileURLToPath(import.meta.url)); 5 - 6 - export const DATA_DIR = resolve(__dirname, 'data'); 7 - export const AUDIO_DIR = resolve(DATA_DIR, 'audio'); 8 - export const TRANSCRIPTS_DIR = resolve(DATA_DIR, 'transcripts'); 9 - export const OUTPUT_DIR = resolve(DATA_DIR, 'output'); 10 - 11 - export const EVENTS_FILE = resolve(DATA_DIR, 'events.json'); 12 - 13 - export const API_URL = 'https://atmo.rsvp/xrpc/community.lexicon.calendar.event.listRecords'; 14 - export const VOD_PLAYBACK_BASE = 15 - 'https://vod-beta.stream.place/xrpc/place.stream.playback.getVideoPlaylist'; 16 - 17 - export interface VodEvent { 18 - rkey: string; 19 - name: string; 20 - description: string; 21 - speakers: string[]; 22 - startsAt: string; 23 - endsAt: string; 24 - vodAtUri: string; 25 - playlistUrl: string; 26 - room: string; 27 - type: string; 28 - } 29 - 30 - export interface WhisperSegment { 31 - start: number; 32 - end: number; 33 - text: string; 34 - speaker?: string; 35 - words: WhisperWord[]; 36 - } 37 - 38 - export interface WhisperWord { 39 - word: string; 40 - start: number; 41 - end: number; 42 - score: number; 43 - speaker?: string; 44 - } 45 - 46 - export interface TranscriptData { 47 - segments: WhisperSegment[]; 48 - word_segments: WhisperWord[]; 49 - language: string; 50 - } 51 - 52 - export interface Chapter { 53 - start: number; 54 - end: number; 55 - title: string; 56 - } 57 - 58 - export interface VodOutput { 59 - rkey: string; 60 - name: string; 61 - speakers: string[]; 62 - description: string; 63 - transcript: TranscriptData; 64 - chapters: Chapter[]; 65 - summary: string; 66 - }
-82
scripts/vod-processing/download-audio.ts
··· 1 - /** 2 - * Step 2: Download audio-only from HLS streams using ffmpeg. 3 - * Outputs 16kHz mono WAV — the exact format whisper-cpp expects. 4 - * ~30MB per hour of audio. 5 - * Output: data/audio/<rkey>.wav 6 - */ 7 - 8 - import { existsSync, mkdirSync, readFileSync, unlinkSync } from 'node:fs'; 9 - import { execSync } from 'node:child_process'; 10 - import { AUDIO_DIR, EVENTS_FILE, type VodEvent } from './config.js'; 11 - 12 - const args = process.argv.slice(2); 13 - const only = args.find((a) => a.startsWith('--only='))?.split('=')[1]; 14 - 15 - function isVodAvailable(url: string): boolean { 16 - try { 17 - execSync(`curl -sf -o /dev/null -w "%{http_code}" "${url}"`, { 18 - timeout: 15_000 19 - }); 20 - return true; 21 - } catch { 22 - return false; 23 - } 24 - } 25 - 26 - function downloadAudio(event: VodEvent): 'ok' | 'skip' | 'fail' { 27 - const outPath = `${AUDIO_DIR}/${event.rkey}.wav`; 28 - if (existsSync(outPath)) { 29 - console.log(` ✓ exists: ${event.rkey}`); 30 - return 'ok'; 31 - } 32 - 33 - if (!isVodAvailable(event.playlistUrl)) { 34 - console.log(` – 404, skipping: ${event.rkey} (${event.name})`); 35 - return 'skip'; 36 - } 37 - 38 - try { 39 - // -vn: no video, -ar 16000 -ac 1: 16kHz mono (whisper-cpp native format) 40 - execSync( 41 - `ffmpeg -i "${event.playlistUrl}" -vn -ar 16000 -ac 1 -c:a pcm_s16le -y "${outPath}" 2>&1`, 42 - { timeout: 600_000 } 43 - ); 44 - if (!existsSync(outPath)) { 45 - console.error(` ✗ no output file: ${event.rkey}`); 46 - return 'fail'; 47 - } 48 - console.log(` ✓ downloaded: ${event.rkey} (${event.name})`); 49 - return 'ok'; 50 - } catch (err) { 51 - // Clean up partial file 52 - if (existsSync(outPath)) unlinkSync(outPath); 53 - const stderr = 54 - (err as { stdout?: Buffer }).stdout?.toString().split('\n').slice(-3).join('\n') ?? 55 - (err as Error).message; 56 - console.error(` ✗ failed: ${event.rkey} (${event.name})\n ${stderr}`); 57 - return 'fail'; 58 - } 59 - } 60 - 61 - function main() { 62 - const events: VodEvent[] = JSON.parse(readFileSync(EVENTS_FILE, 'utf-8')); 63 - mkdirSync(AUDIO_DIR, { recursive: true }); 64 - 65 - const toProcess = only ? events.filter((e) => e.rkey === only) : events; 66 - console.log(`Downloading audio for ${toProcess.length} VODs...\n`); 67 - 68 - let success = 0; 69 - let skipped = 0; 70 - let failed = 0; 71 - 72 - for (const event of toProcess) { 73 - const result = downloadAudio(event); 74 - if (result === 'ok') success++; 75 - else if (result === 'skip') skipped++; 76 - else failed++; 77 - } 78 - 79 - console.log(`\nDone: ${success} downloaded, ${skipped} skipped (404), ${failed} failed`); 80 - } 81 - 82 - main();
-55
scripts/vod-processing/fetch-events.ts
··· 1 - /** 2 - * Step 1: Fetch all atmosphereconf events with VODs from the API. 3 - * Output: data/events.json 4 - */ 5 - 6 - import { writeFileSync, mkdirSync } from 'node:fs'; 7 - import { API_URL, VOD_PLAYBACK_BASE, DATA_DIR, EVENTS_FILE, type VodEvent } from './config.js'; 8 - 9 - async function fetchEvents(): Promise<VodEvent[]> { 10 - const url = `${API_URL}?actor=atmosphereconf.org&sort=startsAt&order=asc&limit=200`; 11 - const resp = await fetch(url); 12 - const data = (await resp.json()) as { 13 - records: Array<{ 14 - rkey: string; 15 - record: { 16 - name?: string; 17 - description?: string; 18 - startsAt?: string; 19 - endsAt?: string; 20 - additionalData?: Record<string, unknown>; 21 - }; 22 - }>; 23 - }; 24 - 25 - const events: VodEvent[] = []; 26 - 27 - for (const r of data.records) { 28 - const rec = r.record; 29 - const ad = (rec.additionalData ?? {}) as Record<string, unknown>; 30 - const vodAtUri = ad.vodAtUri as string | undefined; 31 - if (!vodAtUri) continue; 32 - 33 - const speakers = (ad.speakers as Array<{ name?: string }>) ?? []; 34 - 35 - events.push({ 36 - rkey: r.rkey, 37 - name: rec.name ?? 'unknown', 38 - description: rec.description ?? '', 39 - speakers: speakers.map((s) => s.name ?? '').filter(Boolean), 40 - startsAt: rec.startsAt ?? '', 41 - endsAt: rec.endsAt ?? '', 42 - vodAtUri, 43 - playlistUrl: `${VOD_PLAYBACK_BASE}?uri=${encodeURIComponent(vodAtUri)}`, 44 - room: (ad.room as string) ?? '', 45 - type: (ad.type as string) ?? '' 46 - }); 47 - } 48 - 49 - mkdirSync(DATA_DIR, { recursive: true }); 50 - writeFileSync(EVENTS_FILE, JSON.stringify(events, null, 2)); 51 - console.log(`Found ${events.length} events with VODs → ${EVENTS_FILE}`); 52 - return events; 53 - } 54 - 55 - fetchEvents();
-259
scripts/vod-processing/generate-vtt.ts
··· 1 - /** 2 - * Step 5: Convert whisper-cpp JSON transcripts to WebVTT subtitle files. 3 - * Output: static/vods/<rkey>.vtt 4 - * 5 - * Also generates a JSON manifest at static/vods/manifest.json mapping rkey → available data. 6 - * 7 - * Options: 8 - * --only=<rkey> Process a single event 9 - */ 10 - 11 - import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync } from 'node:fs'; 12 - import { resolve, dirname } from 'node:path'; 13 - import { fileURLToPath } from 'node:url'; 14 - import { TRANSCRIPTS_DIR, EVENTS_FILE, type VodEvent } from './config.js'; 15 - 16 - const __dirname = dirname(fileURLToPath(import.meta.url)); 17 - const STATIC_VODS_DIR = resolve(__dirname, '../../static/vods'); 18 - 19 - const args = process.argv.slice(2); 20 - const only = args.find((a) => a.startsWith('--only='))?.split('=')[1]; 21 - 22 - interface WhisperToken { 23 - text: string; 24 - offsets: { from: number; to: number }; 25 - id: number; 26 - p: number; 27 - } 28 - 29 - interface WhisperSegment { 30 - timestamps: { from: string; to: string }; 31 - offsets: { from: number; to: number }; 32 - text: string; 33 - tokens: WhisperToken[]; 34 - } 35 - 36 - interface WhisperJSON { 37 - transcription: WhisperSegment[]; 38 - } 39 - 40 - function msToVttTime(ms: number): string { 41 - const h = Math.floor(ms / 3600000); 42 - const m = Math.floor((ms % 3600000) / 60000); 43 - const s = Math.floor((ms % 60000) / 1000); 44 - const frac = ms % 1000; 45 - return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}.${String(frac).padStart(3, '0')}`; 46 - } 47 - 48 - function isSpecialToken(token: WhisperToken): boolean { 49 - return token.text.startsWith('[') && token.text.endsWith(']'); 50 - } 51 - 52 - /** Collect all real words across all segments into a flat list */ 53 - function flattenWords(data: WhisperJSON): WhisperToken[] { 54 - return data.transcription.flatMap((seg) => 55 - seg.tokens.filter((t) => !isSpecialToken(t) && t.text.trim()) 56 - ); 57 - } 58 - 59 - const MAX_CUE_WORDS = 12; 60 - const MAX_CUE_MS = 8000; 61 - 62 - /** Split words into subtitle-sized chunks */ 63 - function chunkWords(words: WhisperToken[]): WhisperToken[][] { 64 - const chunks: WhisperToken[][] = []; 65 - let current: WhisperToken[] = []; 66 - 67 - for (const word of words) { 68 - current.push(word); 69 - 70 - const duration = word.offsets.to - (current[0]?.offsets.from ?? 0); 71 - const isSentenceEnd = /[.!?]$/.test(word.text.trim()); 72 - const isLong = current.length >= MAX_CUE_WORDS || duration >= MAX_CUE_MS; 73 - 74 - if (isSentenceEnd || isLong) { 75 - chunks.push(current); 76 - current = []; 77 - } 78 - } 79 - if (current.length > 0) chunks.push(current); 80 - return chunks; 81 - } 82 - 83 - /** Plain text VTT with short cues — works everywhere */ 84 - function generateVtt(data: WhisperJSON): string { 85 - const words = flattenWords(data); 86 - const chunks = chunkWords(words); 87 - const lines: string[] = ['WEBVTT', '']; 88 - 89 - for (const chunk of chunks) { 90 - const from = msToVttTime(chunk[0].offsets.from); 91 - const to = msToVttTime(chunk[chunk.length - 1].offsets.to); 92 - const text = chunk.map((w) => w.text).join('').trim(); 93 - if (!text) continue; 94 - 95 - lines.push(`${from} --> ${to}`); 96 - lines.push(text); 97 - lines.push(''); 98 - } 99 - 100 - return lines.join('\n'); 101 - } 102 - 103 - /** 104 - * Merge whisper tokens so punctuation attaches to the preceding word. 105 - * e.g. [" Okay", "."] → [" Okay."] 106 - * This avoids invalid karaoke cues where a timestamp precedes bare punctuation. 107 - */ 108 - function mergeTokens( 109 - tokens: WhisperToken[] 110 - ): Array<{ text: string; from: number; to: number }> { 111 - const merged: Array<{ text: string; from: number; to: number }> = []; 112 - for (const t of tokens) { 113 - const isPunct = /^[.,!?;:'")\]}\-–—…]+$/.test(t.text.trim()); 114 - if (isPunct && merged.length > 0) { 115 - // Attach punctuation to previous word 116 - merged[merged.length - 1].text += t.text; 117 - merged[merged.length - 1].to = t.offsets.to; 118 - } else { 119 - merged.push({ text: t.text, from: t.offsets.from, to: t.offsets.to }); 120 - } 121 - } 122 - return merged; 123 - } 124 - 125 - /** 126 - * Karaoke VTT with word-level timestamps. 127 - * Spec: <HH:MM:SS.mmm> inline before each word marks when it becomes active. 128 - * Timestamps must be strictly increasing and within the cue's time range. 129 - */ 130 - function generateKaraokeVtt(data: WhisperJSON): string { 131 - const allWords = flattenWords(data); 132 - const merged = mergeTokens(allWords); 133 - 134 - // Re-chunk using merged tokens (reuse same logic but on merged shape) 135 - const chunks: Array<{ text: string; from: number; to: number }>[][] = []; 136 - let current: Array<{ text: string; from: number; to: number }> = []; 137 - for (const word of merged) { 138 - current.push(word); 139 - const duration = word.to - (current[0]?.from ?? 0); 140 - const isSentenceEnd = /[.!?]$/.test(word.text.trim()); 141 - const isLong = current.length >= MAX_CUE_WORDS || duration >= MAX_CUE_MS; 142 - if (isSentenceEnd || isLong) { 143 - chunks.push(current); 144 - current = []; 145 - } 146 - } 147 - if (current.length > 0) chunks.push(current); 148 - 149 - const lines: string[] = ['WEBVTT', '']; 150 - 151 - for (const chunk of chunks) { 152 - const cueStart = chunk[0].from; 153 - const cueEnd = chunk[chunk.length - 1].to; 154 - 155 - // First word text appears at cue start (no inline timestamp needed). 156 - // Subsequent words get an inline timestamp, but only if it's strictly 157 - // greater than cueStart and any previous timestamp. 158 - let cueText = chunk[0].text; 159 - let lastTs = cueStart; 160 - 161 - for (let i = 1; i < chunk.length; i++) { 162 - const ts = chunk[i].from; 163 - if (ts > lastTs && ts < cueEnd) { 164 - cueText += `<${msToVttTime(ts)}>${chunk[i].text}`; 165 - lastTs = ts; 166 - } else { 167 - // Timestamp not strictly increasing or out of range — skip it 168 - cueText += chunk[i].text; 169 - } 170 - } 171 - 172 - cueText = cueText.trim(); 173 - if (!cueText) continue; 174 - 175 - lines.push(`${msToVttTime(cueStart)} --> ${msToVttTime(cueEnd)}`); 176 - lines.push(cueText); 177 - lines.push(''); 178 - } 179 - 180 - return lines.join('\n'); 181 - } 182 - 183 - /** Also generate a plain transcript JSON for the interactive transcript UI */ 184 - function generateTranscriptJson( 185 - data: WhisperJSON 186 - ): Array<{ start: number; end: number; text: string; words: Array<{ text: string; start: number; end: number }> }> { 187 - return data.transcription 188 - .map((seg) => { 189 - const words = seg.tokens 190 - .filter((t) => !isSpecialToken(t) && t.text.trim()) 191 - .map((t) => ({ 192 - text: t.text, 193 - start: t.offsets.from / 1000, 194 - end: t.offsets.to / 1000 195 - })); 196 - 197 - if (words.length === 0) return null; 198 - 199 - return { 200 - start: seg.offsets.from / 1000, 201 - end: seg.offsets.to / 1000, 202 - text: seg.text.trim(), 203 - words 204 - }; 205 - }) 206 - .filter((s): s is NonNullable<typeof s> => s !== null); 207 - } 208 - 209 - function processEvent(event: VodEvent): boolean { 210 - const transcriptFile = `${TRANSCRIPTS_DIR}/${event.rkey}.json`; 211 - if (!existsSync(transcriptFile)) { 212 - console.log(` – no transcript: ${event.rkey}`); 213 - return false; 214 - } 215 - 216 - const data: WhisperJSON = JSON.parse(readFileSync(transcriptFile, 'utf-8')); 217 - 218 - // Generate plain VTT (works everywhere) 219 - const vtt = generateVtt(data); 220 - writeFileSync(`${STATIC_VODS_DIR}/${event.rkey}.vtt`, vtt); 221 - 222 - // Generate karaoke VTT (word-level highlighting) 223 - const karaokeVtt = generateKaraokeVtt(data); 224 - writeFileSync(`${STATIC_VODS_DIR}/${event.rkey}-karaoke.vtt`, karaokeVtt); 225 - 226 - // Generate transcript JSON (for interactive transcript below video) 227 - const transcript = generateTranscriptJson(data); 228 - writeFileSync(`${STATIC_VODS_DIR}/${event.rkey}.json`, JSON.stringify(transcript)); 229 - 230 - console.log(` ✓ ${event.rkey} (${data.transcription.length} segments)`); 231 - return true; 232 - } 233 - 234 - function main() { 235 - const events: VodEvent[] = JSON.parse(readFileSync(EVENTS_FILE, 'utf-8')); 236 - mkdirSync(STATIC_VODS_DIR, { recursive: true }); 237 - 238 - const toProcess = only ? events.filter((e) => e.rkey === only) : events; 239 - console.log(`Generating VTT + transcript JSON for ${toProcess.length} events...\n`); 240 - 241 - let success = 0; 242 - let skipped = 0; 243 - 244 - for (const event of toProcess) { 245 - if (processEvent(event)) success++; 246 - else skipped++; 247 - } 248 - 249 - // Generate manifest: list of rkeys that have VTT files 250 - const allVtts = readdirSync(STATIC_VODS_DIR) 251 - .filter((f) => f.endsWith('.vtt')) 252 - .map((f) => f.replace('.vtt', '')); 253 - writeFileSync(`${STATIC_VODS_DIR}/manifest.json`, JSON.stringify(allVtts)); 254 - 255 - console.log(`\nDone: ${success} generated, ${skipped} skipped`); 256 - console.log(`Manifest: ${allVtts.length} VTTs in static/vods/`); 257 - } 258 - 259 - main();
-67
scripts/vod-processing/pipeline.ts
··· 1 - /** 2 - * Full VOD processing pipeline: 3 - * 1. Fetch events with VODs from API 4 - * 2. Download audio (m4a, no video) 5 - * 3. Transcribe with whisperx (word timestamps + speaker diarization) 6 - * 4. Generate chapters + summaries with Claude 7 - * 8 - * Usage: 9 - * tsx scripts/vod-processing/pipeline.ts [options] 10 - * 11 - * Options: 12 - * --step=<1-4> Run only a specific step 13 - * --only=<rkey> Process only a specific event 14 - * --skip-diarize Skip speaker diarization 15 - * --skip-summary Skip Claude chapters/summary generation 16 - * --hf-token=<token> HuggingFace token for pyannote (or set HF_TOKEN) 17 - * --model=<model> Whisper model (default: large-v3) 18 - * --batch-size=<n> Whisper batch size (default: 16) 19 - * 20 - * Prerequisites: 21 - * brew install ffmpeg 22 - * pip install whisperx 23 - * npm install anthropic (for summaries) 24 - * 25 - * For speaker diarization: 26 - * 1. Create HuggingFace account 27 - * 2. Accept pyannote/speaker-diarization-3.1 terms 28 - * 3. Accept pyannote/segmentation-3.0 terms 29 - * 4. Set HF_TOKEN=<your-token> 30 - */ 31 - 32 - import { execSync } from 'node:child_process'; 33 - 34 - const args = process.argv.slice(2); 35 - const step = args.find((a) => a.startsWith('--step='))?.split('=')[1]; 36 - const passthrough = args.filter((a) => !a.startsWith('--step=')).join(' '); 37 - 38 - const SCRIPTS_DIR = new URL('.', import.meta.url).pathname; 39 - 40 - function run(script: string) { 41 - execSync(`tsx ${SCRIPTS_DIR}${script} ${passthrough}`, { 42 - stdio: 'inherit', 43 - timeout: 86_400_000 // 24h for full pipeline 44 - }); 45 - } 46 - 47 - const steps: Record<string, [string, string]> = { 48 - '1': ['fetch-events.ts', 'Fetching events'], 49 - '2': ['download-audio.ts', 'Downloading audio'], 50 - '3': ['transcribe.ts', 'Transcribing'], 51 - '4': ['summarize.ts', 'Generating chapters & summaries'] 52 - }; 53 - 54 - if (step) { 55 - const s = steps[step]; 56 - if (!s) { 57 - console.error(`Unknown step: ${step}. Use 1-4.`); 58 - process.exit(1); 59 - } 60 - console.log(`\n═══ Step ${step}: ${s[1]} ═══\n`); 61 - run(s[0]); 62 - } else { 63 - for (const [num, [script, label]] of Object.entries(steps)) { 64 - console.log(`\n═══ Step ${num}: ${label} ═══\n`); 65 - run(script); 66 - } 67 - }
-174
scripts/vod-processing/summarize.ts
··· 1 - /** 2 - * Step 4: Use Claude to generate chapters and summaries from transcripts. 3 - * Output: data/output/<rkey>.json 4 - * 5 - * Requires: ANTHROPIC_API_KEY env var, npm install anthropic 6 - */ 7 - 8 - import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'; 9 - import { 10 - TRANSCRIPTS_DIR, 11 - OUTPUT_DIR, 12 - EVENTS_FILE, 13 - type VodEvent, 14 - type TranscriptData, 15 - type VodOutput, 16 - type Chapter 17 - } from './config.js'; 18 - 19 - const args = process.argv.slice(2); 20 - const only = args.find((a) => a.startsWith('--only='))?.split('=')[1]; 21 - const skipSummary = args.includes('--skip-summary'); 22 - 23 - async function getAnthropicClient() { 24 - const { default: Anthropic } = await import('anthropic'); 25 - return new Anthropic(); 26 - } 27 - 28 - function formatTranscriptForPrompt(transcript: TranscriptData): string { 29 - return transcript.segments 30 - .map((seg) => { 31 - const time = formatTime(seg.start); 32 - const speaker = seg.speaker ? `[${seg.speaker}] ` : ''; 33 - return `[${time}] ${speaker}${seg.text.trim()}`; 34 - }) 35 - .join('\n'); 36 - } 37 - 38 - function formatTime(seconds: number): string { 39 - const h = Math.floor(seconds / 3600); 40 - const m = Math.floor((seconds % 3600) / 60); 41 - const s = Math.floor(seconds % 60); 42 - return h > 0 ? `${h}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}` : `${m}:${String(s).padStart(2, '0')}`; 43 - } 44 - 45 - async function generateChaptersAndSummary( 46 - event: VodEvent, 47 - transcript: TranscriptData, 48 - client: Awaited<ReturnType<typeof getAnthropicClient>> 49 - ): Promise<{ chapters: Chapter[]; summary: string }> { 50 - const formattedTranscript = formatTranscriptForPrompt(transcript); 51 - 52 - const prompt = `You are analyzing a conference talk transcript from AtmosphereConf, a conference about the AT Protocol / Bluesky ecosystem. 53 - 54 - Talk: "${event.name}" 55 - Speakers: ${event.speakers.join(', ') || 'Unknown'} 56 - Description: ${event.description || 'No description provided'} 57 - 58 - Here is the timestamped transcript: 59 - 60 - ${formattedTranscript} 61 - 62 - Please provide: 63 - 64 - 1. **Chapters**: Break the talk into logical chapters/sections. Each chapter should have a start timestamp (in seconds), end timestamp (in seconds), and a short descriptive title. Aim for 3-8 chapters depending on talk length. 65 - 66 - 2. **Summary**: A concise summary of the talk (2-4 paragraphs) covering the key points, arguments, and takeaways. 67 - 68 - Respond in this exact JSON format (no markdown, just raw JSON): 69 - { 70 - "chapters": [ 71 - {"start": 0, "end": 120, "title": "Introduction"}, 72 - {"start": 120, "end": 450, "title": "..."} 73 - ], 74 - "summary": "..." 75 - }`; 76 - 77 - const response = await client.messages.create({ 78 - model: 'claude-sonnet-4-20250514', 79 - max_tokens: 4096, 80 - messages: [{ role: 'user', content: prompt }] 81 - }); 82 - 83 - const text = response.content 84 - .filter((c): c is { type: 'text'; text: string } => c.type === 'text') 85 - .map((c) => c.text) 86 - .join(''); 87 - 88 - try { 89 - return JSON.parse(text); 90 - } catch { 91 - // Try to extract JSON from markdown code blocks 92 - const jsonMatch = text.match(/```(?:json)?\s*([\s\S]*?)\s*```/); 93 - if (jsonMatch) { 94 - return JSON.parse(jsonMatch[1]); 95 - } 96 - throw new Error(`Failed to parse Claude response as JSON: ${text.slice(0, 200)}`); 97 - } 98 - } 99 - 100 - async function processEvent( 101 - event: VodEvent, 102 - client: Awaited<ReturnType<typeof getAnthropicClient>> 103 - ): Promise<boolean> { 104 - const outFile = `${OUTPUT_DIR}/${event.rkey}.json`; 105 - if (existsSync(outFile)) { 106 - console.log(` ✓ already processed: ${event.rkey}`); 107 - return true; 108 - } 109 - 110 - const transcriptFile = `${TRANSCRIPTS_DIR}/${event.rkey}.json`; 111 - if (!existsSync(transcriptFile)) { 112 - console.log(` ✗ no transcript: ${event.rkey}`); 113 - return false; 114 - } 115 - 116 - const transcript: TranscriptData = JSON.parse(readFileSync(transcriptFile, 'utf-8')); 117 - 118 - let chapters: Chapter[] = []; 119 - let summary = ''; 120 - 121 - if (!skipSummary) { 122 - try { 123 - console.log(` ⏳ generating chapters/summary: ${event.rkey} (${event.name})...`); 124 - const result = await generateChaptersAndSummary(event, transcript, client); 125 - chapters = result.chapters; 126 - summary = result.summary; 127 - console.log(` ✓ generated: ${event.rkey}`); 128 - } catch (err) { 129 - console.error(` ✗ Claude failed for ${event.rkey}: ${(err as Error).message}`); 130 - } 131 - } 132 - 133 - const output: VodOutput = { 134 - rkey: event.rkey, 135 - name: event.name, 136 - speakers: event.speakers, 137 - description: event.description, 138 - transcript, 139 - chapters, 140 - summary 141 - }; 142 - 143 - writeFileSync(outFile, JSON.stringify(output, null, 2)); 144 - return true; 145 - } 146 - 147 - async function main() { 148 - const events: VodEvent[] = JSON.parse(readFileSync(EVENTS_FILE, 'utf-8')); 149 - mkdirSync(OUTPUT_DIR, { recursive: true }); 150 - 151 - const toProcess = only ? events.filter((e) => e.rkey === only) : events; 152 - console.log(`Processing ${toProcess.length} transcripts...\n`); 153 - 154 - let client: Awaited<ReturnType<typeof getAnthropicClient>> | null = null; 155 - if (!skipSummary) { 156 - if (!process.env.ANTHROPIC_API_KEY) { 157 - console.log('⚠️ No ANTHROPIC_API_KEY set — chapters/summaries will be skipped.\n'); 158 - } else { 159 - client = await getAnthropicClient(); 160 - } 161 - } 162 - 163 - let success = 0; 164 - let failed = 0; 165 - 166 - for (const event of toProcess) { 167 - if (await processEvent(event, client!)) success++; 168 - else failed++; 169 - } 170 - 171 - console.log(`\nDone: ${success} processed, ${failed} failed`); 172 - } 173 - 174 - main();
-131
scripts/vod-processing/transcribe.ts
··· 1 - /** 2 - * Step 3: Run whisper-cpp on audio files. 3 - * Uses whisper-cli (brew install whisper-cpp) with --output-json-full 4 - * for word-level timestamps. 5 - * 6 - * Output: data/transcripts/<rkey>.json 7 - * 8 - * Options: 9 - * --model=<path> Path to ggml model file (default: large-v3-turbo-q8_0) 10 - * --only=<rkey> Process a single event 11 - * --diarize Enable stereo diarization (needs stereo audio) 12 - * --tinydiarize Enable tinydiarize (needs tdrz model) 13 - */ 14 - 15 - import { existsSync, mkdirSync, readFileSync, renameSync } from 'node:fs'; 16 - import { execSync } from 'node:child_process'; 17 - import { AUDIO_DIR, TRANSCRIPTS_DIR, EVENTS_FILE, type VodEvent } from './config.js'; 18 - 19 - const args = process.argv.slice(2); 20 - const model = 21 - args.find((a) => a.startsWith('--model='))?.split('=')[1] ?? 22 - `${process.env.HOME}/Library/Caches/whisper-cpp/ggml-large-v3-turbo-q8_0.bin`; 23 - const only = args.find((a) => a.startsWith('--only='))?.split('=')[1]; 24 - const diarize = args.includes('--diarize'); 25 - const tinydiarize = args.includes('--tinydiarize'); 26 - 27 - function findModel(): string { 28 - if (existsSync(model)) return model; 29 - 30 - // Try common locations 31 - const candidates = [ 32 - `${process.env.HOME}/Library/Caches/whisper-cpp/ggml-large-v3-turbo-q8_0.bin`, 33 - `${process.env.HOME}/Library/Caches/whisper-cpp/ggml-large-v3.bin`, 34 - `${process.env.HOME}/Library/Caches/whisper-cpp/ggml-large-v3-turbo.bin`, 35 - `${process.env.HOME}/.cache/whisper-cpp/ggml-large-v3-turbo-q8_0.bin`, 36 - '/opt/homebrew/share/whisper-cpp/models/ggml-base.en.bin' 37 - ]; 38 - 39 - for (const c of candidates) { 40 - if (existsSync(c)) { 41 - console.log(`Found model: ${c}`); 42 - return c; 43 - } 44 - } 45 - 46 - console.error( 47 - 'No whisper model found. Download one with:\n' + 48 - ' whisper-cli --model-path <path> --model ggml-large-v3-turbo-q8_0\n' + 49 - 'Or pass --model=<path>' 50 - ); 51 - process.exit(1); 52 - } 53 - 54 - function transcribe(event: VodEvent, modelPath: string): boolean { 55 - const audioPath = `${AUDIO_DIR}/${event.rkey}.wav`; 56 - const outFile = `${TRANSCRIPTS_DIR}/${event.rkey}.json`; 57 - 58 - if (existsSync(outFile)) { 59 - console.log(` ✓ already transcribed: ${event.rkey}`); 60 - return true; 61 - } 62 - 63 - if (!existsSync(audioPath)) { 64 - console.log(` ✗ no audio file: ${event.rkey}`); 65 - return false; 66 - } 67 - 68 - const flags = [ 69 - `--model "${modelPath}"`, 70 - '--output-json-full', // includes word-level timestamps 71 - `--output-file "${TRANSCRIPTS_DIR}/${event.rkey}"`, 72 - '--language en', 73 - '--print-progress', 74 - diarize ? '--diarize' : '', 75 - tinydiarize ? '--tinydiarize' : '' 76 - ] 77 - .filter(Boolean) 78 - .join(' '); 79 - 80 - try { 81 - console.log(` ⏳ transcribing: ${event.rkey} (${event.name})...`); 82 - execSync(`whisper-cli ${flags} "${audioPath}" 2>&1`, { 83 - timeout: 1_800_000, // 30 min 84 - stdio: ['pipe', 'pipe', 'pipe'] 85 - }); 86 - 87 - // whisper-cli outputs as <name>.json 88 - if (existsSync(outFile)) { 89 - console.log(` ✓ transcribed: ${event.rkey}`); 90 - return true; 91 - } 92 - 93 - // Sometimes it appends .wav.json 94 - const altOut = `${TRANSCRIPTS_DIR}/${event.rkey}.wav.json`; 95 - if (existsSync(altOut)) { 96 - renameSync(altOut, outFile); 97 - console.log(` ✓ transcribed: ${event.rkey}`); 98 - return true; 99 - } 100 - 101 - console.error(` ✗ no output found for: ${event.rkey}`); 102 - return false; 103 - } catch (err) { 104 - const msg = 105 - (err as { stdout?: Buffer }).stdout?.toString().split('\n').slice(-5).join('\n') ?? 106 - (err as Error).message; 107 - console.error(` ✗ failed: ${event.rkey} — ${msg}`); 108 - return false; 109 - } 110 - } 111 - 112 - function main() { 113 - const modelPath = findModel(); 114 - const events: VodEvent[] = JSON.parse(readFileSync(EVENTS_FILE, 'utf-8')); 115 - mkdirSync(TRANSCRIPTS_DIR, { recursive: true }); 116 - 117 - const toProcess = only ? events.filter((e) => e.rkey === only) : events; 118 - console.log(`Transcribing ${toProcess.length} VODs with whisper-cpp (model: ${modelPath})...\n`); 119 - 120 - let success = 0; 121 - let failed = 0; 122 - 123 - for (const event of toProcess) { 124 - if (transcribe(event, modelPath)) success++; 125 - else failed++; 126 - } 127 - 128 - console.log(`\nDone: ${success} transcribed, ${failed} failed`); 129 - } 130 - 131 - main();
+9 -5
src/lexicon-types/index.ts
··· 10 10 export * as RsvpAtmoGetCursor from "./types/rsvp/atmo/getCursor.js"; 11 11 export * as RsvpAtmoGetOverview from "./types/rsvp/atmo/getOverview.js"; 12 12 export * as RsvpAtmoGetProfile from "./types/rsvp/atmo/getProfile.js"; 13 + export * as RsvpAtmoInviteCreate from "./types/rsvp/atmo/invite/create.js"; 14 + export * as RsvpAtmoInviteDefs from "./types/rsvp/atmo/invite/defs.js"; 15 + export * as RsvpAtmoInviteList from "./types/rsvp/atmo/invite/list.js"; 16 + export * as RsvpAtmoInviteRedeem from "./types/rsvp/atmo/invite/redeem.js"; 17 + export * as RsvpAtmoInviteRevoke from "./types/rsvp/atmo/invite/revoke.js"; 13 18 export * as RsvpAtmoNotifyOfUpdate from "./types/rsvp/atmo/notifyOfUpdate.js"; 14 19 export * as RsvpAtmoRsvpGetRecord from "./types/rsvp/atmo/rsvp/getRecord.js"; 15 20 export * as RsvpAtmoRsvpListRecords from "./types/rsvp/atmo/rsvp/listRecords.js"; ··· 17 22 export * as RsvpAtmoSpaceCreateSpace from "./types/rsvp/atmo/space/createSpace.js"; 18 23 export * as RsvpAtmoSpaceDefs from "./types/rsvp/atmo/space/defs.js"; 19 24 export * as RsvpAtmoSpaceDeleteRecord from "./types/rsvp/atmo/space/deleteRecord.js"; 25 + export * as RsvpAtmoSpaceGetBlob from "./types/rsvp/atmo/space/getBlob.js"; 20 26 export * as RsvpAtmoSpaceGetRecord from "./types/rsvp/atmo/space/getRecord.js"; 21 27 export * as RsvpAtmoSpaceGetSpace from "./types/rsvp/atmo/space/getSpace.js"; 22 - export * as RsvpAtmoSpaceInviteCreate from "./types/rsvp/atmo/space/invite/create.js"; 23 - export * as RsvpAtmoSpaceInviteList from "./types/rsvp/atmo/space/invite/list.js"; 24 - export * as RsvpAtmoSpaceInviteRedeem from "./types/rsvp/atmo/space/invite/redeem.js"; 25 - export * as RsvpAtmoSpaceInviteRevoke from "./types/rsvp/atmo/space/invite/revoke.js"; 26 28 export * as RsvpAtmoSpaceLeaveSpace from "./types/rsvp/atmo/space/leaveSpace.js"; 29 + export * as RsvpAtmoSpaceListBlobs from "./types/rsvp/atmo/space/listBlobs.js"; 27 30 export * as RsvpAtmoSpaceListMembers from "./types/rsvp/atmo/space/listMembers.js"; 28 31 export * as RsvpAtmoSpaceListRecords from "./types/rsvp/atmo/space/listRecords.js"; 29 32 export * as RsvpAtmoSpaceListSpaces from "./types/rsvp/atmo/space/listSpaces.js"; 30 33 export * as RsvpAtmoSpacePutRecord from "./types/rsvp/atmo/space/putRecord.js"; 31 34 export * as RsvpAtmoSpaceRemoveMember from "./types/rsvp/atmo/space/removeMember.js"; 32 - export * as RsvpAtmoSpaceWhoami from "./types/rsvp/atmo/space/whoami.js"; 35 + export * as RsvpAtmoSpaceUploadBlob from "./types/rsvp/atmo/space/uploadBlob.js"; 36 + export * as RsvpAtmoSpaceExtWhoami from "./types/rsvp/atmo/spaceExt/whoami.js";
-239
src/lexicon-types/types/community/lexicon/calendar/event/getRecord.ts
··· 1 - import type {} from "@atcute/lexicons"; 2 - import * as v from "@atcute/lexicons/validations"; 3 - import type {} from "@atcute/lexicons/ambient"; 4 - import * as ComAtprotoLabelDefs from "@atcute/atproto/types/label/defs"; 5 - import * as ComAtprotoRepoStrongRef from "@atcute/atproto/types/repo/strongRef"; 6 - import * as CommunityLexiconCalendarEvent from "../event.js"; 7 - import * as CommunityLexiconCalendarRsvp from "../rsvp.js"; 8 - 9 - const _appBskyActorProfileSchema = /*#__PURE__*/ v.object({ 10 - $type: /*#__PURE__*/ v.optional( 11 - /*#__PURE__*/ v.literal( 12 - "community.lexicon.calendar.event.getRecord#appBskyActorProfile", 13 - ), 14 - ), 15 - /** 16 - * Small image to be displayed next to posts from account. AKA, 'profile picture' 17 - * @accept image/png, image/jpeg 18 - * @maxSize 1000000 19 - */ 20 - avatar: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.blob()), 21 - /** 22 - * Larger horizontal image to display behind profile view. 23 - * @accept image/png, image/jpeg 24 - * @maxSize 1000000 25 - */ 26 - banner: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.blob()), 27 - createdAt: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.datetimeString()), 28 - /** 29 - * Free-form profile description text. 30 - * @maxLength 2560 31 - * @maxGraphemes 256 32 - */ 33 - description: /*#__PURE__*/ v.optional( 34 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 35 - /*#__PURE__*/ v.stringLength(0, 2560), 36 - /*#__PURE__*/ v.stringGraphemes(0, 256), 37 - ]), 38 - ), 39 - /** 40 - * @maxLength 640 41 - * @maxGraphemes 64 42 - */ 43 - displayName: /*#__PURE__*/ v.optional( 44 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 45 - /*#__PURE__*/ v.stringLength(0, 640), 46 - /*#__PURE__*/ v.stringGraphemes(0, 64), 47 - ]), 48 - ), 49 - get joinedViaStarterPack() { 50 - return /*#__PURE__*/ v.optional(ComAtprotoRepoStrongRef.mainSchema); 51 - }, 52 - /** 53 - * Self-label values, specific to the Bluesky application, on the overall account. 54 - */ 55 - get labels() { 56 - return /*#__PURE__*/ v.optional( 57 - /*#__PURE__*/ v.variant([ComAtprotoLabelDefs.selfLabelsSchema]), 58 - ); 59 - }, 60 - get pinnedPost() { 61 - return /*#__PURE__*/ v.optional(ComAtprotoRepoStrongRef.mainSchema); 62 - }, 63 - /** 64 - * Free-form pronouns text. 65 - * @maxLength 200 66 - * @maxGraphemes 20 67 - */ 68 - pronouns: /*#__PURE__*/ v.optional( 69 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 70 - /*#__PURE__*/ v.stringLength(0, 200), 71 - /*#__PURE__*/ v.stringGraphemes(0, 20), 72 - ]), 73 - ), 74 - website: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.genericUriString()), 75 - }); 76 - const _hydrateRsvpsSchema = /*#__PURE__*/ v.object({ 77 - $type: /*#__PURE__*/ v.optional( 78 - /*#__PURE__*/ v.literal( 79 - "community.lexicon.calendar.event.getRecord#hydrateRsvps", 80 - ), 81 - ), 82 - get going() { 83 - return /*#__PURE__*/ v.optional( 84 - /*#__PURE__*/ v.array(hydrateRsvpsRecordSchema), 85 - ); 86 - }, 87 - get interested() { 88 - return /*#__PURE__*/ v.optional( 89 - /*#__PURE__*/ v.array(hydrateRsvpsRecordSchema), 90 - ); 91 - }, 92 - get notgoing() { 93 - return /*#__PURE__*/ v.optional( 94 - /*#__PURE__*/ v.array(hydrateRsvpsRecordSchema), 95 - ); 96 - }, 97 - get other() { 98 - return /*#__PURE__*/ v.optional( 99 - /*#__PURE__*/ v.array(hydrateRsvpsRecordSchema), 100 - ); 101 - }, 102 - }); 103 - const _hydrateRsvpsRecordSchema = /*#__PURE__*/ v.object({ 104 - $type: /*#__PURE__*/ v.optional( 105 - /*#__PURE__*/ v.literal( 106 - "community.lexicon.calendar.event.getRecord#hydrateRsvpsRecord", 107 - ), 108 - ), 109 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 110 - collection: /*#__PURE__*/ v.nsidString(), 111 - did: /*#__PURE__*/ v.didString(), 112 - get record() { 113 - return /*#__PURE__*/ v.optional(CommunityLexiconCalendarRsvp.mainSchema); 114 - }, 115 - rkey: /*#__PURE__*/ v.string(), 116 - time_us: /*#__PURE__*/ v.integer(), 117 - uri: /*#__PURE__*/ v.resourceUriString(), 118 - }); 119 - const _mainSchema = /*#__PURE__*/ v.query( 120 - "community.lexicon.calendar.event.getRecord", 121 - { 122 - params: /*#__PURE__*/ v.object({ 123 - /** 124 - * Number of rsvps records to embed 125 - * @minimum 1 126 - * @maximum 50 127 - */ 128 - hydrateRsvps: /*#__PURE__*/ v.optional( 129 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.integer(), [ 130 - /*#__PURE__*/ v.integerRange(1, 50), 131 - ]), 132 - ), 133 - /** 134 - * Include profile + identity info keyed by DID 135 - */ 136 - profiles: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.boolean()), 137 - /** 138 - * AT URI of the record 139 - */ 140 - uri: /*#__PURE__*/ v.resourceUriString(), 141 - }), 142 - output: { 143 - type: "lex", 144 - schema: /*#__PURE__*/ v.object({ 145 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 146 - collection: /*#__PURE__*/ v.nsidString(), 147 - did: /*#__PURE__*/ v.didString(), 148 - get profiles() { 149 - return /*#__PURE__*/ v.optional( 150 - /*#__PURE__*/ v.array(profileEntrySchema), 151 - ); 152 - }, 153 - get record() { 154 - return /*#__PURE__*/ v.optional( 155 - CommunityLexiconCalendarEvent.mainSchema, 156 - ); 157 - }, 158 - rkey: /*#__PURE__*/ v.string(), 159 - get rsvps() { 160 - return /*#__PURE__*/ v.optional(hydrateRsvpsSchema); 161 - }, 162 - /** 163 - * Total rsvps count 164 - */ 165 - rsvpsCount: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 166 - /** 167 - * rsvps count where status = going 168 - */ 169 - rsvpsGoingCount: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 170 - /** 171 - * rsvps count where status = interested 172 - */ 173 - rsvpsInterestedCount: /*#__PURE__*/ v.optional( 174 - /*#__PURE__*/ v.integer(), 175 - ), 176 - /** 177 - * rsvps count where status = notgoing 178 - */ 179 - rsvpsNotgoingCount: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 180 - time_us: /*#__PURE__*/ v.integer(), 181 - uri: /*#__PURE__*/ v.resourceUriString(), 182 - }), 183 - }, 184 - }, 185 - ); 186 - const _profileEntrySchema = /*#__PURE__*/ v.object({ 187 - $type: /*#__PURE__*/ v.optional( 188 - /*#__PURE__*/ v.literal( 189 - "community.lexicon.calendar.event.getRecord#profileEntry", 190 - ), 191 - ), 192 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 193 - collection: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.nsidString()), 194 - did: /*#__PURE__*/ v.didString(), 195 - handle: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 196 - get record() { 197 - return /*#__PURE__*/ v.optional(appBskyActorProfileSchema); 198 - }, 199 - rkey: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 200 - uri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 201 - }); 202 - 203 - type appBskyActorProfile$schematype = typeof _appBskyActorProfileSchema; 204 - type hydrateRsvps$schematype = typeof _hydrateRsvpsSchema; 205 - type hydrateRsvpsRecord$schematype = typeof _hydrateRsvpsRecordSchema; 206 - type main$schematype = typeof _mainSchema; 207 - type profileEntry$schematype = typeof _profileEntrySchema; 208 - 209 - export interface appBskyActorProfileSchema extends appBskyActorProfile$schematype {} 210 - export interface hydrateRsvpsSchema extends hydrateRsvps$schematype {} 211 - export interface hydrateRsvpsRecordSchema extends hydrateRsvpsRecord$schematype {} 212 - export interface mainSchema extends main$schematype {} 213 - export interface profileEntrySchema extends profileEntry$schematype {} 214 - 215 - export const appBskyActorProfileSchema = 216 - _appBskyActorProfileSchema as appBskyActorProfileSchema; 217 - export const hydrateRsvpsSchema = _hydrateRsvpsSchema as hydrateRsvpsSchema; 218 - export const hydrateRsvpsRecordSchema = 219 - _hydrateRsvpsRecordSchema as hydrateRsvpsRecordSchema; 220 - export const mainSchema = _mainSchema as mainSchema; 221 - export const profileEntrySchema = _profileEntrySchema as profileEntrySchema; 222 - 223 - export interface AppBskyActorProfile extends v.InferInput< 224 - typeof appBskyActorProfileSchema 225 - > {} 226 - export interface HydrateRsvps extends v.InferInput<typeof hydrateRsvpsSchema> {} 227 - export interface HydrateRsvpsRecord extends v.InferInput< 228 - typeof hydrateRsvpsRecordSchema 229 - > {} 230 - export interface ProfileEntry extends v.InferInput<typeof profileEntrySchema> {} 231 - 232 - export interface $params extends v.InferInput<mainSchema["params"]> {} 233 - export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {} 234 - 235 - declare module "@atcute/lexicons/ambient" { 236 - interface XRPCQueries { 237 - "community.lexicon.calendar.event.getRecord": mainSchema; 238 - } 239 - }
-351
src/lexicon-types/types/community/lexicon/calendar/event/listRecords.ts
··· 1 - import type {} from "@atcute/lexicons"; 2 - import * as v from "@atcute/lexicons/validations"; 3 - import type {} from "@atcute/lexicons/ambient"; 4 - import * as ComAtprotoLabelDefs from "@atcute/atproto/types/label/defs"; 5 - import * as ComAtprotoRepoStrongRef from "@atcute/atproto/types/repo/strongRef"; 6 - import * as CommunityLexiconCalendarEvent from "../event.js"; 7 - import * as CommunityLexiconCalendarRsvp from "../rsvp.js"; 8 - 9 - const _appBskyActorProfileSchema = /*#__PURE__*/ v.object({ 10 - $type: /*#__PURE__*/ v.optional( 11 - /*#__PURE__*/ v.literal( 12 - "community.lexicon.calendar.event.listRecords#appBskyActorProfile", 13 - ), 14 - ), 15 - /** 16 - * Small image to be displayed next to posts from account. AKA, 'profile picture' 17 - * @accept image/png, image/jpeg 18 - * @maxSize 1000000 19 - */ 20 - avatar: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.blob()), 21 - /** 22 - * Larger horizontal image to display behind profile view. 23 - * @accept image/png, image/jpeg 24 - * @maxSize 1000000 25 - */ 26 - banner: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.blob()), 27 - createdAt: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.datetimeString()), 28 - /** 29 - * Free-form profile description text. 30 - * @maxLength 2560 31 - * @maxGraphemes 256 32 - */ 33 - description: /*#__PURE__*/ v.optional( 34 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 35 - /*#__PURE__*/ v.stringLength(0, 2560), 36 - /*#__PURE__*/ v.stringGraphemes(0, 256), 37 - ]), 38 - ), 39 - /** 40 - * @maxLength 640 41 - * @maxGraphemes 64 42 - */ 43 - displayName: /*#__PURE__*/ v.optional( 44 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 45 - /*#__PURE__*/ v.stringLength(0, 640), 46 - /*#__PURE__*/ v.stringGraphemes(0, 64), 47 - ]), 48 - ), 49 - get joinedViaStarterPack() { 50 - return /*#__PURE__*/ v.optional(ComAtprotoRepoStrongRef.mainSchema); 51 - }, 52 - /** 53 - * Self-label values, specific to the Bluesky application, on the overall account. 54 - */ 55 - get labels() { 56 - return /*#__PURE__*/ v.optional( 57 - /*#__PURE__*/ v.variant([ComAtprotoLabelDefs.selfLabelsSchema]), 58 - ); 59 - }, 60 - get pinnedPost() { 61 - return /*#__PURE__*/ v.optional(ComAtprotoRepoStrongRef.mainSchema); 62 - }, 63 - /** 64 - * Free-form pronouns text. 65 - * @maxLength 200 66 - * @maxGraphemes 20 67 - */ 68 - pronouns: /*#__PURE__*/ v.optional( 69 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 70 - /*#__PURE__*/ v.stringLength(0, 200), 71 - /*#__PURE__*/ v.stringGraphemes(0, 20), 72 - ]), 73 - ), 74 - website: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.genericUriString()), 75 - }); 76 - const _hydrateRsvpsSchema = /*#__PURE__*/ v.object({ 77 - $type: /*#__PURE__*/ v.optional( 78 - /*#__PURE__*/ v.literal( 79 - "community.lexicon.calendar.event.listRecords#hydrateRsvps", 80 - ), 81 - ), 82 - get going() { 83 - return /*#__PURE__*/ v.optional( 84 - /*#__PURE__*/ v.array(hydrateRsvpsRecordSchema), 85 - ); 86 - }, 87 - get interested() { 88 - return /*#__PURE__*/ v.optional( 89 - /*#__PURE__*/ v.array(hydrateRsvpsRecordSchema), 90 - ); 91 - }, 92 - get notgoing() { 93 - return /*#__PURE__*/ v.optional( 94 - /*#__PURE__*/ v.array(hydrateRsvpsRecordSchema), 95 - ); 96 - }, 97 - get other() { 98 - return /*#__PURE__*/ v.optional( 99 - /*#__PURE__*/ v.array(hydrateRsvpsRecordSchema), 100 - ); 101 - }, 102 - }); 103 - const _hydrateRsvpsRecordSchema = /*#__PURE__*/ v.object({ 104 - $type: /*#__PURE__*/ v.optional( 105 - /*#__PURE__*/ v.literal( 106 - "community.lexicon.calendar.event.listRecords#hydrateRsvpsRecord", 107 - ), 108 - ), 109 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 110 - collection: /*#__PURE__*/ v.nsidString(), 111 - did: /*#__PURE__*/ v.didString(), 112 - get record() { 113 - return /*#__PURE__*/ v.optional(CommunityLexiconCalendarRsvp.mainSchema); 114 - }, 115 - rkey: /*#__PURE__*/ v.string(), 116 - time_us: /*#__PURE__*/ v.integer(), 117 - uri: /*#__PURE__*/ v.resourceUriString(), 118 - }); 119 - const _mainSchema = /*#__PURE__*/ v.query( 120 - "community.lexicon.calendar.event.listRecords", 121 - { 122 - params: /*#__PURE__*/ v.object({ 123 - /** 124 - * Filter by DID or handle (triggers on-demand backfill) 125 - */ 126 - actor: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.actorIdentifierString()), 127 - /** 128 - * Maximum value for createdAt 129 - */ 130 - createdAtMax: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 131 - /** 132 - * Minimum value for createdAt 133 - */ 134 - createdAtMin: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 135 - cursor: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 136 - /** 137 - * Filter by description 138 - */ 139 - description: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 140 - /** 141 - * Maximum value for endsAt 142 - */ 143 - endsAtMax: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 144 - /** 145 - * Minimum value for endsAt 146 - */ 147 - endsAtMin: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 148 - /** 149 - * Number of rsvps records to embed per record 150 - * @minimum 1 151 - * @maximum 50 152 - */ 153 - hydrateRsvps: /*#__PURE__*/ v.optional( 154 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.integer(), [ 155 - /*#__PURE__*/ v.integerRange(1, 50), 156 - ]), 157 - ), 158 - /** 159 - * @minimum 1 160 - * @maximum 200 161 - * @default 50 162 - */ 163 - limit: /*#__PURE__*/ v.optional( 164 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.integer(), [ 165 - /*#__PURE__*/ v.integerRange(1, 200), 166 - ]), 167 - 50, 168 - ), 169 - /** 170 - * Filter by mode 171 - */ 172 - mode: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 173 - /** 174 - * Filter by name 175 - */ 176 - name: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 177 - /** 178 - * Sort direction (default: desc for dates/numbers/counts, asc for strings) 179 - */ 180 - order: /*#__PURE__*/ v.optional( 181 - /*#__PURE__*/ v.string<"asc" | "desc" | (string & {})>(), 182 - ), 183 - /** 184 - * Include profile + identity info keyed by DID 185 - */ 186 - profiles: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.boolean()), 187 - /** 188 - * Minimum total rsvps count 189 - */ 190 - rsvpsCountMin: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 191 - /** 192 - * Minimum rsvps count where status = going 193 - */ 194 - rsvpsGoingCountMin: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 195 - /** 196 - * Minimum rsvps count where status = interested 197 - */ 198 - rsvpsInterestedCountMin: /*#__PURE__*/ v.optional( 199 - /*#__PURE__*/ v.integer(), 200 - ), 201 - /** 202 - * Minimum rsvps count where status = notgoing 203 - */ 204 - rsvpsNotgoingCountMin: /*#__PURE__*/ v.optional( 205 - /*#__PURE__*/ v.integer(), 206 - ), 207 - /** 208 - * Full-text search across: mode, name, status, description 209 - */ 210 - search: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 211 - /** 212 - * Field to sort by (default: time_us) 213 - */ 214 - sort: /*#__PURE__*/ v.optional( 215 - /*#__PURE__*/ v.string< 216 - | "createdAt" 217 - | "description" 218 - | "endsAt" 219 - | "mode" 220 - | "name" 221 - | "rsvpsCount" 222 - | "rsvpsGoingCount" 223 - | "rsvpsInterestedCount" 224 - | "rsvpsNotgoingCount" 225 - | "startsAt" 226 - | "status" 227 - | (string & {}) 228 - >(), 229 - ), 230 - /** 231 - * Maximum value for startsAt 232 - */ 233 - startsAtMax: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 234 - /** 235 - * Minimum value for startsAt 236 - */ 237 - startsAtMin: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 238 - /** 239 - * Filter by status 240 - */ 241 - status: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 242 - }), 243 - output: { 244 - type: "lex", 245 - schema: /*#__PURE__*/ v.object({ 246 - cursor: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 247 - get profiles() { 248 - return /*#__PURE__*/ v.optional( 249 - /*#__PURE__*/ v.array(profileEntrySchema), 250 - ); 251 - }, 252 - get records() { 253 - return /*#__PURE__*/ v.array(recordSchema); 254 - }, 255 - }), 256 - }, 257 - }, 258 - ); 259 - const _profileEntrySchema = /*#__PURE__*/ v.object({ 260 - $type: /*#__PURE__*/ v.optional( 261 - /*#__PURE__*/ v.literal( 262 - "community.lexicon.calendar.event.listRecords#profileEntry", 263 - ), 264 - ), 265 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 266 - collection: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.nsidString()), 267 - did: /*#__PURE__*/ v.didString(), 268 - handle: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 269 - get record() { 270 - return /*#__PURE__*/ v.optional(appBskyActorProfileSchema); 271 - }, 272 - rkey: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 273 - uri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 274 - }); 275 - const _recordSchema = /*#__PURE__*/ v.object({ 276 - $type: /*#__PURE__*/ v.optional( 277 - /*#__PURE__*/ v.literal( 278 - "community.lexicon.calendar.event.listRecords#record", 279 - ), 280 - ), 281 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 282 - collection: /*#__PURE__*/ v.nsidString(), 283 - did: /*#__PURE__*/ v.didString(), 284 - get record() { 285 - return /*#__PURE__*/ v.optional(CommunityLexiconCalendarEvent.mainSchema); 286 - }, 287 - rkey: /*#__PURE__*/ v.string(), 288 - get rsvps() { 289 - return /*#__PURE__*/ v.optional(hydrateRsvpsSchema); 290 - }, 291 - /** 292 - * Total rsvps count 293 - */ 294 - rsvpsCount: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 295 - /** 296 - * rsvps count where status = going 297 - */ 298 - rsvpsGoingCount: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 299 - /** 300 - * rsvps count where status = interested 301 - */ 302 - rsvpsInterestedCount: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 303 - /** 304 - * rsvps count where status = notgoing 305 - */ 306 - rsvpsNotgoingCount: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 307 - time_us: /*#__PURE__*/ v.integer(), 308 - uri: /*#__PURE__*/ v.resourceUriString(), 309 - }); 310 - 311 - type appBskyActorProfile$schematype = typeof _appBskyActorProfileSchema; 312 - type hydrateRsvps$schematype = typeof _hydrateRsvpsSchema; 313 - type hydrateRsvpsRecord$schematype = typeof _hydrateRsvpsRecordSchema; 314 - type main$schematype = typeof _mainSchema; 315 - type profileEntry$schematype = typeof _profileEntrySchema; 316 - type record$schematype = typeof _recordSchema; 317 - 318 - export interface appBskyActorProfileSchema extends appBskyActorProfile$schematype {} 319 - export interface hydrateRsvpsSchema extends hydrateRsvps$schematype {} 320 - export interface hydrateRsvpsRecordSchema extends hydrateRsvpsRecord$schematype {} 321 - export interface mainSchema extends main$schematype {} 322 - export interface profileEntrySchema extends profileEntry$schematype {} 323 - export interface recordSchema extends record$schematype {} 324 - 325 - export const appBskyActorProfileSchema = 326 - _appBskyActorProfileSchema as appBskyActorProfileSchema; 327 - export const hydrateRsvpsSchema = _hydrateRsvpsSchema as hydrateRsvpsSchema; 328 - export const hydrateRsvpsRecordSchema = 329 - _hydrateRsvpsRecordSchema as hydrateRsvpsRecordSchema; 330 - export const mainSchema = _mainSchema as mainSchema; 331 - export const profileEntrySchema = _profileEntrySchema as profileEntrySchema; 332 - export const recordSchema = _recordSchema as recordSchema; 333 - 334 - export interface AppBskyActorProfile extends v.InferInput< 335 - typeof appBskyActorProfileSchema 336 - > {} 337 - export interface HydrateRsvps extends v.InferInput<typeof hydrateRsvpsSchema> {} 338 - export interface HydrateRsvpsRecord extends v.InferInput< 339 - typeof hydrateRsvpsRecordSchema 340 - > {} 341 - export interface ProfileEntry extends v.InferInput<typeof profileEntrySchema> {} 342 - export interface Record extends v.InferInput<typeof recordSchema> {} 343 - 344 - export interface $params extends v.InferInput<mainSchema["params"]> {} 345 - export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {} 346 - 347 - declare module "@atcute/lexicons/ambient" { 348 - interface XRPCQueries { 349 - "community.lexicon.calendar.event.listRecords": mainSchema; 350 - } 351 - }
-184
src/lexicon-types/types/community/lexicon/calendar/rsvp/getRecord.ts
··· 1 - import type {} from "@atcute/lexicons"; 2 - import * as v from "@atcute/lexicons/validations"; 3 - import type {} from "@atcute/lexicons/ambient"; 4 - import * as ComAtprotoLabelDefs from "@atcute/atproto/types/label/defs"; 5 - import * as ComAtprotoRepoStrongRef from "@atcute/atproto/types/repo/strongRef"; 6 - import * as CommunityLexiconCalendarEvent from "../event.js"; 7 - import * as CommunityLexiconCalendarRsvp from "../rsvp.js"; 8 - 9 - const _appBskyActorProfileSchema = /*#__PURE__*/ v.object({ 10 - $type: /*#__PURE__*/ v.optional( 11 - /*#__PURE__*/ v.literal( 12 - "community.lexicon.calendar.rsvp.getRecord#appBskyActorProfile", 13 - ), 14 - ), 15 - /** 16 - * Small image to be displayed next to posts from account. AKA, 'profile picture' 17 - * @accept image/png, image/jpeg 18 - * @maxSize 1000000 19 - */ 20 - avatar: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.blob()), 21 - /** 22 - * Larger horizontal image to display behind profile view. 23 - * @accept image/png, image/jpeg 24 - * @maxSize 1000000 25 - */ 26 - banner: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.blob()), 27 - createdAt: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.datetimeString()), 28 - /** 29 - * Free-form profile description text. 30 - * @maxLength 2560 31 - * @maxGraphemes 256 32 - */ 33 - description: /*#__PURE__*/ v.optional( 34 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 35 - /*#__PURE__*/ v.stringLength(0, 2560), 36 - /*#__PURE__*/ v.stringGraphemes(0, 256), 37 - ]), 38 - ), 39 - /** 40 - * @maxLength 640 41 - * @maxGraphemes 64 42 - */ 43 - displayName: /*#__PURE__*/ v.optional( 44 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 45 - /*#__PURE__*/ v.stringLength(0, 640), 46 - /*#__PURE__*/ v.stringGraphemes(0, 64), 47 - ]), 48 - ), 49 - get joinedViaStarterPack() { 50 - return /*#__PURE__*/ v.optional(ComAtprotoRepoStrongRef.mainSchema); 51 - }, 52 - /** 53 - * Self-label values, specific to the Bluesky application, on the overall account. 54 - */ 55 - get labels() { 56 - return /*#__PURE__*/ v.optional( 57 - /*#__PURE__*/ v.variant([ComAtprotoLabelDefs.selfLabelsSchema]), 58 - ); 59 - }, 60 - get pinnedPost() { 61 - return /*#__PURE__*/ v.optional(ComAtprotoRepoStrongRef.mainSchema); 62 - }, 63 - /** 64 - * Free-form pronouns text. 65 - * @maxLength 200 66 - * @maxGraphemes 20 67 - */ 68 - pronouns: /*#__PURE__*/ v.optional( 69 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 70 - /*#__PURE__*/ v.stringLength(0, 200), 71 - /*#__PURE__*/ v.stringGraphemes(0, 20), 72 - ]), 73 - ), 74 - website: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.genericUriString()), 75 - }); 76 - const _mainSchema = /*#__PURE__*/ v.query( 77 - "community.lexicon.calendar.rsvp.getRecord", 78 - { 79 - params: /*#__PURE__*/ v.object({ 80 - /** 81 - * Embed the referenced event record 82 - */ 83 - hydrateEvent: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.boolean()), 84 - /** 85 - * Include profile + identity info keyed by DID 86 - */ 87 - profiles: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.boolean()), 88 - /** 89 - * AT URI of the record 90 - */ 91 - uri: /*#__PURE__*/ v.resourceUriString(), 92 - }), 93 - output: { 94 - type: "lex", 95 - schema: /*#__PURE__*/ v.object({ 96 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 97 - collection: /*#__PURE__*/ v.nsidString(), 98 - did: /*#__PURE__*/ v.didString(), 99 - get event() { 100 - return /*#__PURE__*/ v.optional(refEventRecordSchema); 101 - }, 102 - get profiles() { 103 - return /*#__PURE__*/ v.optional( 104 - /*#__PURE__*/ v.array(profileEntrySchema), 105 - ); 106 - }, 107 - get record() { 108 - return /*#__PURE__*/ v.optional( 109 - CommunityLexiconCalendarRsvp.mainSchema, 110 - ); 111 - }, 112 - rkey: /*#__PURE__*/ v.string(), 113 - time_us: /*#__PURE__*/ v.integer(), 114 - uri: /*#__PURE__*/ v.resourceUriString(), 115 - }), 116 - }, 117 - }, 118 - ); 119 - const _profileEntrySchema = /*#__PURE__*/ v.object({ 120 - $type: /*#__PURE__*/ v.optional( 121 - /*#__PURE__*/ v.literal( 122 - "community.lexicon.calendar.rsvp.getRecord#profileEntry", 123 - ), 124 - ), 125 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 126 - collection: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.nsidString()), 127 - did: /*#__PURE__*/ v.didString(), 128 - handle: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 129 - get record() { 130 - return /*#__PURE__*/ v.optional(appBskyActorProfileSchema); 131 - }, 132 - rkey: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 133 - uri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 134 - }); 135 - const _refEventRecordSchema = /*#__PURE__*/ v.object({ 136 - $type: /*#__PURE__*/ v.optional( 137 - /*#__PURE__*/ v.literal( 138 - "community.lexicon.calendar.rsvp.getRecord#refEventRecord", 139 - ), 140 - ), 141 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 142 - collection: /*#__PURE__*/ v.nsidString(), 143 - did: /*#__PURE__*/ v.didString(), 144 - get record() { 145 - return /*#__PURE__*/ v.optional(CommunityLexiconCalendarEvent.mainSchema); 146 - }, 147 - rkey: /*#__PURE__*/ v.string(), 148 - time_us: /*#__PURE__*/ v.integer(), 149 - uri: /*#__PURE__*/ v.resourceUriString(), 150 - }); 151 - 152 - type appBskyActorProfile$schematype = typeof _appBskyActorProfileSchema; 153 - type main$schematype = typeof _mainSchema; 154 - type profileEntry$schematype = typeof _profileEntrySchema; 155 - type refEventRecord$schematype = typeof _refEventRecordSchema; 156 - 157 - export interface appBskyActorProfileSchema extends appBskyActorProfile$schematype {} 158 - export interface mainSchema extends main$schematype {} 159 - export interface profileEntrySchema extends profileEntry$schematype {} 160 - export interface refEventRecordSchema extends refEventRecord$schematype {} 161 - 162 - export const appBskyActorProfileSchema = 163 - _appBskyActorProfileSchema as appBskyActorProfileSchema; 164 - export const mainSchema = _mainSchema as mainSchema; 165 - export const profileEntrySchema = _profileEntrySchema as profileEntrySchema; 166 - export const refEventRecordSchema = 167 - _refEventRecordSchema as refEventRecordSchema; 168 - 169 - export interface AppBskyActorProfile extends v.InferInput< 170 - typeof appBskyActorProfileSchema 171 - > {} 172 - export interface ProfileEntry extends v.InferInput<typeof profileEntrySchema> {} 173 - export interface RefEventRecord extends v.InferInput< 174 - typeof refEventRecordSchema 175 - > {} 176 - 177 - export interface $params extends v.InferInput<mainSchema["params"]> {} 178 - export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {} 179 - 180 - declare module "@atcute/lexicons/ambient" { 181 - interface XRPCQueries { 182 - "community.lexicon.calendar.rsvp.getRecord": mainSchema; 183 - } 184 - }
-229
src/lexicon-types/types/community/lexicon/calendar/rsvp/listRecords.ts
··· 1 - import type {} from "@atcute/lexicons"; 2 - import * as v from "@atcute/lexicons/validations"; 3 - import type {} from "@atcute/lexicons/ambient"; 4 - import * as ComAtprotoLabelDefs from "@atcute/atproto/types/label/defs"; 5 - import * as ComAtprotoRepoStrongRef from "@atcute/atproto/types/repo/strongRef"; 6 - import * as CommunityLexiconCalendarEvent from "../event.js"; 7 - import * as CommunityLexiconCalendarRsvp from "../rsvp.js"; 8 - 9 - const _appBskyActorProfileSchema = /*#__PURE__*/ v.object({ 10 - $type: /*#__PURE__*/ v.optional( 11 - /*#__PURE__*/ v.literal( 12 - "community.lexicon.calendar.rsvp.listRecords#appBskyActorProfile", 13 - ), 14 - ), 15 - /** 16 - * Small image to be displayed next to posts from account. AKA, 'profile picture' 17 - * @accept image/png, image/jpeg 18 - * @maxSize 1000000 19 - */ 20 - avatar: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.blob()), 21 - /** 22 - * Larger horizontal image to display behind profile view. 23 - * @accept image/png, image/jpeg 24 - * @maxSize 1000000 25 - */ 26 - banner: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.blob()), 27 - createdAt: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.datetimeString()), 28 - /** 29 - * Free-form profile description text. 30 - * @maxLength 2560 31 - * @maxGraphemes 256 32 - */ 33 - description: /*#__PURE__*/ v.optional( 34 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 35 - /*#__PURE__*/ v.stringLength(0, 2560), 36 - /*#__PURE__*/ v.stringGraphemes(0, 256), 37 - ]), 38 - ), 39 - /** 40 - * @maxLength 640 41 - * @maxGraphemes 64 42 - */ 43 - displayName: /*#__PURE__*/ v.optional( 44 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 45 - /*#__PURE__*/ v.stringLength(0, 640), 46 - /*#__PURE__*/ v.stringGraphemes(0, 64), 47 - ]), 48 - ), 49 - get joinedViaStarterPack() { 50 - return /*#__PURE__*/ v.optional(ComAtprotoRepoStrongRef.mainSchema); 51 - }, 52 - /** 53 - * Self-label values, specific to the Bluesky application, on the overall account. 54 - */ 55 - get labels() { 56 - return /*#__PURE__*/ v.optional( 57 - /*#__PURE__*/ v.variant([ComAtprotoLabelDefs.selfLabelsSchema]), 58 - ); 59 - }, 60 - get pinnedPost() { 61 - return /*#__PURE__*/ v.optional(ComAtprotoRepoStrongRef.mainSchema); 62 - }, 63 - /** 64 - * Free-form pronouns text. 65 - * @maxLength 200 66 - * @maxGraphemes 20 67 - */ 68 - pronouns: /*#__PURE__*/ v.optional( 69 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 70 - /*#__PURE__*/ v.stringLength(0, 200), 71 - /*#__PURE__*/ v.stringGraphemes(0, 20), 72 - ]), 73 - ), 74 - website: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.genericUriString()), 75 - }); 76 - const _mainSchema = /*#__PURE__*/ v.query( 77 - "community.lexicon.calendar.rsvp.listRecords", 78 - { 79 - params: /*#__PURE__*/ v.object({ 80 - /** 81 - * Filter by DID or handle (triggers on-demand backfill) 82 - */ 83 - actor: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.actorIdentifierString()), 84 - cursor: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 85 - /** 86 - * Embed the referenced event record 87 - */ 88 - hydrateEvent: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.boolean()), 89 - /** 90 - * @minimum 1 91 - * @maximum 200 92 - * @default 50 93 - */ 94 - limit: /*#__PURE__*/ v.optional( 95 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.integer(), [ 96 - /*#__PURE__*/ v.integerRange(1, 200), 97 - ]), 98 - 50, 99 - ), 100 - /** 101 - * Sort direction (default: desc for dates/numbers/counts, asc for strings) 102 - */ 103 - order: /*#__PURE__*/ v.optional( 104 - /*#__PURE__*/ v.string<"asc" | "desc" | (string & {})>(), 105 - ), 106 - /** 107 - * Include profile + identity info keyed by DID 108 - */ 109 - profiles: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.boolean()), 110 - /** 111 - * Field to sort by (default: time_us) 112 - */ 113 - sort: /*#__PURE__*/ v.optional( 114 - /*#__PURE__*/ v.string<"status" | "subjectUri" | (string & {})>(), 115 - ), 116 - /** 117 - * Filter by status 118 - */ 119 - status: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 120 - /** 121 - * Filter by subject.uri 122 - */ 123 - subjectUri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 124 - }), 125 - output: { 126 - type: "lex", 127 - schema: /*#__PURE__*/ v.object({ 128 - cursor: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 129 - get profiles() { 130 - return /*#__PURE__*/ v.optional( 131 - /*#__PURE__*/ v.array(profileEntrySchema), 132 - ); 133 - }, 134 - get records() { 135 - return /*#__PURE__*/ v.array(recordSchema); 136 - }, 137 - }), 138 - }, 139 - }, 140 - ); 141 - const _profileEntrySchema = /*#__PURE__*/ v.object({ 142 - $type: /*#__PURE__*/ v.optional( 143 - /*#__PURE__*/ v.literal( 144 - "community.lexicon.calendar.rsvp.listRecords#profileEntry", 145 - ), 146 - ), 147 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 148 - collection: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.nsidString()), 149 - did: /*#__PURE__*/ v.didString(), 150 - handle: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 151 - get record() { 152 - return /*#__PURE__*/ v.optional(appBskyActorProfileSchema); 153 - }, 154 - rkey: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 155 - uri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 156 - }); 157 - const _recordSchema = /*#__PURE__*/ v.object({ 158 - $type: /*#__PURE__*/ v.optional( 159 - /*#__PURE__*/ v.literal( 160 - "community.lexicon.calendar.rsvp.listRecords#record", 161 - ), 162 - ), 163 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 164 - collection: /*#__PURE__*/ v.nsidString(), 165 - did: /*#__PURE__*/ v.didString(), 166 - get event() { 167 - return /*#__PURE__*/ v.optional(refEventRecordSchema); 168 - }, 169 - get record() { 170 - return /*#__PURE__*/ v.optional(CommunityLexiconCalendarRsvp.mainSchema); 171 - }, 172 - rkey: /*#__PURE__*/ v.string(), 173 - time_us: /*#__PURE__*/ v.integer(), 174 - uri: /*#__PURE__*/ v.resourceUriString(), 175 - }); 176 - const _refEventRecordSchema = /*#__PURE__*/ v.object({ 177 - $type: /*#__PURE__*/ v.optional( 178 - /*#__PURE__*/ v.literal( 179 - "community.lexicon.calendar.rsvp.listRecords#refEventRecord", 180 - ), 181 - ), 182 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 183 - collection: /*#__PURE__*/ v.nsidString(), 184 - did: /*#__PURE__*/ v.didString(), 185 - get record() { 186 - return /*#__PURE__*/ v.optional(CommunityLexiconCalendarEvent.mainSchema); 187 - }, 188 - rkey: /*#__PURE__*/ v.string(), 189 - time_us: /*#__PURE__*/ v.integer(), 190 - uri: /*#__PURE__*/ v.resourceUriString(), 191 - }); 192 - 193 - type appBskyActorProfile$schematype = typeof _appBskyActorProfileSchema; 194 - type main$schematype = typeof _mainSchema; 195 - type profileEntry$schematype = typeof _profileEntrySchema; 196 - type record$schematype = typeof _recordSchema; 197 - type refEventRecord$schematype = typeof _refEventRecordSchema; 198 - 199 - export interface appBskyActorProfileSchema extends appBskyActorProfile$schematype {} 200 - export interface mainSchema extends main$schematype {} 201 - export interface profileEntrySchema extends profileEntry$schematype {} 202 - export interface recordSchema extends record$schematype {} 203 - export interface refEventRecordSchema extends refEventRecord$schematype {} 204 - 205 - export const appBskyActorProfileSchema = 206 - _appBskyActorProfileSchema as appBskyActorProfileSchema; 207 - export const mainSchema = _mainSchema as mainSchema; 208 - export const profileEntrySchema = _profileEntrySchema as profileEntrySchema; 209 - export const recordSchema = _recordSchema as recordSchema; 210 - export const refEventRecordSchema = 211 - _refEventRecordSchema as refEventRecordSchema; 212 - 213 - export interface AppBskyActorProfile extends v.InferInput< 214 - typeof appBskyActorProfileSchema 215 - > {} 216 - export interface ProfileEntry extends v.InferInput<typeof profileEntrySchema> {} 217 - export interface Record extends v.InferInput<typeof recordSchema> {} 218 - export interface RefEventRecord extends v.InferInput< 219 - typeof refEventRecordSchema 220 - > {} 221 - 222 - export interface $params extends v.InferInput<mainSchema["params"]> {} 223 - export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {} 224 - 225 - declare module "@atcute/lexicons/ambient" { 226 - interface XRPCQueries { 227 - "community.lexicon.calendar.rsvp.listRecords": mainSchema; 228 - } 229 - }
-30
src/lexicon-types/types/rsvp/atmo/admin/getCursor.ts
··· 1 - import type {} from "@atcute/lexicons"; 2 - import * as v from "@atcute/lexicons/validations"; 3 - import type {} from "@atcute/lexicons/ambient"; 4 - 5 - const _mainSchema = /*#__PURE__*/ v.query("rsvp.atmo.admin.getCursor", { 6 - params: null, 7 - output: { 8 - type: "lex", 9 - schema: /*#__PURE__*/ v.object({ 10 - date: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 11 - seconds_ago: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 12 - time_us: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 13 - }), 14 - }, 15 - }); 16 - 17 - type main$schematype = typeof _mainSchema; 18 - 19 - export interface mainSchema extends main$schematype {} 20 - 21 - export const mainSchema = _mainSchema as mainSchema; 22 - 23 - export interface $params {} 24 - export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {} 25 - 26 - declare module "@atcute/lexicons/ambient" { 27 - interface XRPCQueries { 28 - "rsvp.atmo.admin.getCursor": mainSchema; 29 - } 30 - }
-47
src/lexicon-types/types/rsvp/atmo/admin/getOverview.ts
··· 1 - import type {} from "@atcute/lexicons"; 2 - import * as v from "@atcute/lexicons/validations"; 3 - import type {} from "@atcute/lexicons/ambient"; 4 - 5 - const _collectionStatsSchema = /*#__PURE__*/ v.object({ 6 - $type: /*#__PURE__*/ v.optional( 7 - /*#__PURE__*/ v.literal("rsvp.atmo.admin.getOverview#collectionStats"), 8 - ), 9 - collection: /*#__PURE__*/ v.string(), 10 - records: /*#__PURE__*/ v.integer(), 11 - unique_users: /*#__PURE__*/ v.integer(), 12 - }); 13 - const _mainSchema = /*#__PURE__*/ v.query("rsvp.atmo.admin.getOverview", { 14 - params: null, 15 - output: { 16 - type: "lex", 17 - schema: /*#__PURE__*/ v.object({ 18 - get collections() { 19 - return /*#__PURE__*/ v.array(collectionStatsSchema); 20 - }, 21 - total_records: /*#__PURE__*/ v.integer(), 22 - }), 23 - }, 24 - }); 25 - 26 - type collectionStats$schematype = typeof _collectionStatsSchema; 27 - type main$schematype = typeof _mainSchema; 28 - 29 - export interface collectionStatsSchema extends collectionStats$schematype {} 30 - export interface mainSchema extends main$schematype {} 31 - 32 - export const collectionStatsSchema = 33 - _collectionStatsSchema as collectionStatsSchema; 34 - export const mainSchema = _mainSchema as mainSchema; 35 - 36 - export interface CollectionStats extends v.InferInput< 37 - typeof collectionStatsSchema 38 - > {} 39 - 40 - export interface $params {} 41 - export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {} 42 - 43 - declare module "@atcute/lexicons/ambient" { 44 - interface XRPCQueries { 45 - "rsvp.atmo.admin.getOverview": mainSchema; 46 - } 47 - }
-28
src/lexicon-types/types/rsvp/atmo/admin/reset.ts
··· 1 - import type {} from "@atcute/lexicons"; 2 - import * as v from "@atcute/lexicons/validations"; 3 - import type {} from "@atcute/lexicons/ambient"; 4 - 5 - const _mainSchema = /*#__PURE__*/ v.query("rsvp.atmo.admin.reset", { 6 - params: null, 7 - output: { 8 - type: "lex", 9 - schema: /*#__PURE__*/ v.object({ 10 - ok: /*#__PURE__*/ v.boolean(), 11 - }), 12 - }, 13 - }); 14 - 15 - type main$schematype = typeof _mainSchema; 16 - 17 - export interface mainSchema extends main$schematype {} 18 - 19 - export const mainSchema = _mainSchema as mainSchema; 20 - 21 - export interface $params {} 22 - export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {} 23 - 24 - declare module "@atcute/lexicons/ambient" { 25 - interface XRPCQueries { 26 - "rsvp.atmo.admin.reset": mainSchema; 27 - } 28 - }
-43
src/lexicon-types/types/rsvp/atmo/admin/sync.ts
··· 1 - import type {} from "@atcute/lexicons"; 2 - import * as v from "@atcute/lexicons/validations"; 3 - import type {} from "@atcute/lexicons/ambient"; 4 - 5 - const _mainSchema = /*#__PURE__*/ v.query("rsvp.atmo.admin.sync", { 6 - params: /*#__PURE__*/ v.object({ 7 - /** 8 - * @minimum 1 9 - * @maximum 50 10 - * @default 10 11 - */ 12 - concurrency: /*#__PURE__*/ v.optional( 13 - /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.integer(), [ 14 - /*#__PURE__*/ v.integerRange(1, 50), 15 - ]), 16 - 10, 17 - ), 18 - }), 19 - output: { 20 - type: "lex", 21 - schema: /*#__PURE__*/ v.object({ 22 - backfilled: /*#__PURE__*/ v.integer(), 23 - discovered: /*#__PURE__*/ v.integer(), 24 - done: /*#__PURE__*/ v.boolean(), 25 - remaining: /*#__PURE__*/ v.integer(), 26 - }), 27 - }, 28 - }); 29 - 30 - type main$schematype = typeof _mainSchema; 31 - 32 - export interface mainSchema extends main$schematype {} 33 - 34 - export const mainSchema = _mainSchema as mainSchema; 35 - 36 - export interface $params extends v.InferInput<mainSchema["params"]> {} 37 - export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {} 38 - 39 - declare module "@atcute/lexicons/ambient" { 40 - interface XRPCQueries { 41 - "rsvp.atmo.admin.sync": mainSchema; 42 - } 43 - }
+14 -16
src/lexicon-types/types/rsvp/atmo/event/getRecord.ts
··· 108 108 }, 109 109 rkey: /*#__PURE__*/ v.string(), 110 110 /** 111 - * Present when the record was read from a permissioned space. 111 + * Present when the record was read from a permissioned space; `ats://` URI. 112 112 */ 113 - space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 113 + space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 114 114 time_us: /*#__PURE__*/ v.integer(), 115 115 uri: /*#__PURE__*/ v.resourceUriString(), 116 116 }); ··· 135 135 */ 136 136 profiles: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.boolean()), 137 137 /** 138 - * If set, fetch from this permissioned space (requires service-auth JWT or a read-grant invite token). 138 + * If set, fetch from this permissioned space (requires service-auth JWT or a read-grant invite token). `ats://` URI. 139 139 */ 140 - spaceUri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 140 + spaceUri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 141 141 /** 142 142 * AT URI of the record 143 143 */ ··· 146 146 output: { 147 147 type: "lex", 148 148 schema: /*#__PURE__*/ v.object({ 149 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 149 + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), 150 150 collection: /*#__PURE__*/ v.nsidString(), 151 151 did: /*#__PURE__*/ v.didString(), 152 152 get profiles() { 153 153 return /*#__PURE__*/ v.optional( 154 154 /*#__PURE__*/ v.array(profileEntrySchema), 155 - ); 156 - }, 157 - get record() { 158 - return /*#__PURE__*/ v.optional( 159 - CommunityLexiconCalendarEvent.mainSchema, 160 155 ); 161 156 }, 162 157 rkey: /*#__PURE__*/ v.string(), ··· 180 175 */ 181 176 rsvpsNotgoingCount: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 182 177 /** 183 - * Present when the record was read from a permissioned space; its value is the space URI. 178 + * Present when the record was read from a permissioned space; its value is the `ats://` space URI. 184 179 */ 185 - space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 180 + space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 186 181 time_us: /*#__PURE__*/ v.integer(), 187 182 uri: /*#__PURE__*/ v.resourceUriString(), 183 + get value() { 184 + return CommunityLexiconCalendarEvent.mainSchema; 185 + }, 188 186 }), 189 187 }, 190 188 }); ··· 192 190 $type: /*#__PURE__*/ v.optional( 193 191 /*#__PURE__*/ v.literal("rsvp.atmo.event.getRecord#profileEntry"), 194 192 ), 195 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 193 + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), 196 194 collection: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.nsidString()), 197 195 did: /*#__PURE__*/ v.didString(), 198 196 handle: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 199 - get record() { 197 + rkey: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 198 + uri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 199 + get value() { 200 200 return /*#__PURE__*/ v.optional(appBskyActorProfileSchema); 201 201 }, 202 - rkey: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 203 - uri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 204 202 }); 205 203 206 204 type appBskyActorProfile$schematype = typeof _appBskyActorProfileSchema;
+14 -14
src/lexicon-types/types/rsvp/atmo/event/listRecords.ts
··· 108 108 }, 109 109 rkey: /*#__PURE__*/ v.string(), 110 110 /** 111 - * Present when the record was read from a permissioned space. 111 + * Present when the record was read from a permissioned space; `ats://` URI. 112 112 */ 113 - space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 113 + space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 114 114 time_us: /*#__PURE__*/ v.integer(), 115 115 uri: /*#__PURE__*/ v.resourceUriString(), 116 116 }); ··· 237 237 >(), 238 238 ), 239 239 /** 240 - * If set, query records inside this permissioned space (requires service-auth JWT or a read-grant invite token). 240 + * If set, query records inside this permissioned space (requires service-auth JWT or a read-grant invite token). `ats://` URI. 241 241 */ 242 - spaceUri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 242 + spaceUri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 243 243 /** 244 244 * Maximum value for startsAt 245 245 */ ··· 272 272 $type: /*#__PURE__*/ v.optional( 273 273 /*#__PURE__*/ v.literal("rsvp.atmo.event.listRecords#profileEntry"), 274 274 ), 275 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 275 + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), 276 276 collection: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.nsidString()), 277 277 did: /*#__PURE__*/ v.didString(), 278 278 handle: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 279 - get record() { 280 - return /*#__PURE__*/ v.optional(appBskyActorProfileSchema); 281 - }, 282 279 rkey: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 283 280 uri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 281 + get value() { 282 + return /*#__PURE__*/ v.optional(appBskyActorProfileSchema); 283 + }, 284 284 }); 285 285 const _recordSchema = /*#__PURE__*/ v.object({ 286 286 $type: /*#__PURE__*/ v.optional( 287 287 /*#__PURE__*/ v.literal("rsvp.atmo.event.listRecords#record"), 288 288 ), 289 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 289 + cid: /*#__PURE__*/ v.cidString(), 290 290 collection: /*#__PURE__*/ v.nsidString(), 291 291 did: /*#__PURE__*/ v.didString(), 292 - get record() { 293 - return /*#__PURE__*/ v.optional(CommunityLexiconCalendarEvent.mainSchema); 294 - }, 295 292 rkey: /*#__PURE__*/ v.string(), 296 293 get rsvps() { 297 294 return /*#__PURE__*/ v.optional(hydrateRsvpsSchema); ··· 313 310 */ 314 311 rsvpsNotgoingCount: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 315 312 /** 316 - * Present when the record was read from a permissioned space; its value is the space URI. 313 + * Present when the record was read from a permissioned space; its value is the `ats://` space URI. 317 314 */ 318 - space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 315 + space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 319 316 time_us: /*#__PURE__*/ v.integer(), 320 317 uri: /*#__PURE__*/ v.resourceUriString(), 318 + get value() { 319 + return CommunityLexiconCalendarEvent.mainSchema; 320 + }, 321 321 }); 322 322 323 323 type appBskyActorProfile$schematype = typeof _appBskyActorProfileSchema;
+4 -4
src/lexicon-types/types/rsvp/atmo/getProfile.ts
··· 89 89 $type: /*#__PURE__*/ v.optional( 90 90 /*#__PURE__*/ v.literal("rsvp.atmo.getProfile#profileEntry"), 91 91 ), 92 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 92 + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), 93 93 collection: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.nsidString()), 94 94 did: /*#__PURE__*/ v.didString(), 95 95 handle: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 96 - get record() { 97 - return /*#__PURE__*/ v.optional(appBskyActorProfileSchema); 98 - }, 99 96 rkey: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 100 97 uri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 98 + get value() { 99 + return /*#__PURE__*/ v.optional(appBskyActorProfileSchema); 100 + }, 101 101 }); 102 102 103 103 type appBskyActorProfile$schematype = typeof _appBskyActorProfileSchema;
+65
src/lexicon-types/types/rsvp/atmo/invite/defs.ts
··· 1 + import type {} from "@atcute/lexicons"; 2 + import * as v from "@atcute/lexicons/validations"; 3 + 4 + const _inviteViewSchema = /*#__PURE__*/ v.object({ 5 + $type: /*#__PURE__*/ v.optional( 6 + /*#__PURE__*/ v.literal("rsvp.atmo.invite.defs#inviteView"), 7 + ), 8 + /** 9 + * Set for community-owned spaces. Absent for user-owned. 10 + */ 11 + accessLevel: /*#__PURE__*/ v.optional( 12 + /*#__PURE__*/ v.string< 13 + "admin" | "manager" | "member" | "owner" | (string & {}) 14 + >(), 15 + ), 16 + /** 17 + * Unix ms. 18 + */ 19 + createdAt: /*#__PURE__*/ v.integer(), 20 + createdBy: /*#__PURE__*/ v.didString(), 21 + /** 22 + * Unix ms. Omitted for no expiry. 23 + */ 24 + expiresAt: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 25 + /** 26 + * Set for user-owned spaces. Absent for community-owned. 27 + */ 28 + kind: /*#__PURE__*/ v.optional( 29 + /*#__PURE__*/ v.string<"join" | "read" | "read-join" | (string & {})>(), 30 + ), 31 + /** 32 + * @minimum 1 33 + */ 34 + maxUses: /*#__PURE__*/ v.optional( 35 + /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.integer(), [ 36 + /*#__PURE__*/ v.integerRange(1), 37 + ]), 38 + ), 39 + /** 40 + * @maxLength 500 41 + */ 42 + note: /*#__PURE__*/ v.optional( 43 + /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 44 + /*#__PURE__*/ v.stringLength(0, 500), 45 + ]), 46 + ), 47 + /** 48 + * Unix ms. Omitted if not revoked. 49 + */ 50 + revokedAt: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 51 + spaceUri: /*#__PURE__*/ v.string(), 52 + /** 53 + * Stable identifier for list/revoke operations. 54 + */ 55 + tokenHash: /*#__PURE__*/ v.string(), 56 + usedCount: /*#__PURE__*/ v.integer(), 57 + }); 58 + 59 + type inviteView$schematype = typeof _inviteViewSchema; 60 + 61 + export interface inviteViewSchema extends inviteView$schematype {} 62 + 63 + export const inviteViewSchema = _inviteViewSchema as inviteViewSchema; 64 + 65 + export interface InviteView extends v.InferInput<typeof inviteViewSchema> {}
+47
src/lexicon-types/types/rsvp/atmo/invite/redeem.ts
··· 1 + import type {} from "@atcute/lexicons"; 2 + import * as v from "@atcute/lexicons/validations"; 3 + import type {} from "@atcute/lexicons/ambient"; 4 + 5 + const _mainSchema = /*#__PURE__*/ v.procedure("rsvp.atmo.invite.redeem", { 6 + params: null, 7 + input: { 8 + type: "lex", 9 + schema: /*#__PURE__*/ v.object({ 10 + token: /*#__PURE__*/ v.string(), 11 + }), 12 + }, 13 + output: { 14 + type: "lex", 15 + schema: /*#__PURE__*/ v.object({ 16 + /** 17 + * Set for community-owned spaces — the level granted. 18 + */ 19 + accessLevel: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 20 + /** 21 + * Set for community-owned spaces. 22 + */ 23 + communityDid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.didString()), 24 + /** 25 + * Set for user-owned spaces — echoes the invite kind consumed. 26 + */ 27 + kind: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 28 + spaceUri: /*#__PURE__*/ v.string(), 29 + }), 30 + }, 31 + }); 32 + 33 + type main$schematype = typeof _mainSchema; 34 + 35 + export interface mainSchema extends main$schematype {} 36 + 37 + export const mainSchema = _mainSchema as mainSchema; 38 + 39 + export interface $params {} 40 + export interface $input extends v.InferXRPCBodyInput<mainSchema["input"]> {} 41 + export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {} 42 + 43 + declare module "@atcute/lexicons/ambient" { 44 + interface XRPCProcedures { 45 + "rsvp.atmo.invite.redeem": mainSchema; 46 + } 47 + }
+14 -16
src/lexicon-types/types/rsvp/atmo/rsvp/getRecord.ts
··· 86 86 */ 87 87 profiles: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.boolean()), 88 88 /** 89 - * If set, fetch from this permissioned space (requires service-auth JWT or a read-grant invite token). 89 + * If set, fetch from this permissioned space (requires service-auth JWT or a read-grant invite token). `ats://` URI. 90 90 */ 91 - spaceUri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 91 + spaceUri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 92 92 /** 93 93 * AT URI of the record 94 94 */ ··· 97 97 output: { 98 98 type: "lex", 99 99 schema: /*#__PURE__*/ v.object({ 100 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 100 + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), 101 101 collection: /*#__PURE__*/ v.nsidString(), 102 102 did: /*#__PURE__*/ v.didString(), 103 103 get event() { ··· 108 108 /*#__PURE__*/ v.array(profileEntrySchema), 109 109 ); 110 110 }, 111 - get record() { 112 - return /*#__PURE__*/ v.optional( 113 - CommunityLexiconCalendarRsvp.mainSchema, 114 - ); 115 - }, 116 111 rkey: /*#__PURE__*/ v.string(), 117 112 /** 118 - * Present when the record was read from a permissioned space; its value is the space URI. 113 + * Present when the record was read from a permissioned space; its value is the `ats://` space URI. 119 114 */ 120 - space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 115 + space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 121 116 time_us: /*#__PURE__*/ v.integer(), 122 117 uri: /*#__PURE__*/ v.resourceUriString(), 118 + get value() { 119 + return CommunityLexiconCalendarRsvp.mainSchema; 120 + }, 123 121 }), 124 122 }, 125 123 }); ··· 127 125 $type: /*#__PURE__*/ v.optional( 128 126 /*#__PURE__*/ v.literal("rsvp.atmo.rsvp.getRecord#profileEntry"), 129 127 ), 130 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 128 + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), 131 129 collection: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.nsidString()), 132 130 did: /*#__PURE__*/ v.didString(), 133 131 handle: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 134 - get record() { 132 + rkey: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 133 + uri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 134 + get value() { 135 135 return /*#__PURE__*/ v.optional(appBskyActorProfileSchema); 136 136 }, 137 - rkey: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 138 - uri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 139 137 }); 140 138 const _refEventRecordSchema = /*#__PURE__*/ v.object({ 141 139 $type: /*#__PURE__*/ v.optional( ··· 149 147 }, 150 148 rkey: /*#__PURE__*/ v.string(), 151 149 /** 152 - * Present when the record was read from a permissioned space. 150 + * Present when the record was read from a permissioned space; `ats://` URI. 153 151 */ 154 - space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 152 + space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 155 153 time_us: /*#__PURE__*/ v.integer(), 156 154 uri: /*#__PURE__*/ v.resourceUriString(), 157 155 });
+25 -15
src/lexicon-types/types/rsvp/atmo/rsvp/listRecords.ts
··· 81 81 * Only used with spaceUri — filter to records authored by this DID. 82 82 */ 83 83 byUser: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.didString()), 84 + /** 85 + * Maximum value for createdAt 86 + */ 87 + createdAtMax: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 88 + /** 89 + * Minimum value for createdAt 90 + */ 91 + createdAtMin: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 84 92 cursor: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 85 93 /** 86 94 * Embed the referenced event record ··· 115 123 * Field to sort by (default: time_us) 116 124 */ 117 125 sort: /*#__PURE__*/ v.optional( 118 - /*#__PURE__*/ v.string<"status" | "subjectUri" | (string & {})>(), 126 + /*#__PURE__*/ v.string< 127 + "createdAt" | "status" | "subjectUri" | (string & {}) 128 + >(), 119 129 ), 120 130 /** 121 - * If set, query records inside this permissioned space (requires service-auth JWT or a read-grant invite token). 131 + * If set, query records inside this permissioned space (requires service-auth JWT or a read-grant invite token). `ats://` URI. 122 132 */ 123 - spaceUri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 133 + spaceUri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 124 134 /** 125 135 * Filter by status 126 136 */ ··· 149 159 $type: /*#__PURE__*/ v.optional( 150 160 /*#__PURE__*/ v.literal("rsvp.atmo.rsvp.listRecords#profileEntry"), 151 161 ), 152 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 162 + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), 153 163 collection: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.nsidString()), 154 164 did: /*#__PURE__*/ v.didString(), 155 165 handle: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 156 - get record() { 157 - return /*#__PURE__*/ v.optional(appBskyActorProfileSchema); 158 - }, 159 166 rkey: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 160 167 uri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 168 + get value() { 169 + return /*#__PURE__*/ v.optional(appBskyActorProfileSchema); 170 + }, 161 171 }); 162 172 const _recordSchema = /*#__PURE__*/ v.object({ 163 173 $type: /*#__PURE__*/ v.optional( 164 174 /*#__PURE__*/ v.literal("rsvp.atmo.rsvp.listRecords#record"), 165 175 ), 166 - cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 176 + cid: /*#__PURE__*/ v.cidString(), 167 177 collection: /*#__PURE__*/ v.nsidString(), 168 178 did: /*#__PURE__*/ v.didString(), 169 179 get event() { 170 180 return /*#__PURE__*/ v.optional(refEventRecordSchema); 171 181 }, 172 - get record() { 173 - return /*#__PURE__*/ v.optional(CommunityLexiconCalendarRsvp.mainSchema); 174 - }, 175 182 rkey: /*#__PURE__*/ v.string(), 176 183 /** 177 - * Present when the record was read from a permissioned space; its value is the space URI. 184 + * Present when the record was read from a permissioned space; its value is the `ats://` space URI. 178 185 */ 179 - space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 186 + space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 180 187 time_us: /*#__PURE__*/ v.integer(), 181 188 uri: /*#__PURE__*/ v.resourceUriString(), 189 + get value() { 190 + return CommunityLexiconCalendarRsvp.mainSchema; 191 + }, 182 192 }); 183 193 const _refEventRecordSchema = /*#__PURE__*/ v.object({ 184 194 $type: /*#__PURE__*/ v.optional( ··· 192 202 }, 193 203 rkey: /*#__PURE__*/ v.string(), 194 204 /** 195 - * Present when the record was read from a permissioned space. 205 + * Present when the record was read from a permissioned space; `ats://` URI. 196 206 */ 197 - space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 207 + space: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 198 208 time_us: /*#__PURE__*/ v.integer(), 199 209 uri: /*#__PURE__*/ v.resourceUriString(), 200 210 });
+1 -8
src/lexicon-types/types/rsvp/atmo/space/addMember.ts
··· 8 8 type: "lex", 9 9 schema: /*#__PURE__*/ v.object({ 10 10 did: /*#__PURE__*/ v.didString(), 11 - /** 12 - * @default "write" 13 - */ 14 - perms: /*#__PURE__*/ v.optional( 15 - /*#__PURE__*/ v.string<"read" | "write" | (string & {})>(), 16 - "write", 17 - ), 18 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 11 + spaceUri: /*#__PURE__*/ v.string(), 19 12 }), 20 13 }, 21 14 output: {
-3
src/lexicon-types/types/rsvp/atmo/space/createSpace.ts
··· 18 18 * Space key. Auto-generated (TID) if omitted. 19 19 */ 20 20 key: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 21 - memberListRef: /*#__PURE__*/ v.optional( 22 - /*#__PURE__*/ v.resourceUriString(), 23 - ), 24 21 /** 25 22 * Space type NSID. Defaults to the service's configured type. 26 23 */
+17 -9
src/lexicon-types/types/rsvp/atmo/space/defs.ts
··· 11 11 */ 12 12 mode: /*#__PURE__*/ v.string<"allow" | "deny" | (string & {})>(), 13 13 }); 14 + const _blobInfoSchema = /*#__PURE__*/ v.object({ 15 + $type: /*#__PURE__*/ v.optional( 16 + /*#__PURE__*/ v.literal("rsvp.atmo.space.defs#blobInfo"), 17 + ), 18 + authorDid: /*#__PURE__*/ v.didString(), 19 + cid: /*#__PURE__*/ v.cidString(), 20 + createdAt: /*#__PURE__*/ v.integer(), 21 + mimeType: /*#__PURE__*/ v.string(), 22 + size: /*#__PURE__*/ v.integer(), 23 + }); 14 24 const _inviteViewSchema = /*#__PURE__*/ v.object({ 15 25 $type: /*#__PURE__*/ v.optional( 16 26 /*#__PURE__*/ v.literal("rsvp.atmo.space.defs#inviteView"), ··· 21 31 kind: /*#__PURE__*/ v.string<"join" | "read" | "read-join" | (string & {})>(), 22 32 maxUses: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 23 33 note: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 24 - perms: /*#__PURE__*/ v.string<"read" | "write" | (string & {})>(), 25 34 revokedAt: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 26 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 35 + spaceUri: /*#__PURE__*/ v.string(), 27 36 tokenHash: /*#__PURE__*/ v.string(), 28 37 usedCount: /*#__PURE__*/ v.integer(), 29 38 }); ··· 34 43 addedAt: /*#__PURE__*/ v.integer(), 35 44 addedBy: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.didString()), 36 45 did: /*#__PURE__*/ v.didString(), 37 - /** 38 - * 'write' implies 'read'. Space owner is always implicit write. 39 - */ 40 - perms: /*#__PURE__*/ v.string<"read" | "write" | (string & {})>(), 41 46 }); 42 47 const _recordViewSchema = /*#__PURE__*/ v.object({ 43 48 $type: /*#__PURE__*/ v.optional( ··· 49 54 createdAt: /*#__PURE__*/ v.integer(), 50 55 record: /*#__PURE__*/ v.unknown(), 51 56 rkey: /*#__PURE__*/ v.string(), 52 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 57 + spaceUri: /*#__PURE__*/ v.string(), 53 58 }); 54 59 const _spaceViewSchema = /*#__PURE__*/ v.object({ 55 60 $type: /*#__PURE__*/ v.optional( ··· 64 69 appPolicyRef: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 65 70 createdAt: /*#__PURE__*/ v.integer(), 66 71 key: /*#__PURE__*/ v.string(), 67 - memberListRef: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.resourceUriString()), 68 72 ownerDid: /*#__PURE__*/ v.didString(), 69 73 serviceDid: /*#__PURE__*/ v.string(), 70 74 type: /*#__PURE__*/ v.nsidString(), 71 - uri: /*#__PURE__*/ v.resourceUriString(), 75 + uri: /*#__PURE__*/ v.string(), 72 76 }); 73 77 74 78 type appPolicy$schematype = typeof _appPolicySchema; 79 + type blobInfo$schematype = typeof _blobInfoSchema; 75 80 type inviteView$schematype = typeof _inviteViewSchema; 76 81 type memberView$schematype = typeof _memberViewSchema; 77 82 type recordView$schematype = typeof _recordViewSchema; 78 83 type spaceView$schematype = typeof _spaceViewSchema; 79 84 80 85 export interface appPolicySchema extends appPolicy$schematype {} 86 + export interface blobInfoSchema extends blobInfo$schematype {} 81 87 export interface inviteViewSchema extends inviteView$schematype {} 82 88 export interface memberViewSchema extends memberView$schematype {} 83 89 export interface recordViewSchema extends recordView$schematype {} 84 90 export interface spaceViewSchema extends spaceView$schematype {} 85 91 86 92 export const appPolicySchema = _appPolicySchema as appPolicySchema; 93 + export const blobInfoSchema = _blobInfoSchema as blobInfoSchema; 87 94 export const inviteViewSchema = _inviteViewSchema as inviteViewSchema; 88 95 export const memberViewSchema = _memberViewSchema as memberViewSchema; 89 96 export const recordViewSchema = _recordViewSchema as recordViewSchema; 90 97 export const spaceViewSchema = _spaceViewSchema as spaceViewSchema; 91 98 92 99 export interface AppPolicy extends v.InferInput<typeof appPolicySchema> {} 100 + export interface BlobInfo extends v.InferInput<typeof blobInfoSchema> {} 93 101 export interface InviteView extends v.InferInput<typeof inviteViewSchema> {} 94 102 export interface MemberView extends v.InferInput<typeof memberViewSchema> {} 95 103 export interface RecordView extends v.InferInput<typeof recordViewSchema> {}
+1 -1
src/lexicon-types/types/rsvp/atmo/space/deleteRecord.ts
··· 9 9 schema: /*#__PURE__*/ v.object({ 10 10 collection: /*#__PURE__*/ v.nsidString(), 11 11 rkey: /*#__PURE__*/ v.string(), 12 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 12 + spaceUri: /*#__PURE__*/ v.string(), 13 13 }), 14 14 }, 15 15 output: {
+32
src/lexicon-types/types/rsvp/atmo/space/getBlob.ts
··· 1 + import type {} from "@atcute/lexicons"; 2 + import * as v from "@atcute/lexicons/validations"; 3 + import type {} from "@atcute/lexicons/ambient"; 4 + 5 + const _mainSchema = /*#__PURE__*/ v.query("rsvp.atmo.space.getBlob", { 6 + params: /*#__PURE__*/ v.object({ 7 + cid: /*#__PURE__*/ v.cidString(), 8 + /** 9 + * Read-grant invite token for anonymous bearer access. 10 + */ 11 + inviteToken: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 12 + spaceUri: /*#__PURE__*/ v.string(), 13 + }), 14 + output: { 15 + type: "blob", 16 + }, 17 + }); 18 + 19 + type main$schematype = typeof _mainSchema; 20 + 21 + export interface mainSchema extends main$schematype {} 22 + 23 + export const mainSchema = _mainSchema as mainSchema; 24 + 25 + export interface $params extends v.InferInput<mainSchema["params"]> {} 26 + export type $output = v.InferXRPCBodyInput<mainSchema["output"]>; 27 + 28 + declare module "@atcute/lexicons/ambient" { 29 + interface XRPCQueries { 30 + "rsvp.atmo.space.getBlob": mainSchema; 31 + } 32 + }
+1 -1
src/lexicon-types/types/rsvp/atmo/space/getRecord.ts
··· 12 12 */ 13 13 inviteToken: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 14 14 rkey: /*#__PURE__*/ v.string(), 15 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 15 + spaceUri: /*#__PURE__*/ v.string(), 16 16 }), 17 17 output: { 18 18 type: "lex",
+1 -1
src/lexicon-types/types/rsvp/atmo/space/getSpace.ts
··· 9 9 * Read-grant invite token. When supplied, replaces JWT auth for this read. 10 10 */ 11 11 inviteToken: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 12 - uri: /*#__PURE__*/ v.resourceUriString(), 12 + uri: /*#__PURE__*/ v.string(), 13 13 }), 14 14 output: { 15 15 type: "lex",
+14 -16
src/lexicon-types/types/rsvp/atmo/space/invite/create.ts src/lexicon-types/types/rsvp/atmo/invite/create.ts
··· 1 1 import type {} from "@atcute/lexicons"; 2 2 import * as v from "@atcute/lexicons/validations"; 3 3 import type {} from "@atcute/lexicons/ambient"; 4 - import * as RsvpAtmoSpaceDefs from "../defs.js"; 4 + import * as RsvpAtmoInviteDefs from "./defs.js"; 5 5 6 - const _mainSchema = /*#__PURE__*/ v.procedure("rsvp.atmo.space.invite.create", { 6 + const _mainSchema = /*#__PURE__*/ v.procedure("rsvp.atmo.invite.create", { 7 7 params: null, 8 8 input: { 9 9 type: "lex", 10 10 schema: /*#__PURE__*/ v.object({ 11 11 /** 12 + * For community-owned spaces. The access level granted on redemption — the creator's own level caps what they can grant. 13 + */ 14 + accessLevel: /*#__PURE__*/ v.optional( 15 + /*#__PURE__*/ v.string< 16 + "admin" | "manager" | "member" | "owner" | (string & {}) 17 + >(), 18 + ), 19 + /** 12 20 * Unix ms timestamp. Omit for no expiry. 13 21 */ 14 22 expiresAt: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 15 23 /** 16 - * join: redeem to become a member. read: bearer-only read access, no membership. read-join: anonymous read + signed-in redeem to join. 17 - * @default "join" 24 + * For user-owned spaces. join: redeem to become a member. read: bearer-only read access, no membership. read-join: anonymous read + signed-in redeem to join. 18 25 */ 19 26 kind: /*#__PURE__*/ v.optional( 20 27 /*#__PURE__*/ v.string<"join" | "read" | "read-join" | (string & {})>(), 21 - "join", 22 28 ), 23 29 /** 24 - * Caps join redemptions only — read-token reads are unlimited. Omit for unlimited joins. 25 30 * @minimum 1 26 31 */ 27 32 maxUses: /*#__PURE__*/ v.optional( ··· 37 42 /*#__PURE__*/ v.stringLength(0, 500), 38 43 ]), 39 44 ), 40 - /** 41 - * @default "write" 42 - */ 43 - perms: /*#__PURE__*/ v.optional( 44 - /*#__PURE__*/ v.string<"read" | "write" | (string & {})>(), 45 - "write", 46 - ), 47 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 45 + spaceUri: /*#__PURE__*/ v.string(), 48 46 }), 49 47 }, 50 48 output: { 51 49 type: "lex", 52 50 schema: /*#__PURE__*/ v.object({ 53 51 get invite() { 54 - return RsvpAtmoSpaceDefs.inviteViewSchema; 52 + return RsvpAtmoInviteDefs.inviteViewSchema; 55 53 }, 56 54 /** 57 55 * Raw token. Shown once — cannot be retrieved later. ··· 73 71 74 72 declare module "@atcute/lexicons/ambient" { 75 73 interface XRPCProcedures { 76 - "rsvp.atmo.space.invite.create": mainSchema; 74 + "rsvp.atmo.invite.create": mainSchema; 77 75 } 78 76 }
+5 -5
src/lexicon-types/types/rsvp/atmo/space/invite/list.ts src/lexicon-types/types/rsvp/atmo/invite/list.ts
··· 1 1 import type {} from "@atcute/lexicons"; 2 2 import * as v from "@atcute/lexicons/validations"; 3 3 import type {} from "@atcute/lexicons/ambient"; 4 - import * as RsvpAtmoSpaceDefs from "../defs.js"; 4 + import * as RsvpAtmoInviteDefs from "./defs.js"; 5 5 6 - const _mainSchema = /*#__PURE__*/ v.query("rsvp.atmo.space.invite.list", { 6 + const _mainSchema = /*#__PURE__*/ v.query("rsvp.atmo.invite.list", { 7 7 params: /*#__PURE__*/ v.object({ 8 8 /** 9 9 * @default false 10 10 */ 11 11 includeRevoked: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.boolean(), false), 12 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 12 + spaceUri: /*#__PURE__*/ v.string(), 13 13 }), 14 14 output: { 15 15 type: "lex", 16 16 schema: /*#__PURE__*/ v.object({ 17 17 get invites() { 18 - return /*#__PURE__*/ v.array(RsvpAtmoSpaceDefs.inviteViewSchema); 18 + return /*#__PURE__*/ v.array(RsvpAtmoInviteDefs.inviteViewSchema); 19 19 }, 20 20 }), 21 21 }, ··· 32 32 33 33 declare module "@atcute/lexicons/ambient" { 34 34 interface XRPCQueries { 35 - "rsvp.atmo.space.invite.list": mainSchema; 35 + "rsvp.atmo.invite.list": mainSchema; 36 36 } 37 37 }
-36
src/lexicon-types/types/rsvp/atmo/space/invite/redeem.ts
··· 1 - import type {} from "@atcute/lexicons"; 2 - import * as v from "@atcute/lexicons/validations"; 3 - import type {} from "@atcute/lexicons/ambient"; 4 - 5 - const _mainSchema = /*#__PURE__*/ v.procedure("rsvp.atmo.space.invite.redeem", { 6 - params: null, 7 - input: { 8 - type: "lex", 9 - schema: /*#__PURE__*/ v.object({ 10 - token: /*#__PURE__*/ v.string(), 11 - }), 12 - }, 13 - output: { 14 - type: "lex", 15 - schema: /*#__PURE__*/ v.object({ 16 - perms: /*#__PURE__*/ v.string<"read" | "write" | (string & {})>(), 17 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 18 - }), 19 - }, 20 - }); 21 - 22 - type main$schematype = typeof _mainSchema; 23 - 24 - export interface mainSchema extends main$schematype {} 25 - 26 - export const mainSchema = _mainSchema as mainSchema; 27 - 28 - export interface $params {} 29 - export interface $input extends v.InferXRPCBodyInput<mainSchema["input"]> {} 30 - export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {} 31 - 32 - declare module "@atcute/lexicons/ambient" { 33 - interface XRPCProcedures { 34 - "rsvp.atmo.space.invite.redeem": mainSchema; 35 - } 36 - }
+6 -3
src/lexicon-types/types/rsvp/atmo/space/invite/revoke.ts src/lexicon-types/types/rsvp/atmo/invite/revoke.ts
··· 2 2 import * as v from "@atcute/lexicons/validations"; 3 3 import type {} from "@atcute/lexicons/ambient"; 4 4 5 - const _mainSchema = /*#__PURE__*/ v.procedure("rsvp.atmo.space.invite.revoke", { 5 + const _mainSchema = /*#__PURE__*/ v.procedure("rsvp.atmo.invite.revoke", { 6 6 params: null, 7 7 input: { 8 8 type: "lex", 9 9 schema: /*#__PURE__*/ v.object({ 10 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 10 + /** 11 + * Optional — ownership is inferred from the invite row; required for user-owned spaces for a sanity check. 12 + */ 13 + spaceUri: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 11 14 tokenHash: /*#__PURE__*/ v.string(), 12 15 }), 13 16 }, ··· 31 34 32 35 declare module "@atcute/lexicons/ambient" { 33 36 interface XRPCProcedures { 34 - "rsvp.atmo.space.invite.revoke": mainSchema; 37 + "rsvp.atmo.invite.revoke": mainSchema; 35 38 } 36 39 }
+1 -1
src/lexicon-types/types/rsvp/atmo/space/leaveSpace.ts
··· 7 7 input: { 8 8 type: "lex", 9 9 schema: /*#__PURE__*/ v.object({ 10 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 10 + spaceUri: /*#__PURE__*/ v.string(), 11 11 }), 12 12 }, 13 13 output: {
+50
src/lexicon-types/types/rsvp/atmo/space/listBlobs.ts
··· 1 + import type {} from "@atcute/lexicons"; 2 + import * as v from "@atcute/lexicons/validations"; 3 + import type {} from "@atcute/lexicons/ambient"; 4 + import * as RsvpAtmoSpaceDefs from "./defs.js"; 5 + 6 + const _mainSchema = /*#__PURE__*/ v.query("rsvp.atmo.space.listBlobs", { 7 + params: /*#__PURE__*/ v.object({ 8 + /** 9 + * Only blobs uploaded by this DID. 10 + */ 11 + byUser: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.didString()), 12 + cursor: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 13 + /** 14 + * @minimum 1 15 + * @maximum 200 16 + * @default 50 17 + */ 18 + limit: /*#__PURE__*/ v.optional( 19 + /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.integer(), [ 20 + /*#__PURE__*/ v.integerRange(1, 200), 21 + ]), 22 + 50, 23 + ), 24 + spaceUri: /*#__PURE__*/ v.string(), 25 + }), 26 + output: { 27 + type: "lex", 28 + schema: /*#__PURE__*/ v.object({ 29 + get blobs() { 30 + return /*#__PURE__*/ v.array(RsvpAtmoSpaceDefs.blobInfoSchema); 31 + }, 32 + cursor: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 33 + }), 34 + }, 35 + }); 36 + 37 + type main$schematype = typeof _mainSchema; 38 + 39 + export interface mainSchema extends main$schematype {} 40 + 41 + export const mainSchema = _mainSchema as mainSchema; 42 + 43 + export interface $params extends v.InferInput<mainSchema["params"]> {} 44 + export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {} 45 + 46 + declare module "@atcute/lexicons/ambient" { 47 + interface XRPCQueries { 48 + "rsvp.atmo.space.listBlobs": mainSchema; 49 + } 50 + }
+1 -1
src/lexicon-types/types/rsvp/atmo/space/listMembers.ts
··· 5 5 6 6 const _mainSchema = /*#__PURE__*/ v.query("rsvp.atmo.space.listMembers", { 7 7 params: /*#__PURE__*/ v.object({ 8 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 8 + spaceUri: /*#__PURE__*/ v.string(), 9 9 }), 10 10 output: { 11 11 type: "lex",
+1 -1
src/lexicon-types/types/rsvp/atmo/space/listRecords.ts
··· 26 26 ]), 27 27 50, 28 28 ), 29 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 29 + spaceUri: /*#__PURE__*/ v.string(), 30 30 }), 31 31 output: { 32 32 type: "lex",
+4
src/lexicon-types/types/rsvp/atmo/space/listSpaces.ts
··· 18 18 50, 19 19 ), 20 20 /** 21 + * With scope=member, filter to spaces owned by this DID. Ignored when scope=owner. 22 + */ 23 + owner: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.didString()), 24 + /** 21 25 * @default "member" 22 26 */ 23 27 scope: /*#__PURE__*/ v.optional(
+1 -1
src/lexicon-types/types/rsvp/atmo/space/putRecord.ts
··· 10 10 collection: /*#__PURE__*/ v.nsidString(), 11 11 record: /*#__PURE__*/ v.unknown(), 12 12 rkey: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 13 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 13 + spaceUri: /*#__PURE__*/ v.string(), 14 14 }), 15 15 }, 16 16 output: {
+1 -1
src/lexicon-types/types/rsvp/atmo/space/removeMember.ts
··· 8 8 type: "lex", 9 9 schema: /*#__PURE__*/ v.object({ 10 10 did: /*#__PURE__*/ v.didString(), 11 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 11 + spaceUri: /*#__PURE__*/ v.string(), 12 12 }), 13 13 }, 14 14 output: {
-42
src/lexicon-types/types/rsvp/atmo/space/transferOwnership.ts
··· 1 - import type {} from "@atcute/lexicons"; 2 - import * as v from "@atcute/lexicons/validations"; 3 - import type {} from "@atcute/lexicons/ambient"; 4 - import * as RsvpAtmoSpaceDefs from "./defs.js"; 5 - 6 - const _mainSchema = /*#__PURE__*/ v.procedure( 7 - "rsvp.atmo.space.transferOwnership", 8 - { 9 - params: null, 10 - input: { 11 - type: "lex", 12 - schema: /*#__PURE__*/ v.object({ 13 - newOwnerDid: /*#__PURE__*/ v.didString(), 14 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 15 - }), 16 - }, 17 - output: { 18 - type: "lex", 19 - schema: /*#__PURE__*/ v.object({ 20 - get space() { 21 - return RsvpAtmoSpaceDefs.spaceViewSchema; 22 - }, 23 - }), 24 - }, 25 - }, 26 - ); 27 - 28 - type main$schematype = typeof _mainSchema; 29 - 30 - export interface mainSchema extends main$schematype {} 31 - 32 - export const mainSchema = _mainSchema as mainSchema; 33 - 34 - export interface $params {} 35 - export interface $input extends v.InferXRPCBodyInput<mainSchema["input"]> {} 36 - export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {} 37 - 38 - declare module "@atcute/lexicons/ambient" { 39 - interface XRPCProcedures { 40 - "rsvp.atmo.space.transferOwnership": mainSchema; 41 - } 42 - }
+34
src/lexicon-types/types/rsvp/atmo/space/uploadBlob.ts
··· 1 + import type {} from "@atcute/lexicons"; 2 + import * as v from "@atcute/lexicons/validations"; 3 + import type {} from "@atcute/lexicons/ambient"; 4 + 5 + const _mainSchema = /*#__PURE__*/ v.procedure("rsvp.atmo.space.uploadBlob", { 6 + params: /*#__PURE__*/ v.object({ 7 + spaceUri: /*#__PURE__*/ v.string(), 8 + }), 9 + input: { 10 + type: "blob", 11 + }, 12 + output: { 13 + type: "lex", 14 + schema: /*#__PURE__*/ v.object({ 15 + blob: /*#__PURE__*/ v.blob(), 16 + }), 17 + }, 18 + }); 19 + 20 + type main$schematype = typeof _mainSchema; 21 + 22 + export interface mainSchema extends main$schematype {} 23 + 24 + export const mainSchema = _mainSchema as mainSchema; 25 + 26 + export interface $params extends v.InferInput<mainSchema["params"]> {} 27 + export type $input = v.InferXRPCBodyInput<mainSchema["input"]>; 28 + export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {} 29 + 30 + declare module "@atcute/lexicons/ambient" { 31 + interface XRPCProcedures { 32 + "rsvp.atmo.space.uploadBlob": mainSchema; 33 + } 34 + }
+10 -8
src/lexicon-types/types/rsvp/atmo/space/whoami.ts src/lexicon-types/types/rsvp/atmo/spaceExt/whoami.ts
··· 2 2 import * as v from "@atcute/lexicons/validations"; 3 3 import type {} from "@atcute/lexicons/ambient"; 4 4 5 - const _mainSchema = /*#__PURE__*/ v.query("rsvp.atmo.space.whoami", { 5 + const _mainSchema = /*#__PURE__*/ v.query("rsvp.atmo.spaceExt.whoami", { 6 6 params: /*#__PURE__*/ v.object({ 7 - spaceUri: /*#__PURE__*/ v.resourceUriString(), 7 + spaceUri: /*#__PURE__*/ v.string(), 8 8 }), 9 9 output: { 10 10 type: "lex", 11 11 schema: /*#__PURE__*/ v.object({ 12 - isMember: /*#__PURE__*/ v.boolean(), 13 - isOwner: /*#__PURE__*/ v.boolean(), 14 12 /** 15 - * Present only when the caller is a member or the owner. 13 + * Only set for community-owned spaces. Null when the caller has no resolvable access. 16 14 */ 17 - perms: /*#__PURE__*/ v.optional( 18 - /*#__PURE__*/ v.string<"read" | "write" | (string & {})>(), 15 + accessLevel: /*#__PURE__*/ v.optional( 16 + /*#__PURE__*/ v.string< 17 + "admin" | "manager" | "member" | "owner" | (string & {}) 18 + >(), 19 19 ), 20 + isMember: /*#__PURE__*/ v.boolean(), 21 + isOwner: /*#__PURE__*/ v.boolean(), 20 22 }), 21 23 }, 22 24 }); ··· 32 34 33 35 declare module "@atcute/lexicons/ambient" { 34 36 interface XRPCQueries { 35 - "rsvp.atmo.space.whoami": mainSchema; 37 + "rsvp.atmo.spaceExt.whoami": mainSchema; 36 38 } 37 39 }
+2 -2
src/lib/atproto/server/profile.ts
··· 13 13 return { 14 14 did: p.did, 15 15 handle: p.handle && p.handle !== 'handle.invalid' ? p.handle : did, 16 - displayName: p.record?.displayName, 17 - avatar: p.record?.avatar ? getProfileBlobUrl(p.did, p.record.avatar) : undefined 16 + displayName: p.value?.displayName, 17 + avatar: p.value?.avatar ? getProfileBlobUrl(p.did, p.value.avatar) : undefined 18 18 }; 19 19 } catch (e) { 20 20 console.error('Failed to load profile:', e);
+3 -3
src/lib/components/RecentActivity.svelte
··· 29 29 return plural ? 'are interested' : 'is interested'; 30 30 } 31 31 32 - function relativeTime(timeUs: number): string { 33 - const ageMs = Date.now() - timeUs / 1000; 32 + function relativeTime(timeMs: number): string { 33 + const ageMs = Date.now() - timeMs; 34 34 const sec = Math.max(0, Math.floor(ageMs / 1000)); 35 35 if (sec < 60) return 'just now'; 36 36 const mins = Math.floor(sec / 60); ··· 66 66 {eventTitle} 67 67 </h3> 68 68 <span class="text-base-500 shrink-0 text-xs"> 69 - {relativeTime(cluster.latestTimeUs)} 69 + {relativeTime(cluster.latestCreatedAtMs)} 70 70 </span> 71 71 </div> 72 72 <div class="mt-2 flex items-center gap-2">
+18 -9
src/lib/contrail.ts
··· 69 69 export type ActivityCluster = { 70 70 event: FlatEventRecord; 71 71 attendees: AttendeeInfo[]; 72 - latestTimeUs: number; 72 + /** ms since epoch of the most recent RSVP in this cluster, taken from the 73 + * RSVP record's `createdAt` (when the user actually RSVP'd) — not from 74 + * contrail's `time_us` (which reflects index time and all bunches up after 75 + * a backfill). */ 76 + latestCreatedAtMs: number; 73 77 }; 74 78 75 79 type ListEventsParams = { ··· 115 119 } 116 120 117 121 export function flattenEventRecord(record: FlattenableEventRecord): FlatEventRecord | null { 118 - if (!record.record?.startsAt) return null; 122 + // Top-level envelope records use `value`; hydrated sub-records (e.g. the 123 + // event embedded on an RSVP) still use `record`. Accept either shape. 124 + const body = 125 + ('value' in record ? (record.value as EventData | undefined) : undefined) ?? 126 + ('record' in record ? (record.record as EventData | undefined) : undefined); 127 + if (!body?.startsAt) return null; 119 128 120 129 return { 121 - ...(record.record as EventData), 130 + ...body, 122 131 cid: record.cid ?? null, 123 132 did: record.did, 124 133 rkey: record.rkey, ··· 147 156 export function eventUrl(event: FlatEventRecord, actor?: string): string { 148 157 const who = actor || event.did; 149 158 if (event.space) { 150 - const m = event.space.match(/^at:\/\/[^/]+\/[^/]+\/([^/]+)$/); 159 + const m = event.space.match(/^ats?:\/\/[^/]+\/[^/]+\/([^/]+)$/); 151 160 const skey = m?.[1]; 152 161 if (skey) return `/p/${who}/e/${event.rkey}/s/${skey}`; 153 162 } ··· 161 170 return { 162 171 did, 163 172 handle: profile.handle, 164 - displayName: profile.record?.displayName, 165 - avatar: getProfileBlobUrl(did, profile.record?.avatar) 173 + displayName: profile.value?.displayName, 174 + avatar: getProfileBlobUrl(did, profile.value?.avatar) 166 175 }; 167 176 } 168 177 ··· 177 186 return { 178 187 did, 179 188 status, 180 - avatar: getProfileBlobUrl(did, profile?.record?.avatar), 181 - name: profile?.record?.displayName || handle || did, 189 + avatar: getProfileBlobUrl(did, profile?.value?.avatar), 190 + name: profile?.value?.displayName || handle || did, 182 191 handle, 183 192 url: getProfileUrl(handle || did) 184 193 }; ··· 390 399 const seen = new Set<string>(); 391 400 return (response.data.records ?? []) 392 401 .filter((record) => { 393 - const status = record.record?.status; 402 + const status = record.value?.status; 394 403 return status?.endsWith('#going') || status?.endsWith('#interested'); 395 404 }) 396 405 .flatMap((record) => {
+7 -2
src/lib/contrail/config.ts src/lib/contrail.config.ts
··· 1 1 import type { ContrailConfig } from '@atmo-dev/contrail'; 2 - import { SPACE_TYPE } from '../spaces/config'; 2 + import { SPACE_TYPE } from './spaces/config'; 3 3 4 4 export const config: ContrailConfig = { 5 5 namespace: 'rsvp.atmo', ··· 61 61 collection: 'community.lexicon.calendar.rsvp', 62 62 queryable: { 63 63 status: {}, 64 - 'subject.uri': {} 64 + 'subject.uri': {}, 65 + // Sortable so the home-page activity feed can order by when the user 66 + // actually RSVP'd (record.createdAt) — not by when contrail indexed 67 + // it (time_us). Without this, a fresh backfill clusters thousands of 68 + // historical RSVPs at the top of time_us order, drowning live activity. 69 + createdAt: { type: 'range' } 65 70 }, 66 71 references: { 67 72 event: {
+1 -1
src/lib/contrail/index.ts
··· 1 1 import { Contrail } from '@atmo-dev/contrail'; 2 2 import { createHandler } from '@atmo-dev/contrail/server'; 3 3 import { Client } from '@atcute/client'; 4 - import { config } from './config'; 4 + import { config } from '../contrail.config'; 5 5 import { getSpacesConfig, spacesAvailable } from '../spaces/config'; 6 6 7 7 const spaces = getSpacesConfig();
+5 -5
src/lib/spaces/server/spaces.remote.ts
··· 6 6 import { getSpacesClient } from './client'; 7 7 import { SPACE_TYPE, spacesAvailable } from '../config'; 8 8 9 - const atUriSchema = v.pipe(v.string(), v.regex(/^at:\/\/.+/)); 9 + const atUriSchema = v.pipe(v.string(), v.regex(/^ats?:\/\/.+/)); 10 10 const didSchema = v.pipe(v.string(), v.regex(/^did:[a-z]+:.+/)); 11 11 const nsidSchema = v.pipe(v.string(), v.regex(/^[a-zA-Z][a-zA-Z0-9-]*(\.[a-zA-Z][a-zA-Z0-9-]*){2,}$/)); 12 12 ··· 165 165 }), 166 166 async (input) => { 167 167 const { client } = getClient(); 168 - const res = await client.post('rsvp.atmo.space.invite.create', { 168 + const res = await client.post('rsvp.atmo.invite.create', { 169 169 input: { ...input, spaceUri: input.spaceUri as unknown as import('@atcute/lexicons').ResourceUri } 170 170 }); 171 171 if (!res.ok) error(res.status, 'createInvite failed'); ··· 177 177 v.object({ spaceUri: atUriSchema, includeRevoked: v.optional(v.boolean()) }), 178 178 async ({ spaceUri, includeRevoked }) => { 179 179 const { client } = getClient(); 180 - const res = await client.get('rsvp.atmo.space.invite.list', { 180 + const res = await client.get('rsvp.atmo.invite.list', { 181 181 params: { 182 182 spaceUri: spaceUri as unknown as import('@atcute/lexicons').ResourceUri, 183 183 includeRevoked: includeRevoked ?? false ··· 192 192 v.object({ spaceUri: atUriSchema, tokenHash: v.string() }), 193 193 async (input) => { 194 194 const { client } = getClient(); 195 - const res = await client.post('rsvp.atmo.space.invite.revoke', { 195 + const res = await client.post('rsvp.atmo.invite.revoke', { 196 196 input: { ...input, spaceUri: input.spaceUri as unknown as import('@atcute/lexicons').ResourceUri } 197 197 }); 198 198 if (!res.ok) error(res.status, 'revokeInvite failed'); ··· 246 246 247 247 export const redeemInvite = command(v.object({ token: v.string() }), async ({ token }) => { 248 248 const { client } = getClient(); 249 - const res = await client.post('rsvp.atmo.space.invite.redeem', { input: { token } }); 249 + const res = await client.post('rsvp.atmo.invite.redeem', { input: { token } }); 250 250 if (!res.ok) { 251 251 console.error('[redeemInvite] xrpc error', res.status, res.data); 252 252 error(res.status, `redeemInvite ${res.status}: ${JSON.stringify(res.data)}`);
+1 -1
src/routes/(app)/+layout.svelte
··· 12 12 13 13 <ModeWatcher /> 14 14 15 - <Navbar class="top-2 right-2 left-2 mx-auto max-w-3xl rounded-full pr-3 pl-6"> 15 + <Navbar class="top-2 right-2 left-2 mx-auto max-w-3xl rounded-full! pr-3 pl-6"> 16 16 <div class="flex items-center gap-6"> 17 17 <a 18 18 href={resolve('/')}
+11 -5
src/routes/(app)/+page.server.ts
··· 45 45 46 46 const rsvpEvents = (rsvpResponse.ok ? (rsvpResponse.data.records ?? []) : []) 47 47 .filter((r) => { 48 - const status = r.record?.status; 48 + const status = r.value?.status; 49 49 return status?.endsWith('#going') || status?.endsWith('#interested'); 50 50 }) 51 51 .flatMap((r) => { ··· 89 89 params: { 90 90 hydrateEvent: true, 91 91 profiles: true, 92 + sort: 'createdAt', 93 + order: 'desc', 92 94 limit: ACTIVITY_FETCH_LIMIT 93 95 } 94 96 }); ··· 100 102 const clusters = new Map<string, ActivityCluster>(); 101 103 102 104 for (const r of records) { 103 - const status = r.record?.status; 105 + const status = r.value?.status; 104 106 const isGoing = status?.endsWith('#going'); 105 107 const isInterested = status?.endsWith('#interested'); 106 108 if (!isGoing && !isInterested) continue; ··· 113 115 if (eventEndMs < nowMs) continue; 114 116 115 117 const attendee = buildAttendee(r.did, isGoing ? 'going' : 'interested', profiles); 118 + // `createdAt` is an atproto convention all RSVPs carry, even though the 119 + // community.lexicon.calendar.rsvp schema doesn't formally declare it. 120 + const createdAt = (r.value as { createdAt?: string } | undefined)?.createdAt; 121 + const createdAtMs = createdAt ? new Date(createdAt).getTime() : 0; 116 122 117 123 let cluster = clusters.get(flatEvent.uri); 118 124 if (!cluster) { 119 - cluster = { event: flatEvent, attendees: [], latestTimeUs: r.time_us }; 125 + cluster = { event: flatEvent, attendees: [], latestCreatedAtMs: createdAtMs }; 120 126 clusters.set(flatEvent.uri, cluster); 121 127 } 122 128 cluster.attendees.push(attendee); 123 - if (r.time_us > cluster.latestTimeUs) cluster.latestTimeUs = r.time_us; 129 + if (createdAtMs > cluster.latestCreatedAtMs) cluster.latestCreatedAtMs = createdAtMs; 124 130 } 125 131 126 132 return Array.from(clusters.values()) 127 - .sort((a, b) => b.latestTimeUs - a.latestTimeUs) 133 + .sort((a, b) => b.latestCreatedAtMs - a.latestCreatedAtMs) 128 134 .slice(0, ACTIVITY_DISPLAY_LIMIT); 129 135 })(); 130 136
+1 -1
src/routes/(app)/calendar/+page.server.ts
··· 31 31 32 32 const rsvpEvents = (rsvpResponse.ok ? (rsvpResponse.data.records ?? []) : []) 33 33 .filter((r) => { 34 - const status = r.record?.status; 34 + const status = r.value?.status; 35 35 return status?.endsWith('#going') || status?.endsWith('#interested'); 36 36 }) 37 37 .flatMap((r) => {
+3 -3
src/routes/(app)/p/[actor]/+page.svelte
··· 11 11 12 12 let hostProfile = $derived(data.actorProfile); 13 13 let hostDid = $derived(data.actorDid as string); 14 - let hostName = $derived(hostProfile?.record?.displayName || hostProfile?.handle || hostDid); 14 + let hostName = $derived(hostProfile?.value?.displayName || hostProfile?.handle || hostDid); 15 15 16 16 let now = $derived(new Date()); 17 17 ··· 45 45 profile={{ 46 46 handle: hostProfile?.handle, 47 47 displayName: hostName, 48 - avatar: hostProfile?.record?.avatar 49 - ? getProfileBlobUrl(hostDid, hostProfile.record.avatar) 48 + avatar: hostProfile?.value?.avatar 49 + ? getProfileBlobUrl(hostDid, hostProfile.value.avatar) 50 50 : undefined 51 51 }} 52 52 >
+1 -1
src/routes/(app)/p/[actor]/calendar.ics/+server.ts
··· 42 42 43 43 const rsvpEvents = (rsvpResponse.ok ? (rsvpResponse.data.records ?? []) : []) 44 44 .filter((r) => { 45 - const status = r.record?.status; 45 + const status = r.value?.status; 46 46 return status?.endsWith('#going') || status?.endsWith('#interested'); 47 47 }) 48 48 .flatMap((r) => {
+2 -2
src/routes/(app)/p/[actor]/e/[rkey]/+page.server.ts
··· 65 65 .then((p) => ({ 66 66 id: s.id, 67 67 name: s.name, 68 - avatar: p?.record?.avatar ? getProfileBlobUrl(p.did, p.record.avatar) : undefined, 68 + avatar: p?.value?.avatar ? getProfileBlobUrl(p.did, p.value.avatar) : undefined, 69 69 handle: p?.handle || s.id 70 70 })) 71 71 .catch(() => ({ id: s.id, name: s.name, avatar: undefined, handle: s.id })) ··· 80 80 rkey, 81 81 hostProfile: getHostProfile(did, fullEventRecord.profiles) ?? null, 82 82 attendees, 83 - viewerRsvpStatus: getRsvpStatus(viewerRsvpRecord?.record?.status), 83 + viewerRsvpStatus: getRsvpStatus(viewerRsvpRecord?.value?.status), 84 84 viewerRsvpRkey: viewerRsvpRecord?.rkey ?? null, 85 85 parentEvent, 86 86 vod,
+7 -7
src/routes/(app)/p/[actor]/e/[rkey]/s/[skey]/+page.server.ts
··· 18 18 return { authState: 'not-found' as const }; 19 19 } 20 20 21 - const spaceUri = `at://${ownerDid}/${SPACE_TYPE}/${params.skey}`; 21 + const spaceUri = `ats://${ownerDid}/${SPACE_TYPE}/${params.skey}`; 22 22 const inviteToken = url.searchParams.get('invite') ?? undefined; 23 23 const hasInvite = inviteToken != null; 24 24 ··· 79 79 hostProfile = { 80 80 did: p.did, 81 81 handle: p.handle && p.handle !== 'handle.invalid' ? p.handle : ownerDid, 82 - displayName: p.record?.displayName, 83 - avatar: p.record?.avatar ? getProfileBlobUrl(p.did, p.record.avatar) : undefined 82 + displayName: p.value?.displayName, 83 + avatar: p.value?.avatar ? getProfileBlobUrl(p.did, p.value.avatar) : undefined 84 84 }; 85 85 } 86 86 } catch { ··· 120 120 profileMap.set(did, { 121 121 did: p.did, 122 122 handle: p.handle && p.handle !== 'handle.invalid' ? p.handle : did, 123 - displayName: p.record?.displayName, 124 - avatar: p.record?.avatar ? getProfileBlobUrl(p.did, p.record.avatar) : undefined 123 + displayName: p.value?.displayName, 124 + avatar: p.value?.avatar ? getProfileBlobUrl(p.did, p.value.avatar) : undefined 125 125 }); 126 126 } 127 127 } catch { ··· 242 242 profileMap.set(d, { 243 243 did: p.did, 244 244 handle: p.handle && p.handle !== 'handle.invalid' ? p.handle : d, 245 - displayName: p.record?.displayName, 246 - avatar: p.record?.avatar ? getProfileBlobUrl(p.did, p.record.avatar) : undefined 245 + displayName: p.value?.displayName, 246 + avatar: p.value?.avatar ? getProfileBlobUrl(p.did, p.value.avatar) : undefined 247 247 }); 248 248 } 249 249 } catch {
+1 -1
src/routes/(app)/p/[actor]/e/[rkey]/s/[skey]/admin/+page.server.ts
··· 11 11 if (!ownerDid) throw error(404, 'Not found'); 12 12 if (ownerDid !== locals.did) throw error(403, 'Only the host can manage this event'); 13 13 14 - const spaceUri = `at://${ownerDid}/${SPACE_TYPE}/${params.skey}`; 14 + const spaceUri = `ats://${ownerDid}/${SPACE_TYPE}/${params.skey}`; 15 15 16 16 const [members, invites] = await Promise.all([ 17 17 listMembers({ spaceUri }).catch(() => []),
-1
src/routes/(app)/p/[actor]/e/[rkey]/s/[skey]/admin/+page.svelte
··· 137 137 <li class="flex items-center justify-between py-2"> 138 138 <div> 139 139 <div class="font-mono text-xs">{m.did}</div> 140 - <div class="text-base-500 text-xs">{m.perms}</div> 141 140 </div> 142 141 <button class="text-xs text-red-600" onclick={() => handleRemoveMember(m.did)} 143 142 >Remove</button
+4 -2
src/routes/(app)/p/[actor]/e/calendar/+server.ts
··· 7 7 buildEventAttendees, 8 8 flattenEventRecords, 9 9 getHostProfile, 10 + getServerClient, 10 11 listEventRecordsFromContrail, 11 12 RSVP_HYDRATE_LIMIT 12 13 } from '$lib/contrail'; 13 14 14 - export async function GET({ params }) { 15 + export async function GET({ params, platform }) { 15 16 if (!isActorIdentifier(params.actor)) { 16 17 throw error(404, 'Not found'); 17 18 } ··· 23 24 } 24 25 25 26 try { 26 - const response = await listEventRecordsFromContrail({ 27 + const client = getServerClient(platform!.env.DB); 28 + const response = await listEventRecordsFromContrail(client, { 27 29 actor: params.actor, 28 30 hydrateRsvps: RSVP_HYDRATE_LIMIT, 29 31 profiles: true,
+2 -2
src/routes/(app)/p/[actor]/hosting/+page.svelte
··· 6 6 7 7 let hostProfile = $derived(data.actorProfile); 8 8 let hostDid = $derived(data.actorDid as string); 9 - let hostName = $derived(hostProfile?.record?.displayName || hostProfile?.handle || hostDid); 9 + let hostName = $derived(hostProfile?.value?.displayName || hostProfile?.handle || hostDid); 10 10 let hostAvatar = $derived( 11 - hostProfile?.record?.avatar ? getProfileBlobUrl(hostDid, hostProfile.record.avatar) : undefined 11 + hostProfile?.value?.avatar ? getProfileBlobUrl(hostDid, hostProfile.value.avatar) : undefined 12 12 ); 13 13 14 14 let fetchParams: Record<string, string> = $derived({
+2 -2
src/routes/(app)/p/[actor]/past-events/+page.svelte
··· 6 6 7 7 let hostProfile = $derived(data.actorProfile); 8 8 let hostDid = $derived(data.actorDid as string); 9 - let hostName = $derived(hostProfile?.record?.displayName || hostProfile?.handle || hostDid); 9 + let hostName = $derived(hostProfile?.value?.displayName || hostProfile?.handle || hostDid); 10 10 let hostAvatar = $derived( 11 - hostProfile?.record?.avatar ? getProfileBlobUrl(hostDid, hostProfile.record.avatar) : undefined 11 + hostProfile?.value?.avatar ? getProfileBlobUrl(hostDid, hostProfile.value.avatar) : undefined 12 12 ); 13 13 14 14 let fetchParams: Record<string, string> = $derived({
+2 -2
src/routes/(app)/p/atmosphereconf.org/+page.server.ts
··· 32 32 const rsvpRkeys: Record<string, string> = {}; 33 33 if (rsvpResponse?.ok) { 34 34 for (const r of rsvpResponse.data.records ?? []) { 35 - const status = r.record?.status; 36 - const uri = r.record?.subject?.uri; 35 + const status = r.value?.status; 36 + const uri = r.value?.subject?.uri; 37 37 if (status && uri) { 38 38 const shortStatus = status.split('#').pop()!; 39 39 rsvpStatuses[uri] = shortStatus;
+3 -3
src/routes/(app)/p/atmosphereconf.org/+page.svelte
··· 21 21 let hostDid = $derived(hostProfile?.did ?? ''); 22 22 let isOwnProfile = $derived(user.isLoggedIn && !!hostDid && user.did === hostDid); 23 23 let hostName = $derived( 24 - hostProfile?.record?.displayName || hostProfile?.handle || 'ATmosphereConf' 24 + hostProfile?.value?.displayName || hostProfile?.handle || 'ATmosphereConf' 25 25 ); 26 26 27 27 let scheduleEvents = $derived(getScheduleEvents(data.events)); ··· 112 112 profile={{ 113 113 handle: hostProfile?.handle, 114 114 displayName: hostName, 115 - avatar: hostProfile?.record?.avatar 116 - ? getProfileBlobUrl(hostDid, hostProfile.record.avatar) 115 + avatar: hostProfile?.value?.avatar 116 + ? getProfileBlobUrl(hostDid, hostProfile.value.avatar) 117 117 : undefined 118 118 }} 119 119 >
+1 -1
src/routes/embed/p/[actor]/e/[rkey]/+page.server.ts
··· 61 61 hostProfile, 62 62 thumbnailUrl, 63 63 viewerDid, 64 - viewerRsvpStatus: getRsvpStatus(viewerRsvpRecord?.record?.status), 64 + viewerRsvpStatus: getRsvpStatus(viewerRsvpRecord?.value?.status), 65 65 viewerRsvpRkey: viewerRsvpRecord?.rkey ?? null 66 66 }; 67 67 } catch (e) {
+1 -2
wrangler.jsonc
··· 18 18 { 19 19 "binding": "DB", 20 20 "database_name": "atmo-events-v2", 21 - "database_id": "7ac1d7f2-afc2-4ac6-8fce-d192c02f63a5", 22 - "remote": true 21 + "database_id": "7ac1d7f2-afc2-4ac6-8fce-d192c02f63a5" 23 22 } 24 23 ], 25 24 "triggers": {