@bunizao/contracts 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/comments.d.ts +36 -50
- package/dist/comments.js +6 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +10 -3
- package/dist/instagram.d.ts +29 -0
- package/dist/instagram.js +0 -0
- package/dist/routes.d.ts +2 -0
- package/dist/routes.js +4 -0
- package/package.json +6 -1
package/dist/comments.d.ts
CHANGED
|
@@ -104,9 +104,10 @@ export interface ReaderMuteResult {
|
|
|
104
104
|
so this can never be used to probe which addresses have commented. */
|
|
105
105
|
export interface ReaderResendInput {
|
|
106
106
|
email: string;
|
|
107
|
-
/**
|
|
108
|
-
verification link
|
|
109
|
-
a
|
|
107
|
+
/** Newsletter opt-in, despite the name: carried into the fresh
|
|
108
|
+
verification link from the stale token's payload, and confirming the
|
|
109
|
+
address activates a newsletter subscription. Not the reply-mail switch
|
|
110
|
+
(that is `ReaderMe.notifyReplies`). Optional; a bare resend sends false. */
|
|
110
111
|
notifyReplies?: boolean;
|
|
111
112
|
locale?: CommentLocale;
|
|
112
113
|
}
|
|
@@ -379,8 +380,10 @@ export interface CommentCreateInput {
|
|
|
379
380
|
/** Signed server timestamp minted at first interaction with the compose
|
|
380
381
|
box — see "The risk stack" step 4 (dwell time). */
|
|
381
382
|
dwellToken: string;
|
|
382
|
-
/**
|
|
383
|
-
|
|
383
|
+
/** Newsletter opt-in, despite the name: the reader accepted the
|
|
384
|
+
post-comment subscribe offer, and confirming the address activates a
|
|
385
|
+
newsletter subscription. Not the reply-mail switch (that is
|
|
386
|
+
`ReaderMe.notifyReplies`). Both clients send false. */
|
|
384
387
|
notifyReplies?: boolean;
|
|
385
388
|
locale?: CommentLocale;
|
|
386
389
|
/** Client evidence, optional and never a gate -- see `ClientEvidence`. */
|
|
@@ -438,47 +441,10 @@ export interface CommentPolicy {
|
|
|
438
441
|
requireVerifiedEmail: boolean;
|
|
439
442
|
}
|
|
440
443
|
export declare const DEFAULT_COMMENT_POLICY: CommentPolicy;
|
|
441
|
-
/** Ghost internal tags that override the site-wide default, one knob each.
|
|
442
|
-
*
|
|
443
|
-
* Internal tags are the switch because they are the only per-post field the
|
|
444
|
-
* author already edits in Ghost, and both halves of the system can read them:
|
|
445
|
-
* the site sees them through the Admin API at build time, site-api through the
|
|
446
|
-
* Content API at request time (`include=tags` returns internal tags). One
|
|
447
|
-
* source of truth, no settings table, no admin screen to keep in sync.
|
|
448
|
-
*
|
|
449
|
-
* `#no-comments` predates the others and is kept: it always meant "this post
|
|
450
|
-
* takes no more comments", which is `readonly`. */
|
|
451
444
|
export declare const COMMENT_POLICY_TAGS: {
|
|
452
|
-
readonly 'comments-off': (policy: CommentPolicy) =>
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
an open thread can refuse them. */
|
|
456
|
-
reactions: boolean;
|
|
457
|
-
/** Accept a comment only from an address that has been verified. Anonymous
|
|
458
|
-
and unverified-email writers are refused rather than held. */
|
|
459
|
-
requireVerifiedEmail: boolean;
|
|
460
|
-
mode: CommentsMode;
|
|
461
|
-
};
|
|
462
|
-
readonly 'comments-readonly': (policy: CommentPolicy) => {
|
|
463
|
-
/** Whether the heart can be pressed — on the post and on its comments.
|
|
464
|
-
Independent of `mode`: a post can take reactions with comments off, and
|
|
465
|
-
an open thread can refuse them. */
|
|
466
|
-
reactions: boolean;
|
|
467
|
-
/** Accept a comment only from an address that has been verified. Anonymous
|
|
468
|
-
and unverified-email writers are refused rather than held. */
|
|
469
|
-
requireVerifiedEmail: boolean;
|
|
470
|
-
mode: CommentsMode;
|
|
471
|
-
};
|
|
472
|
-
readonly 'no-comments': (policy: CommentPolicy) => {
|
|
473
|
-
/** Whether the heart can be pressed — on the post and on its comments.
|
|
474
|
-
Independent of `mode`: a post can take reactions with comments off, and
|
|
475
|
-
an open thread can refuse them. */
|
|
476
|
-
reactions: boolean;
|
|
477
|
-
/** Accept a comment only from an address that has been verified. Anonymous
|
|
478
|
-
and unverified-email writers are refused rather than held. */
|
|
479
|
-
requireVerifiedEmail: boolean;
|
|
480
|
-
mode: CommentsMode;
|
|
481
|
-
};
|
|
445
|
+
readonly 'comments-off': (policy: CommentPolicy) => CommentPolicy;
|
|
446
|
+
readonly 'comments-readonly': (policy: CommentPolicy) => CommentPolicy;
|
|
447
|
+
readonly 'no-comments': (policy: CommentPolicy) => CommentPolicy;
|
|
482
448
|
readonly 'reactions-off': (policy: CommentPolicy) => {
|
|
483
449
|
mode: CommentsMode;
|
|
484
450
|
/** Accept a comment only from an address that has been verified. Anonymous
|
|
@@ -502,7 +468,8 @@ export interface CommentPolicyTagLike {
|
|
|
502
468
|
slug?: string | null;
|
|
503
469
|
}
|
|
504
470
|
/** Fold a post's tags onto the site-wide default. Order does not matter:
|
|
505
|
-
every tag sets one field,
|
|
471
|
+
every tag sets one field, conflicting mode tags keep the stricter mode, and
|
|
472
|
+
a tag the map does not know is ignored. */
|
|
506
473
|
export declare function commentPolicyFromTags(tags: readonly CommentPolicyTagLike[] | null | undefined, base?: CommentPolicy): CommentPolicy;
|
|
507
474
|
/** Whether the post takes new comments — the one question the API asks. Both
|
|
508
475
|
`readonly` and `off` answer no; the difference between them is drawn, not
|
|
@@ -547,17 +514,36 @@ export declare function avatarClass(seed: number): number;
|
|
|
547
514
|
/** A seed in colour class `cls`; `variety` fills the digits that pick the
|
|
548
515
|
expression, pose and head shape. */
|
|
549
516
|
export declare function seedInClass(cls: number, variety: number): number;
|
|
550
|
-
/**
|
|
517
|
+
/** How many faces an `offer` holds. */
|
|
518
|
+
export declare const AVATAR_OFFER_SIZE = 5;
|
|
519
|
+
/** POST body for `READER_AVATAR_SEED_PATH`.
|
|
520
|
+
|
|
521
|
+
- `issue` (the default): one seed, handed out and counted. The first face
|
|
522
|
+
a browser gets.
|
|
523
|
+
- `offer`: AVATAR_OFFER_SIZE candidates to choose from, nothing counted
|
|
524
|
+
or kept -- a reader browsing faces has not taken one yet.
|
|
525
|
+
- `choose`: `seed` becomes the caller's face, counted and, for a verified
|
|
526
|
+
reader, kept. */
|
|
551
527
|
export interface AvatarSeedInput {
|
|
552
|
-
/** The seed on screen now.
|
|
553
|
-
|
|
528
|
+
/** The seed on screen now. `issue` and `offer` always answer in other
|
|
529
|
+
colour classes, so every new face visibly changes. */
|
|
554
530
|
current?: number | null;
|
|
531
|
+
mode?: 'issue' | 'offer' | 'choose';
|
|
532
|
+
/** Required for `choose`. */
|
|
533
|
+
seed?: number;
|
|
555
534
|
}
|
|
535
|
+
/** The answer to `issue` and `choose`. */
|
|
556
536
|
export interface AvatarSeedResult {
|
|
557
|
-
/**
|
|
537
|
+
/** For `issue`, in the least-used colour class across the site, never
|
|
538
|
+
`current`'s. For `choose`, the seed that was sent. */
|
|
558
539
|
seed: number;
|
|
559
540
|
/** True when the caller is a verified reader and the seed is now theirs
|
|
560
541
|
everywhere. False for anyone else: the client keeps it and sends it as
|
|
561
542
|
`CommentCreateInput.avatarSeed`. */
|
|
562
543
|
persisted: boolean;
|
|
563
544
|
}
|
|
545
|
+
/** The answer to `offer`: one seed in each of the AVATAR_OFFER_SIZE
|
|
546
|
+
least-used colour classes, none of them `current`'s. */
|
|
547
|
+
export interface AvatarSeedOfferResult {
|
|
548
|
+
seeds: number[];
|
|
549
|
+
}
|
package/dist/comments.js
CHANGED
|
@@ -32,10 +32,11 @@ var DEFAULT_COMMENT_POLICY = {
|
|
|
32
32
|
reactions: true,
|
|
33
33
|
requireVerifiedEmail: false
|
|
34
34
|
};
|
|
35
|
+
var withStricterMode = (policy, mode) => COMMENTS_MODES.indexOf(mode) > COMMENTS_MODES.indexOf(policy.mode) ? { ...policy, mode } : policy;
|
|
35
36
|
var COMMENT_POLICY_TAGS = {
|
|
36
|
-
"comments-off": (policy) => (
|
|
37
|
-
"comments-readonly": (policy) => (
|
|
38
|
-
"no-comments": (policy) => (
|
|
37
|
+
"comments-off": (policy) => withStricterMode(policy, "off"),
|
|
38
|
+
"comments-readonly": (policy) => withStricterMode(policy, "readonly"),
|
|
39
|
+
"no-comments": (policy) => withStricterMode(policy, "readonly"),
|
|
39
40
|
"reactions-off": (policy) => ({ ...policy, reactions: false }),
|
|
40
41
|
"comments-verified": (policy) => ({ ...policy, requireVerifiedEmail: true })
|
|
41
42
|
};
|
|
@@ -73,8 +74,10 @@ function seedInClass(cls, variety) {
|
|
|
73
74
|
const span = Math.floor(MAX_AVATAR_SEED / AVATAR_CLASSES);
|
|
74
75
|
return Math.abs(Math.trunc(variety)) % span * AVATAR_CLASSES + Math.abs(Math.trunc(cls)) % AVATAR_CLASSES;
|
|
75
76
|
}
|
|
77
|
+
var AVATAR_OFFER_SIZE = 5;
|
|
76
78
|
export {
|
|
77
79
|
AVATAR_CLASSES,
|
|
80
|
+
AVATAR_OFFER_SIZE,
|
|
78
81
|
COMMENTS_MODES,
|
|
79
82
|
COMMENT_ANCHOR_PATTERN,
|
|
80
83
|
COMMENT_ANCHOR_TOKEN_LENGTH,
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -44,10 +44,11 @@ var DEFAULT_COMMENT_POLICY = {
|
|
|
44
44
|
reactions: true,
|
|
45
45
|
requireVerifiedEmail: false
|
|
46
46
|
};
|
|
47
|
+
var withStricterMode = (policy, mode) => COMMENTS_MODES.indexOf(mode) > COMMENTS_MODES.indexOf(policy.mode) ? { ...policy, mode } : policy;
|
|
47
48
|
var COMMENT_POLICY_TAGS = {
|
|
48
|
-
"comments-off": (policy) => (
|
|
49
|
-
"comments-readonly": (policy) => (
|
|
50
|
-
"no-comments": (policy) => (
|
|
49
|
+
"comments-off": (policy) => withStricterMode(policy, "off"),
|
|
50
|
+
"comments-readonly": (policy) => withStricterMode(policy, "readonly"),
|
|
51
|
+
"no-comments": (policy) => withStricterMode(policy, "readonly"),
|
|
51
52
|
"reactions-off": (policy) => ({ ...policy, reactions: false }),
|
|
52
53
|
"comments-verified": (policy) => ({ ...policy, requireVerifiedEmail: true })
|
|
53
54
|
};
|
|
@@ -85,6 +86,7 @@ function seedInClass(cls, variety) {
|
|
|
85
86
|
const span = Math.floor(MAX_AVATAR_SEED / AVATAR_CLASSES);
|
|
86
87
|
return Math.abs(Math.trunc(variety)) % span * AVATAR_CLASSES + Math.abs(Math.trunc(cls)) % AVATAR_CLASSES;
|
|
87
88
|
}
|
|
89
|
+
var AVATAR_OFFER_SIZE = 5;
|
|
88
90
|
// src/content.ts
|
|
89
91
|
var CONTENT_DOCUMENT_SOURCES = ["mood", "post"];
|
|
90
92
|
var POST_LOCALE_RE = /^[a-z]{2,8}(?:-[a-z0-9]{1,8})*$/;
|
|
@@ -131,6 +133,8 @@ var MOOD_SEARCH_PATH = "/v2/mood/search";
|
|
|
131
133
|
var MOOD_IMAGE_PROXY_BASE_PATH = "/v2/images";
|
|
132
134
|
var MOOD_MEDIA_PROXY_BASE_PATH = "/v2/media";
|
|
133
135
|
var LISTENING_PATH = "/v2/listening";
|
|
136
|
+
var INSTAGRAM_PROFILE_PATH = "/v2/instagram";
|
|
137
|
+
var INSTAGRAM_AVATAR_PATH = "/v2/instagram/avatar";
|
|
134
138
|
var COMMENTS_PATH = "/v2/comments";
|
|
135
139
|
var COMMENT_PATH_PREFIX = "/v2/comments/";
|
|
136
140
|
var OWNER_MESSAGES_PATH = "/v2/messages";
|
|
@@ -217,6 +221,7 @@ export {
|
|
|
217
221
|
ADMIN_BASE_PATH,
|
|
218
222
|
API_PREFIX,
|
|
219
223
|
AVATAR_CLASSES,
|
|
224
|
+
AVATAR_OFFER_SIZE,
|
|
220
225
|
BLOG_ANALYTICS_ARTICLE_ENDPOINT,
|
|
221
226
|
BLOG_ANALYTICS_COMPLETION_SCROLL_DEPTH,
|
|
222
227
|
BLOG_ANALYTICS_EVENTS_DEFAULT_LIMIT,
|
|
@@ -241,6 +246,8 @@ export {
|
|
|
241
246
|
EVENT_STATUSES,
|
|
242
247
|
GHOST_WEBHOOK_PATH,
|
|
243
248
|
HEALTH_PATH,
|
|
249
|
+
INSTAGRAM_AVATAR_PATH,
|
|
250
|
+
INSTAGRAM_PROFILE_PATH,
|
|
244
251
|
LEGACY_ADMIN_BASE_PATH,
|
|
245
252
|
LEGACY_GHOST_WEBHOOK_PATH,
|
|
246
253
|
LEGACY_HEALTH_PATH,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface InstagramProfileCounts {
|
|
2
|
+
posts: number;
|
|
3
|
+
followers: number;
|
|
4
|
+
following: number;
|
|
5
|
+
}
|
|
6
|
+
export interface InstagramProfileAvatar {
|
|
7
|
+
/** Absolute URL of the stored picture, served by site-api. */
|
|
8
|
+
url: string;
|
|
9
|
+
contentType: string;
|
|
10
|
+
bytes: number;
|
|
11
|
+
/** Hex SHA-256 of the stored bytes; the avatar route sends it as the ETag. */
|
|
12
|
+
sha256: string;
|
|
13
|
+
}
|
|
14
|
+
export interface InstagramProfileAttempt {
|
|
15
|
+
at: string;
|
|
16
|
+
ok: boolean;
|
|
17
|
+
/** Why the attempt failed, e.g. `profile:401`; null when it succeeded. */
|
|
18
|
+
error: string | null;
|
|
19
|
+
}
|
|
20
|
+
export interface InstagramProfile {
|
|
21
|
+
username: string;
|
|
22
|
+
fullName: string;
|
|
23
|
+
profileUrl: string;
|
|
24
|
+
avatar: InstagramProfileAvatar;
|
|
25
|
+
counts: InstagramProfileCounts;
|
|
26
|
+
/** When the stored profile was last read from Instagram. */
|
|
27
|
+
refreshedAt: string;
|
|
28
|
+
lastAttempt: InstagramProfileAttempt;
|
|
29
|
+
}
|
|
File without changes
|
package/dist/routes.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export declare const MOOD_SEARCH_PATH: '/v2/mood/search';
|
|
|
12
12
|
export declare const MOOD_IMAGE_PROXY_BASE_PATH: '/v2/images';
|
|
13
13
|
export declare const MOOD_MEDIA_PROXY_BASE_PATH: '/v2/media';
|
|
14
14
|
export declare const LISTENING_PATH: '/v2/listening';
|
|
15
|
+
export declare const INSTAGRAM_PROFILE_PATH: '/v2/instagram';
|
|
16
|
+
export declare const INSTAGRAM_AVATAR_PATH: '/v2/instagram/avatar';
|
|
15
17
|
export declare const COMMENTS_PATH: '/v2/comments';
|
|
16
18
|
export declare const COMMENT_PATH_PREFIX: '/v2/comments/';
|
|
17
19
|
export declare const OWNER_MESSAGES_PATH: '/v2/messages';
|
package/dist/routes.js
CHANGED
|
@@ -13,6 +13,8 @@ var MOOD_SEARCH_PATH = "/v2/mood/search";
|
|
|
13
13
|
var MOOD_IMAGE_PROXY_BASE_PATH = "/v2/images";
|
|
14
14
|
var MOOD_MEDIA_PROXY_BASE_PATH = "/v2/media";
|
|
15
15
|
var LISTENING_PATH = "/v2/listening";
|
|
16
|
+
var INSTAGRAM_PROFILE_PATH = "/v2/instagram";
|
|
17
|
+
var INSTAGRAM_AVATAR_PATH = "/v2/instagram/avatar";
|
|
16
18
|
var COMMENTS_PATH = "/v2/comments";
|
|
17
19
|
var COMMENT_PATH_PREFIX = "/v2/comments/";
|
|
18
20
|
var OWNER_MESSAGES_PATH = "/v2/messages";
|
|
@@ -45,6 +47,8 @@ export {
|
|
|
45
47
|
COMMENT_PATH_PREFIX,
|
|
46
48
|
GHOST_WEBHOOK_PATH,
|
|
47
49
|
HEALTH_PATH,
|
|
50
|
+
INSTAGRAM_AVATAR_PATH,
|
|
51
|
+
INSTAGRAM_PROFILE_PATH,
|
|
48
52
|
LEGACY_ADMIN_BASE_PATH,
|
|
49
53
|
LEGACY_GHOST_WEBHOOK_PATH,
|
|
50
54
|
LEGACY_HEALTH_PATH,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bunizao/contracts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Shared TypeScript contracts for buxx.me services and clients.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -48,6 +48,11 @@
|
|
|
48
48
|
"import": "./dist/content.js",
|
|
49
49
|
"default": "./dist/content.js"
|
|
50
50
|
},
|
|
51
|
+
"./instagram": {
|
|
52
|
+
"types": "./dist/instagram.d.ts",
|
|
53
|
+
"import": "./dist/instagram.js",
|
|
54
|
+
"default": "./dist/instagram.js"
|
|
55
|
+
},
|
|
51
56
|
"./listening": {
|
|
52
57
|
"types": "./dist/listening.d.ts",
|
|
53
58
|
"import": "./dist/listening.js",
|