@atproto/bsky 0.1.1 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -0
- package/dist/api/app/bsky/actor/getSuggestions.d.ts.map +1 -1
- package/dist/api/app/bsky/actor/getSuggestions.js +9 -3
- package/dist/api/app/bsky/actor/getSuggestions.js.map +1 -1
- package/dist/api/app/bsky/feed/getFeed.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getFeed.js +44 -15
- package/dist/api/app/bsky/feed/getFeed.js.map +1 -1
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +7 -3
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js +13 -4
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedFeeds.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js +12 -4
- package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js +10 -3
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js +13 -4
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.js +18 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js +17 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js +18 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js +18 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js.map +1 -1
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +22 -0
- package/dist/config.js.map +1 -1
- package/dist/data-plane/server/routes/atmosphere.d.ts +5 -0
- package/dist/data-plane/server/routes/atmosphere.d.ts.map +1 -0
- package/dist/data-plane/server/routes/atmosphere.js +24 -0
- package/dist/data-plane/server/routes/atmosphere.js.map +1 -0
- package/dist/data-plane/server/routes/index.js +2 -2
- package/dist/data-plane/server/routes/index.js.map +1 -1
- package/dist/feature-gates/gates.d.ts +10 -0
- package/dist/feature-gates/gates.d.ts.map +1 -1
- package/dist/feature-gates/gates.js +10 -0
- package/dist/feature-gates/gates.js.map +1 -1
- package/dist/feature-gates/index.js +2 -2
- package/dist/feature-gates/index.js.map +1 -1
- package/dist/hydration/external.d.ts +65 -2
- package/dist/hydration/external.d.ts.map +1 -1
- package/dist/hydration/external.js +220 -29
- package/dist/hydration/external.js.map +1 -1
- package/dist/hydration/hydrator.d.ts.map +1 -1
- package/dist/hydration/hydrator.js +7 -7
- package/dist/hydration/hydrator.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.d.ts +2 -0
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.js +1 -0
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.d.ts +2 -0
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.js +1 -0
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.d.ts +2 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.js +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.d.ts +2 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.js +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.d.ts +2 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.js +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.d.ts +2 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.js +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.js.map +1 -1
- package/dist/lexicons/tools/ozone/inbox/defs.defs.d.ts +110 -6
- package/dist/lexicons/tools/ozone/inbox/defs.defs.d.ts.map +1 -1
- package/dist/lexicons/tools/ozone/inbox/defs.defs.js +90 -2
- package/dist/lexicons/tools/ozone/inbox/defs.defs.js.map +1 -1
- package/dist/lexicons/tools/ozone/inbox/getAccountStatus.d.ts +3 -0
- package/dist/lexicons/tools/ozone/inbox/getAccountStatus.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getAccountStatus.defs.d.ts +50 -0
- package/dist/lexicons/tools/ozone/inbox/getAccountStatus.defs.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getAccountStatus.defs.js +22 -0
- package/dist/lexicons/tools/ozone/inbox/getAccountStatus.defs.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getAccountStatus.js +6 -0
- package/dist/lexicons/tools/ozone/inbox/getAccountStatus.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getActionedSubject.d.ts +3 -0
- package/dist/lexicons/tools/ozone/inbox/getActionedSubject.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getActionedSubject.defs.d.ts +35 -0
- package/dist/lexicons/tools/ozone/inbox/getActionedSubject.defs.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getActionedSubject.defs.js +23 -0
- package/dist/lexicons/tools/ozone/inbox/getActionedSubject.defs.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getActionedSubject.js +6 -0
- package/dist/lexicons/tools/ozone/inbox/getActionedSubject.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getNotificationPreferences.d.ts +3 -0
- package/dist/lexicons/tools/ozone/inbox/getNotificationPreferences.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getNotificationPreferences.defs.d.ts +28 -0
- package/dist/lexicons/tools/ozone/inbox/getNotificationPreferences.defs.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getNotificationPreferences.defs.js +18 -0
- package/dist/lexicons/tools/ozone/inbox/getNotificationPreferences.defs.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getNotificationPreferences.js +6 -0
- package/dist/lexicons/tools/ozone/inbox/getNotificationPreferences.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getReport.d.ts +3 -0
- package/dist/lexicons/tools/ozone/inbox/getReport.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getReport.defs.d.ts +75 -0
- package/dist/lexicons/tools/ozone/inbox/getReport.defs.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getReport.defs.js +52 -0
- package/dist/lexicons/tools/ozone/inbox/getReport.defs.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getReport.js +6 -0
- package/dist/lexicons/tools/ozone/inbox/getReport.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getUnreadCount.d.ts +3 -0
- package/dist/lexicons/tools/ozone/inbox/getUnreadCount.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getUnreadCount.defs.d.ts +43 -0
- package/dist/lexicons/tools/ozone/inbox/getUnreadCount.defs.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getUnreadCount.defs.js +28 -0
- package/dist/lexicons/tools/ozone/inbox/getUnreadCount.defs.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/getUnreadCount.js +6 -0
- package/dist/lexicons/tools/ozone/inbox/getUnreadCount.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/listActionedSubjects.d.ts +3 -0
- package/dist/lexicons/tools/ozone/inbox/listActionedSubjects.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/listActionedSubjects.defs.d.ts +41 -0
- package/dist/lexicons/tools/ozone/inbox/listActionedSubjects.defs.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/listActionedSubjects.defs.js +33 -0
- package/dist/lexicons/tools/ozone/inbox/listActionedSubjects.defs.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/listActionedSubjects.js +6 -0
- package/dist/lexicons/tools/ozone/inbox/listActionedSubjects.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/listNotifications.d.ts +3 -0
- package/dist/lexicons/tools/ozone/inbox/listNotifications.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/listNotifications.defs.d.ts +48 -0
- package/dist/lexicons/tools/ozone/inbox/listNotifications.defs.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/listNotifications.defs.js +31 -0
- package/dist/lexicons/tools/ozone/inbox/listNotifications.defs.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/listNotifications.js +6 -0
- package/dist/lexicons/tools/ozone/inbox/listNotifications.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/listReports.d.ts +3 -0
- package/dist/lexicons/tools/ozone/inbox/listReports.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/listReports.defs.d.ts +72 -0
- package/dist/lexicons/tools/ozone/inbox/listReports.defs.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/listReports.defs.js +57 -0
- package/dist/lexicons/tools/ozone/inbox/listReports.defs.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/listReports.js +6 -0
- package/dist/lexicons/tools/ozone/inbox/listReports.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/putNotificationPreferences.d.ts +3 -0
- package/dist/lexicons/tools/ozone/inbox/putNotificationPreferences.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/putNotificationPreferences.defs.d.ts +27 -0
- package/dist/lexicons/tools/ozone/inbox/putNotificationPreferences.defs.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/putNotificationPreferences.defs.js +19 -0
- package/dist/lexicons/tools/ozone/inbox/putNotificationPreferences.defs.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/putNotificationPreferences.js +6 -0
- package/dist/lexicons/tools/ozone/inbox/putNotificationPreferences.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/updateSeen.d.ts +3 -0
- package/dist/lexicons/tools/ozone/inbox/updateSeen.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/updateSeen.defs.d.ts +40 -0
- package/dist/lexicons/tools/ozone/inbox/updateSeen.defs.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/updateSeen.defs.js +21 -0
- package/dist/lexicons/tools/ozone/inbox/updateSeen.defs.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox/updateSeen.js +6 -0
- package/dist/lexicons/tools/ozone/inbox/updateSeen.js.map +1 -0
- package/dist/lexicons/tools/ozone/inbox.d.ts +10 -0
- package/dist/lexicons/tools/ozone/inbox.d.ts.map +1 -1
- package/dist/lexicons/tools/ozone/inbox.js +10 -0
- package/dist/lexicons/tools/ozone/inbox.js.map +1 -1
- package/dist/lexicons/tools/ozone/moderation/defs.defs.d.ts +10 -0
- package/dist/lexicons/tools/ozone/moderation/defs.defs.d.ts.map +1 -1
- package/dist/lexicons/tools/ozone/moderation/defs.defs.js +5 -0
- package/dist/lexicons/tools/ozone/moderation/defs.defs.js.map +1 -1
- package/dist/lexicons/tools/ozone/server/getCapabilities.d.ts +3 -0
- package/dist/lexicons/tools/ozone/server/getCapabilities.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/server/getCapabilities.defs.d.ts +26 -0
- package/dist/lexicons/tools/ozone/server/getCapabilities.defs.d.ts.map +1 -0
- package/dist/lexicons/tools/ozone/server/getCapabilities.defs.js +22 -0
- package/dist/lexicons/tools/ozone/server/getCapabilities.defs.js.map +1 -0
- package/dist/lexicons/tools/ozone/server/getCapabilities.js +6 -0
- package/dist/lexicons/tools/ozone/server/getCapabilities.js.map +1 -0
- package/dist/lexicons/tools/ozone/server.d.ts +1 -0
- package/dist/lexicons/tools/ozone/server.d.ts.map +1 -1
- package/dist/lexicons/tools/ozone/server.js +1 -0
- package/dist/lexicons/tools/ozone/server.js.map +1 -1
- package/dist/proto/bsky_connect.d.ts +57 -21
- package/dist/proto/bsky_connect.d.ts.map +1 -1
- package/dist/proto/bsky_connect.js +57 -21
- package/dist/proto/bsky_connect.js.map +1 -1
- package/dist/proto/bsky_pb.d.ts +361 -72
- package/dist/proto/bsky_pb.d.ts.map +1 -1
- package/dist/proto/bsky_pb.js +529 -70
- package/dist/proto/bsky_pb.js.map +1 -1
- package/dist/util/standard-site.d.ts +0 -12
- package/dist/util/standard-site.d.ts.map +1 -1
- package/dist/util/standard-site.js +0 -14
- package/dist/util/standard-site.js.map +1 -1
- package/package.json +8 -8
- package/dist/data-plane/server/routes/site-standard.d.ts +0 -6
- package/dist/data-plane/server/routes/site-standard.d.ts.map +0 -1
- package/dist/data-plane/server/routes/site-standard.js +0 -9
- package/dist/data-plane/server/routes/site-standard.js.map +0 -1
|
@@ -1,16 +1,4 @@
|
|
|
1
|
-
import type { AtUriString } from '@atproto/syntax';
|
|
2
1
|
export declare const SITE_STANDARD_NSID_PREFIX = "site.standard.";
|
|
3
|
-
/**
|
|
4
|
-
* Composes a stable map key from an `(uri, cid)` pair. A single hydration
|
|
5
|
-
* batch can pull more than one version of the same SS record URI (different
|
|
6
|
-
* posts pinning different cids), so the composite is needed for O(1)
|
|
7
|
-
* version-exact lookups.
|
|
8
|
-
*/
|
|
9
|
-
export declare const siteStandardRecordKey: (uri: string, cid: string) => string;
|
|
10
|
-
export declare const parseSiteStandardRecordKey: (key: string) => {
|
|
11
|
-
uri: AtUriString;
|
|
12
|
-
cid: string;
|
|
13
|
-
};
|
|
14
2
|
/**
|
|
15
3
|
* Confirm that the supplied SS records actually back `assumedUrl`. The
|
|
16
4
|
* record-side URL is built by concatenating the publication URL (or the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standard-site.d.ts","sourceRoot":"","sources":["../../src/util/standard-site.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"standard-site.d.ts","sourceRoot":"","sources":["../../src/util/standard-site.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,mBAAmB,CAAA;AAgFzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,eAAO,MAAM,0BAA0B,aAEjC;IACE,GAAG,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IACpB,IAAI,EAAE;QAAE,MAAM,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;CAClD,GACD,SAAS,eAEX;IAAE,GAAG,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,IAAI,EAAE;QAAE,MAAM,EAAE;YAAE,GAAG,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;CAAE,GAAG,SAAS,cAC7D,MAAM,KACjB,OA2BF,CAAA;AAID;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,SAC/B,MAAM,KACX,MAAM,GAAG,SAIX,CAAA"}
|
|
@@ -1,18 +1,4 @@
|
|
|
1
1
|
export const SITE_STANDARD_NSID_PREFIX = 'site.standard.';
|
|
2
|
-
/**
|
|
3
|
-
* Composes a stable map key from an `(uri, cid)` pair. A single hydration
|
|
4
|
-
* batch can pull more than one version of the same SS record URI (different
|
|
5
|
-
* posts pinning different cids), so the composite is needed for O(1)
|
|
6
|
-
* version-exact lookups.
|
|
7
|
-
*/
|
|
8
|
-
export const siteStandardRecordKey = (uri, cid) => `${uri}@${cid}`;
|
|
9
|
-
export const parseSiteStandardRecordKey = (key) => {
|
|
10
|
-
const at = key.lastIndexOf('@');
|
|
11
|
-
return {
|
|
12
|
-
uri: key.slice(0, at),
|
|
13
|
-
cid: key.slice(at + 1),
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
2
|
/**
|
|
17
3
|
* Parse `url` as HTTP(S) and reduce it to a canonical
|
|
18
4
|
* `protocol://host/path` string for equality comparison: lowercases host,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standard-site.js","sourceRoot":"","sources":["../../src/util/standard-site.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AtUriString } from '@atproto/syntax'\n\nexport const SITE_STANDARD_NSID_PREFIX = 'site.standard.'\n\n/**\n * Composes a stable map key from an `(uri, cid)` pair. A single hydration\n * batch can pull more than one version of the same SS record URI (different\n * posts pinning different cids), so the composite is needed for O(1)\n * version-exact lookups.\n */\nexport const siteStandardRecordKey = (uri: string, cid: string) =>\n `${uri}@${cid}`\n\nexport const parseSiteStandardRecordKey = (\n key: string,\n): { uri: AtUriString; cid: string } => {\n const at = key.lastIndexOf('@')\n return {\n uri: key.slice(0, at) as AtUriString,\n cid: key.slice(at + 1),\n }\n}\n\n/**\n * Parse `url` as HTTP(S) and reduce it to a canonical\n * `protocol://host/path` string for equality comparison: lowercases host,\n * strips a trailing slash from the path, and drops query/fragment. Returns\n * `null` when the input isn't a valid HTTP(S) URL.\n */\nconst canonicalizeHttpUrl = (url: string): string | null => {\n let parsed: URL\n try {\n parsed = new URL(url)\n } catch {\n return null\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') return null\n const path = parsed.pathname === '/' ? '' : parsed.pathname.replace(/\\/$/, '')\n return `${parsed.protocol}//${parsed.host}${path}`\n}\n\n/**\n * Append `path` to `base` with exactly one slash between, or return `base`\n * unchanged when `path` is empty. Unlike `new URL(path, base)`, a leading\n * slash on `path` does NOT swallow `base`'s pathname — so\n * `joinPath('https://x.com/blog', '/foo')` is `https://x.com/blog/foo`,\n * not `https://x.com/foo`.\n */\nconst joinPath = (base: string, path: string): string => {\n if (!path) return base\n const baseTrimmed = base.endsWith('/') ? base.slice(0, -1) : base\n const pathTrimmed = path.startsWith('/') ? path.slice(1) : path\n return `${baseTrimmed}/${pathTrimmed}`\n}\n\n/**\n * Apex domains whose authors own the full subpath space under their\n * record-claimed URL. Each entry matches itself and any subdomain; e.g.\n * `pckt.blog` matches `pckt.blog` and `waow-tech.pckt.blog`.\n *\n * On these domains, an `assumedUrl` whose pathname extends the canonical\n * record URL with extra segments is treated as valid. Adding to this list\n * is a trust call — only platforms where each record's URL space is\n * authoritatively owned by its author belong here.\n */\nconst SUBPATH_FRIENDLY_DOMAINS = ['pckt.blog', 'leaflet.pub', 'offprint.app']\n\nconst isSubpathFriendlyHost = (host: string): boolean => {\n const lower = host.toLowerCase()\n return SUBPATH_FRIENDLY_DOMAINS.some(\n (domain) => lower === domain || lower.endsWith(`.${domain}`),\n )\n}\n\n/**\n * Return whether `recordUrl` and `assumedUrl` should validate as the same\n * canonical content. Strictly equal canonical forms always match. On\n * subpath-friendly hosts (see `SUBPATH_FRIENDLY_DOMAINS`), an `assumedUrl`\n * whose path extends `recordUrl`'s with extra segments is also accepted.\n *\n * Both inputs are pre-canonicalized strings (`canonicalizeHttpUrl` output)\n * with no trailing slash and no query/fragment.\n */\nconst canonicalUrlMatchesAssumed = (\n canonicalRecordUrl: string,\n canonicalAssumedUrl: string,\n): boolean => {\n if (canonicalRecordUrl === canonicalAssumedUrl) return true\n // Subpath fallback. Both strings are canonicalized, so a real\n // path-segment boundary at `recordUrl + '/'` (e.g. `/foo` vs `/foo-bar`\n // never matches; `/foo` vs `/foo/bar` does).\n if (!canonicalAssumedUrl.startsWith(`${canonicalRecordUrl}/`)) return false\n let host: string\n try {\n host = new URL(canonicalAssumedUrl).host\n } catch {\n return false\n }\n return isSubpathFriendlyHost(host)\n}\n\n/**\n * Confirm that the supplied SS records actually back `assumedUrl`. The\n * record-side URL is built by concatenating the publication URL (or the\n * loose-doc site) with the document's `path` field, then both sides are\n * canonicalized for equality: lowercase host, query/fragment dropped,\n * trailing slash stripped.\n *\n * Path concatenation is `base + '/' + path` semantics — a leading `/` on\n * `path` does NOT swallow the base's pathname (the way\n * `new URL(path, base)` would). So\n * `'https://atproto.com/blog' + '/indexing-standard-site'` resolves to\n * `https://atproto.com/blog/indexing-standard-site` regardless of which\n * side carries the slash.\n *\n * Structural validation of the doc/pub pair (matching `site` ↔ pub URI,\n * no orphan docs that claim a missing publication) happens upstream in\n * `getSiteStandardRecordsFromHydrationMapsByRefs` /\n * `…ByDocumentUri` (see `hydration/external.ts`); by the time this\n * function runs the pair is already known to be structurally consistent,\n * so we only check whether the records back the URL.\n *\n * For document validation, `SUBPATH_FRIENDLY_DOMAINS` (and their\n * subdomains) accept an assumed URL whose path extends the canonical\n * record URL with additional segments — these are platforms where each\n * record's author owns the full subpath space under their claimed URL.\n * Publication-only validation always requires exact match: there's no\n * coherent \"subpath\" of a publication's home page.\n *\n * Cases:\n * - Document + publication: `publication.url + document.path` must\n * canonicalize to `assumedUrl` (or be a subpath-friendly prefix of it).\n * - Loose document (web-URL `site`): `document.site + document.path`\n * must canonicalize to `assumedUrl` (or be a subpath-friendly prefix).\n * (Doc with at-uri `site` but no publication can't reach this function\n * — the lookups reject it.)\n * - Publication only: `publication.url` must canonicalize exactly to\n * `assumedUrl`.\n * - Neither: vacuously valid; the caller short-circuits before we get\n * here.\n */\nexport const validateStandardSiteForUrl = (\n document:\n | {\n ref: { uri: string }\n info: { record: { site: string; path?: string } }\n }\n | undefined,\n publication:\n { ref: { uri: string }; info: { record: { url: string } } } | undefined,\n assumedUrl: string,\n): boolean => {\n const canonicalAssumed = canonicalizeHttpUrl(assumedUrl)\n if (canonicalAssumed === null) return false\n\n if (document && publication) {\n const joined = canonicalizeHttpUrl(\n joinPath(publication.info.record.url, document.info.record.path ?? ''),\n )\n return (\n joined !== null && canonicalUrlMatchesAssumed(joined, canonicalAssumed)\n )\n }\n if (document) {\n const joined = canonicalizeHttpUrl(\n joinPath(document.info.record.site, document.info.record.path ?? ''),\n )\n return (\n joined !== null && canonicalUrlMatchesAssumed(joined, canonicalAssumed)\n )\n }\n if (publication) {\n // Publication-only matches are exact: `assumedUrl` represents the\n // publication's home page, not an article underneath it. Subpath\n // extensions belong to document validation.\n return canonicalizeHttpUrl(publication.info.record.url) === canonicalAssumed\n }\n return true\n}\n\nconst WORDS_PER_MINUTE = 200\n\n/**\n * Estimate reading time in minutes from a plaintext document body. Returns\n * `undefined` when the input has no countable words. Uses a coarse\n * `WORDS_PER_MINUTE` heuristic; swap in a more accurate library here if\n * needed (e.g. `reading-time`).\n */\nexport const estimateReadingTimeMinutes = (\n text: string,\n): number | undefined => {\n const words = text.trim().split(/\\s+/).filter(Boolean).length\n if (!words) return undefined\n return Math.max(1, Math.ceil(words / WORDS_PER_MINUTE))\n}\n"]}
|
|
1
|
+
{"version":3,"file":"standard-site.js","sourceRoot":"","sources":["../../src/util/standard-site.ts"],"names":[],"mappings":"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","sourcesContent":["export const SITE_STANDARD_NSID_PREFIX = 'site.standard.'\n\n/**\n * Parse `url` as HTTP(S) and reduce it to a canonical\n * `protocol://host/path` string for equality comparison: lowercases host,\n * strips a trailing slash from the path, and drops query/fragment. Returns\n * `null` when the input isn't a valid HTTP(S) URL.\n */\nconst canonicalizeHttpUrl = (url: string): string | null => {\n let parsed: URL\n try {\n parsed = new URL(url)\n } catch {\n return null\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') return null\n const path = parsed.pathname === '/' ? '' : parsed.pathname.replace(/\\/$/, '')\n return `${parsed.protocol}//${parsed.host}${path}`\n}\n\n/**\n * Append `path` to `base` with exactly one slash between, or return `base`\n * unchanged when `path` is empty. Unlike `new URL(path, base)`, a leading\n * slash on `path` does NOT swallow `base`'s pathname — so\n * `joinPath('https://x.com/blog', '/foo')` is `https://x.com/blog/foo`,\n * not `https://x.com/foo`.\n */\nconst joinPath = (base: string, path: string): string => {\n if (!path) return base\n const baseTrimmed = base.endsWith('/') ? base.slice(0, -1) : base\n const pathTrimmed = path.startsWith('/') ? path.slice(1) : path\n return `${baseTrimmed}/${pathTrimmed}`\n}\n\n/**\n * Apex domains whose authors own the full subpath space under their\n * record-claimed URL. Each entry matches itself and any subdomain; e.g.\n * `pckt.blog` matches `pckt.blog` and `waow-tech.pckt.blog`.\n *\n * On these domains, an `assumedUrl` whose pathname extends the canonical\n * record URL with extra segments is treated as valid. Adding to this list\n * is a trust call — only platforms where each record's URL space is\n * authoritatively owned by its author belong here.\n */\nconst SUBPATH_FRIENDLY_DOMAINS = ['pckt.blog', 'leaflet.pub', 'offprint.app']\n\nconst isSubpathFriendlyHost = (host: string): boolean => {\n const lower = host.toLowerCase()\n return SUBPATH_FRIENDLY_DOMAINS.some(\n (domain) => lower === domain || lower.endsWith(`.${domain}`),\n )\n}\n\n/**\n * Return whether `recordUrl` and `assumedUrl` should validate as the same\n * canonical content. Strictly equal canonical forms always match. On\n * subpath-friendly hosts (see `SUBPATH_FRIENDLY_DOMAINS`), an `assumedUrl`\n * whose path extends `recordUrl`'s with extra segments is also accepted.\n *\n * Both inputs are pre-canonicalized strings (`canonicalizeHttpUrl` output)\n * with no trailing slash and no query/fragment.\n */\nconst canonicalUrlMatchesAssumed = (\n canonicalRecordUrl: string,\n canonicalAssumedUrl: string,\n): boolean => {\n if (canonicalRecordUrl === canonicalAssumedUrl) return true\n // Subpath fallback. Both strings are canonicalized, so a real\n // path-segment boundary at `recordUrl + '/'` (e.g. `/foo` vs `/foo-bar`\n // never matches; `/foo` vs `/foo/bar` does).\n if (!canonicalAssumedUrl.startsWith(`${canonicalRecordUrl}/`)) return false\n let host: string\n try {\n host = new URL(canonicalAssumedUrl).host\n } catch {\n return false\n }\n return isSubpathFriendlyHost(host)\n}\n\n/**\n * Confirm that the supplied SS records actually back `assumedUrl`. The\n * record-side URL is built by concatenating the publication URL (or the\n * loose-doc site) with the document's `path` field, then both sides are\n * canonicalized for equality: lowercase host, query/fragment dropped,\n * trailing slash stripped.\n *\n * Path concatenation is `base + '/' + path` semantics — a leading `/` on\n * `path` does NOT swallow the base's pathname (the way\n * `new URL(path, base)` would). So\n * `'https://atproto.com/blog' + '/indexing-standard-site'` resolves to\n * `https://atproto.com/blog/indexing-standard-site` regardless of which\n * side carries the slash.\n *\n * Structural validation of the doc/pub pair (matching `site` ↔ pub URI,\n * no orphan docs that claim a missing publication) happens upstream in\n * `getSiteStandardRecordsFromHydrationMapsByRefs` /\n * `…ByDocumentUri` (see `hydration/external.ts`); by the time this\n * function runs the pair is already known to be structurally consistent,\n * so we only check whether the records back the URL.\n *\n * For document validation, `SUBPATH_FRIENDLY_DOMAINS` (and their\n * subdomains) accept an assumed URL whose path extends the canonical\n * record URL with additional segments — these are platforms where each\n * record's author owns the full subpath space under their claimed URL.\n * Publication-only validation always requires exact match: there's no\n * coherent \"subpath\" of a publication's home page.\n *\n * Cases:\n * - Document + publication: `publication.url + document.path` must\n * canonicalize to `assumedUrl` (or be a subpath-friendly prefix of it).\n * - Loose document (web-URL `site`): `document.site + document.path`\n * must canonicalize to `assumedUrl` (or be a subpath-friendly prefix).\n * (Doc with at-uri `site` but no publication can't reach this function\n * — the lookups reject it.)\n * - Publication only: `publication.url` must canonicalize exactly to\n * `assumedUrl`.\n * - Neither: vacuously valid; the caller short-circuits before we get\n * here.\n */\nexport const validateStandardSiteForUrl = (\n document:\n | {\n ref: { uri: string }\n info: { record: { site: string; path?: string } }\n }\n | undefined,\n publication:\n { ref: { uri: string }; info: { record: { url: string } } } | undefined,\n assumedUrl: string,\n): boolean => {\n const canonicalAssumed = canonicalizeHttpUrl(assumedUrl)\n if (canonicalAssumed === null) return false\n\n if (document && publication) {\n const joined = canonicalizeHttpUrl(\n joinPath(publication.info.record.url, document.info.record.path ?? ''),\n )\n return (\n joined !== null && canonicalUrlMatchesAssumed(joined, canonicalAssumed)\n )\n }\n if (document) {\n const joined = canonicalizeHttpUrl(\n joinPath(document.info.record.site, document.info.record.path ?? ''),\n )\n return (\n joined !== null && canonicalUrlMatchesAssumed(joined, canonicalAssumed)\n )\n }\n if (publication) {\n // Publication-only matches are exact: `assumedUrl` represents the\n // publication's home page, not an article underneath it. Subpath\n // extensions belong to document validation.\n return canonicalizeHttpUrl(publication.info.record.url) === canonicalAssumed\n }\n return true\n}\n\nconst WORDS_PER_MINUTE = 200\n\n/**\n * Estimate reading time in minutes from a plaintext document body. Returns\n * `undefined` when the input has no countable words. Uses a coarse\n * `WORDS_PER_MINUTE` heuristic; swap in a more accurate library here if\n * needed (e.g. `reading-time`).\n */\nexport const estimateReadingTimeMinutes = (\n text: string,\n): number | undefined => {\n const words = text.trim().split(/\\s+/).filter(Boolean).length\n if (!words) return undefined\n return Math.max(1, Math.ceil(words / WORDS_PER_MINUTE))\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/bsky",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Reference implementation of app.bsky App View (Bluesky API)",
|
|
6
6
|
"keywords": [
|
|
@@ -71,18 +71,18 @@
|
|
|
71
71
|
"undici_v8": "npm:undici@^8.x",
|
|
72
72
|
"zod": "3.23.8",
|
|
73
73
|
"@atproto-labs/fetch-node": "^0.4.0",
|
|
74
|
+
"@atproto-labs/opentelemetry-node": "^0.3.1",
|
|
74
75
|
"@atproto-labs/xrpc-utils": "^0.1.25",
|
|
75
|
-
"@atproto
|
|
76
|
-
"@atproto/api": "^0.23.1",
|
|
77
|
-
"@atproto/crypto": "^0.5.7",
|
|
76
|
+
"@atproto/api": "^0.24.0",
|
|
78
77
|
"@atproto/common": "^0.8.5",
|
|
79
|
-
"@atproto/
|
|
78
|
+
"@atproto/crypto": "^0.5.7",
|
|
80
79
|
"@atproto/identity": "^0.5.16",
|
|
80
|
+
"@atproto/did": "^0.5.6",
|
|
81
|
+
"@atproto/lex": "^0.3.14",
|
|
81
82
|
"@atproto/repo": "^0.11.0",
|
|
82
83
|
"@atproto/sync": "^0.4.13",
|
|
83
|
-
"@atproto/syntax": "^0.7.6",
|
|
84
84
|
"@atproto/xrpc-server": "^0.13.4",
|
|
85
|
-
"@atproto/
|
|
85
|
+
"@atproto/syntax": "^0.7.6"
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
88
|
"@bufbuild/buf": "^1.73.0",
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"@types/pg": "^8.15.5",
|
|
97
97
|
"@types/qs": "^6.15.1",
|
|
98
98
|
"vitest": "^4.1.10",
|
|
99
|
-
"@atproto/pds": "^0.5.
|
|
99
|
+
"@atproto/pds": "^0.5.38"
|
|
100
100
|
},
|
|
101
101
|
"scripts": {
|
|
102
102
|
"codegen:buf": "buf generate ../bsync/proto && buf generate ./proto",
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { ServiceImpl } from '@connectrpc/connect';
|
|
2
|
-
import type { Service } from '../../../proto/bsky_connect.js';
|
|
3
|
-
import type { Database } from '../db/index.js';
|
|
4
|
-
export default _default;
|
|
5
|
-
declare function _default(_db: Database): Partial<ServiceImpl<typeof Service>>;
|
|
6
|
-
//# sourceMappingURL=site-standard.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"site-standard.d.ts","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/site-standard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;;0BAE9B,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"site-standard.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/site-standard.ts"],"names":[],"mappings":"AAIA,eAAe,CAAC,GAAa,EAAwC,EAAE,CAAC,CAAC;IACvE,KAAK,CAAC,2BAA2B;QAC/B,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,CAAA;IAC5C,CAAC;IACD,KAAK,CAAC,2BAA2B;QAC/B,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,CAAA;IAC5C,CAAC;CACF,CAAC,CAAA","sourcesContent":["import type { ServiceImpl } from '@connectrpc/connect'\nimport type { Service } from '../../../proto/bsky_connect.js'\nimport type { Database } from '../db/index.js'\n\nexport default (_db: Database): Partial<ServiceImpl<typeof Service>> => ({\n async getSiteStandardRecordsByURI() {\n return { documents: [], publications: [] }\n },\n async getSiteStandardRecordsByRef() {\n return { documents: [], publications: [] }\n },\n})\n"]}
|