graze-client 0.8.0 → 0.9.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/build/dts/GrazeClient.d.ts +368 -242
- package/build/dts/GrazeClient.d.ts.map +1 -1
- package/build/dts/builder.d.ts +8 -8
- package/build/dts/builder.d.ts.map +1 -1
- package/build/dts/common.d.ts +2 -3
- package/build/dts/common.d.ts.map +1 -1
- package/build/dts/index.d.ts +13 -13
- package/build/dts/index.d.ts.map +1 -1
- package/build/dts/schema/Post.d.ts +52 -52
- package/build/dts/schema/StickyPosts.d.ts +55 -56
- package/build/dts/schema/StickyPosts.d.ts.map +1 -1
- package/build/dts/schema/UpdateAlgorithmPayload.d.ts +187 -163
- package/build/dts/schema/UpdateAlgorithmPayload.d.ts.map +1 -1
- package/build/dts/schema/shared.d.ts +127 -127
- package/build/dts/schema/shared.d.ts.map +1 -1
- package/build/dts/stickyposts.d.ts +80 -78
- package/build/dts/stickyposts.d.ts.map +1 -1
- package/build/esm/GrazeClient.js +45 -29
- package/build/esm/GrazeClient.js.map +1 -1
- package/build/esm/builder.js +2 -2
- package/build/esm/builder.js.map +1 -1
- package/build/esm/common.js +4 -3
- package/build/esm/common.js.map +1 -1
- package/build/esm/index.js +8 -5
- package/build/esm/index.js.map +1 -1
- package/build/esm/schema/Post.js +6 -6
- package/build/esm/schema/Post.js.map +1 -1
- package/build/esm/schema/StickyPosts.js +2 -3
- package/build/esm/schema/StickyPosts.js.map +1 -1
- package/build/esm/schema/UpdateAlgorithmPayload.js +116 -39
- package/build/esm/schema/UpdateAlgorithmPayload.js.map +1 -1
- package/build/esm/schema/shared.js +6 -6
- package/build/esm/schema/shared.js.map +1 -1
- package/build/esm/stickyposts.js +28 -13
- package/build/esm/stickyposts.js.map +1 -1
- package/package.json +8 -10
- package/src/GrazeClient.ts +55 -47
- package/src/builder.ts +14 -14
- package/src/common.ts +4 -9
- package/src/index.ts +24 -19
- package/src/schema/Post.ts +6 -6
- package/src/schema/StickyPosts.ts +3 -7
- package/src/schema/UpdateAlgorithmPayload.ts +80 -67
- package/src/schema/shared.ts +6 -6
- package/src/stickyposts.ts +44 -23
package/src/GrazeClient.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Config, Context, Data, Effect, Layer, Redacted, Schema } from "effect";
|
|
1
2
|
import {
|
|
2
3
|
AlgoUpdateResponse,
|
|
3
4
|
GetAlgoResponse,
|
|
@@ -5,21 +6,18 @@ import {
|
|
|
5
6
|
HidePostBody,
|
|
6
7
|
UnhidePostBody,
|
|
7
8
|
} from "./schema/shared.js";
|
|
8
|
-
import {
|
|
9
|
-
FetchHttpClient,
|
|
10
|
-
HttpApi,
|
|
11
|
-
HttpApiClient,
|
|
12
|
-
HttpApiEndpoint,
|
|
13
|
-
HttpApiGroup,
|
|
14
|
-
HttpApiSchema,
|
|
15
|
-
HttpClient,
|
|
16
|
-
HttpClientRequest,
|
|
17
|
-
} from "@effect/platform";
|
|
18
|
-
import { Config, Data, Effect, Redacted, Schema } from "effect";
|
|
19
9
|
|
|
20
|
-
import * as Form from "./schema/UpdateAlgorithmPayload.js";
|
|
21
10
|
import { FeedIdParam, UserIdParam } from "./common.js";
|
|
11
|
+
import * as Form from "./schema/UpdateAlgorithmPayload.js";
|
|
22
12
|
import { StickyPostsApiGroup } from "./stickyposts.js";
|
|
13
|
+
import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
|
|
14
|
+
import * as HttpApi from "effect/unstable/httpapi/HttpApi";
|
|
15
|
+
import * as HttpApiClient from "effect/unstable/httpapi/HttpApiClient";
|
|
16
|
+
import * as HttpApiEndpoint from "effect/unstable/httpapi/HttpApiEndpoint";
|
|
17
|
+
import * as HttpApiGroup from "effect/unstable/httpapi/HttpApiGroup";
|
|
18
|
+
import * as HttpApiSchema from "effect/unstable/httpapi/HttpApiSchema";
|
|
19
|
+
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
20
|
+
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
|
|
23
21
|
|
|
24
22
|
function isStringOrBlob(val: unknown): val is string | Blob {
|
|
25
23
|
return typeof val === "string" || val instanceof Blob;
|
|
@@ -27,10 +25,10 @@ function isStringOrBlob(val: unknown): val is string | Blob {
|
|
|
27
25
|
|
|
28
26
|
const encodeForm = (obj: Form.FullForm) =>
|
|
29
27
|
Effect.gen(function* () {
|
|
30
|
-
const encoded = yield* Schema.
|
|
28
|
+
const encoded = yield* Schema.encodeEffect(Form.FullForm)(obj);
|
|
31
29
|
const formData = new FormData();
|
|
32
30
|
for (const key in encoded) {
|
|
33
|
-
if (
|
|
31
|
+
if (Object.prototype.hasOwnProperty.call(encoded, key)) {
|
|
34
32
|
const val = encoded[key as keyof Form.FullForm];
|
|
35
33
|
if (isStringOrBlob(val)) {
|
|
36
34
|
formData.append(key, val);
|
|
@@ -42,44 +40,49 @@ const encodeForm = (obj: Form.FullForm) =>
|
|
|
42
40
|
|
|
43
41
|
const GrazeApiGroup = HttpApiGroup.make("graze", { topLevel: true })
|
|
44
42
|
.add(
|
|
45
|
-
HttpApiEndpoint.get("getFeeds"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
43
|
+
HttpApiEndpoint.get("getFeeds", "/app/my_feeds", {
|
|
44
|
+
// v3 GET `setPayload` serialised to query params (GET has no body); v4
|
|
45
|
+
// expresses that as `query`.
|
|
46
|
+
query: Schema.Struct({
|
|
47
|
+
user_id: UserIdParam,
|
|
48
|
+
}),
|
|
49
|
+
success: GetAlgorithmsResponse,
|
|
50
|
+
}),
|
|
52
51
|
)
|
|
53
52
|
.add(
|
|
54
|
-
HttpApiEndpoint.get("getFeed"
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
HttpApiEndpoint.get("getFeed", "/app/my_feeds/:feedId", {
|
|
54
|
+
params: { feedId: FeedIdParam },
|
|
55
|
+
success: GetAlgoResponse,
|
|
56
|
+
}),
|
|
57
57
|
)
|
|
58
58
|
.add(
|
|
59
|
-
HttpApiEndpoint.post("updateAlgorithm"
|
|
60
|
-
.
|
|
61
|
-
|
|
59
|
+
HttpApiEndpoint.post("updateAlgorithm", "/app/edit_algo_image", {
|
|
60
|
+
payload: Form.FullForm.pipe(HttpApiSchema.asMultipart()),
|
|
61
|
+
success: AlgoUpdateResponse,
|
|
62
|
+
}),
|
|
62
63
|
)
|
|
63
64
|
.add(
|
|
64
|
-
HttpApiEndpoint.get(
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
HttpApiEndpoint.get("publishAlgorithm", "/app/publish_algo/:feedId", {
|
|
66
|
+
params: { feedId: FeedIdParam },
|
|
67
|
+
success: Schema.Unknown,
|
|
68
|
+
}),
|
|
67
69
|
)
|
|
68
70
|
.add(
|
|
69
|
-
HttpApiEndpoint.post("hidePost"
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
HttpApiEndpoint.post("hidePost", "/app/hide_post", {
|
|
72
|
+
payload: HidePostBody,
|
|
73
|
+
success: Schema.Unknown,
|
|
74
|
+
}),
|
|
72
75
|
)
|
|
73
76
|
.add(
|
|
74
|
-
HttpApiEndpoint.post("unhidePost"
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
HttpApiEndpoint.post("unhidePost", "/app/unhide_post", {
|
|
78
|
+
payload: UnhidePostBody,
|
|
79
|
+
success: Schema.Unknown,
|
|
80
|
+
}),
|
|
77
81
|
);
|
|
78
82
|
|
|
79
83
|
class GrazeApiDef extends HttpApi.make("grazeApi")
|
|
80
84
|
.add(GrazeApiGroup)
|
|
81
|
-
.add(StickyPostsApiGroup)
|
|
82
|
-
.addError(Schema.Unknown) {}
|
|
85
|
+
.add(StickyPostsApiGroup) {}
|
|
83
86
|
|
|
84
87
|
const grazeLive = Effect.gen(function* () {
|
|
85
88
|
const baseUrl = yield* Config.url("GRAZE_API_URL");
|
|
@@ -93,8 +96,8 @@ const grazeLive = Effect.gen(function* () {
|
|
|
93
96
|
HttpClient.mapRequest(
|
|
94
97
|
HttpClientRequest.setHeaders({
|
|
95
98
|
cookie: Redacted.value(cookie),
|
|
96
|
-
})
|
|
97
|
-
)
|
|
99
|
+
}),
|
|
100
|
+
),
|
|
98
101
|
),
|
|
99
102
|
});
|
|
100
103
|
|
|
@@ -104,8 +107,8 @@ const grazeLive = Effect.gen(function* () {
|
|
|
104
107
|
return yield* client.updateAlgorithm({ payload: formData });
|
|
105
108
|
});
|
|
106
109
|
|
|
107
|
-
const userId = yield* Config.
|
|
108
|
-
const getFeeds = () => client.getFeeds({
|
|
110
|
+
const userId = yield* Config.int("GRAZE_USER_ID");
|
|
111
|
+
const getFeeds = () => client.getFeeds({ query: { user_id: userId } });
|
|
109
112
|
|
|
110
113
|
return {
|
|
111
114
|
...client,
|
|
@@ -114,13 +117,18 @@ const grazeLive = Effect.gen(function* () {
|
|
|
114
117
|
};
|
|
115
118
|
});
|
|
116
119
|
|
|
117
|
-
export class GrazeClient extends
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
export class GrazeClient extends Context.Service<
|
|
121
|
+
GrazeClient,
|
|
122
|
+
Effect.Success<typeof grazeLive>
|
|
123
|
+
>()("GrazeClient") {
|
|
124
|
+
static readonly layer = Layer.effect(GrazeClient, grazeLive).pipe(
|
|
125
|
+
Layer.provide(FetchHttpClient.layer),
|
|
126
|
+
);
|
|
122
127
|
}
|
|
123
128
|
|
|
129
|
+
/** The resolved service shape (v4 has no `.Service` namespace on the tag). */
|
|
130
|
+
export type GrazeClientService = Effect.Success<typeof grazeLive>;
|
|
131
|
+
|
|
124
132
|
export class GrazeError extends Data.TaggedError("GrazeError")<{
|
|
125
133
|
message: string;
|
|
126
134
|
status: number;
|
package/src/builder.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type {
|
|
2
2
|
AttributeComparison,
|
|
3
3
|
AttributeName,
|
|
4
4
|
AttributeValue,
|
|
@@ -18,8 +18,8 @@ const neverMatch: Filter = {
|
|
|
18
18
|
or: [],
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
const and = (...filters:
|
|
22
|
-
const flatFilters: Filter
|
|
21
|
+
const and = (...filters: Array<Filter | null>): Filter => {
|
|
22
|
+
const flatFilters: Array<Filter> = [];
|
|
23
23
|
filters.forEach((f) => {
|
|
24
24
|
if (f === null) {
|
|
25
25
|
// if the filter is null, we never want to match this block.
|
|
@@ -33,8 +33,8 @@ const and = (...filters: (Filter | null)[]): Filter => {
|
|
|
33
33
|
});
|
|
34
34
|
return { and: flatFilters };
|
|
35
35
|
};
|
|
36
|
-
const or = (...filters:
|
|
37
|
-
const flatFilters: Filter
|
|
36
|
+
const or = (...filters: Array<Filter | null>): Filter => {
|
|
37
|
+
const flatFilters: Array<Filter> = [];
|
|
38
38
|
filters
|
|
39
39
|
.filter((f) => f !== null)
|
|
40
40
|
.forEach((f) => {
|
|
@@ -49,26 +49,26 @@ const or = (...filters: (Filter | null)[]): Filter => {
|
|
|
49
49
|
|
|
50
50
|
const regexMatches = (
|
|
51
51
|
attribute: RegexMatches["regex_matches"][0],
|
|
52
|
-
regex: string
|
|
52
|
+
regex: string,
|
|
53
53
|
): RegexMatches => ({
|
|
54
54
|
regex_matches: [attribute, regex, true],
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
const regexNegationMatches = (
|
|
58
58
|
attribute: RegexNegationMatches["regex_negation_matches"][0],
|
|
59
|
-
regex: string
|
|
59
|
+
regex: string,
|
|
60
60
|
): RegexNegationMatches => ({
|
|
61
61
|
regex_negation_matches: [attribute, regex, true],
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
const textMatchesAny = ({
|
|
65
65
|
attribute,
|
|
66
|
-
patterns,
|
|
67
66
|
caseInsensitive = true,
|
|
67
|
+
patterns,
|
|
68
68
|
useRegex = false,
|
|
69
69
|
}: {
|
|
70
70
|
attribute: AttributeName;
|
|
71
|
-
patterns: string
|
|
71
|
+
patterns: Array<string>;
|
|
72
72
|
caseInsensitive?: boolean;
|
|
73
73
|
useRegex?: boolean;
|
|
74
74
|
}): TextMatchesAny => ({
|
|
@@ -77,12 +77,12 @@ const textMatchesAny = ({
|
|
|
77
77
|
|
|
78
78
|
const textMatchesNone = ({
|
|
79
79
|
attribute,
|
|
80
|
-
patterns,
|
|
81
80
|
caseInsensitive = true,
|
|
81
|
+
patterns,
|
|
82
82
|
useRegex = false,
|
|
83
83
|
}: {
|
|
84
84
|
attribute: AttributeName;
|
|
85
|
-
patterns: string
|
|
85
|
+
patterns: Array<string>;
|
|
86
86
|
caseInsensitive?: boolean;
|
|
87
87
|
useRegex?: boolean;
|
|
88
88
|
}): TextMatchesNone => ({
|
|
@@ -98,7 +98,7 @@ const isNotListMember = (uri: string): ListMemberFilter => ({
|
|
|
98
98
|
const socialGraph = (
|
|
99
99
|
identifier: string,
|
|
100
100
|
op: SocialGraph["social_graph"][1],
|
|
101
|
-
relation: SocialGraph["social_graph"][2]
|
|
101
|
+
relation: SocialGraph["social_graph"][2],
|
|
102
102
|
): SocialGraph => ({
|
|
103
103
|
social_graph: [identifier, op, relation],
|
|
104
104
|
});
|
|
@@ -133,7 +133,7 @@ const hasNoNSFWLabels: Filter = {
|
|
|
133
133
|
const attributeCompare = (
|
|
134
134
|
attr: AttributeName,
|
|
135
135
|
op: AttributeComparison,
|
|
136
|
-
value: AttributeValue
|
|
136
|
+
value: AttributeValue,
|
|
137
137
|
): Filter => ({
|
|
138
138
|
attribute_compare: [attr, op, value],
|
|
139
139
|
});
|
|
@@ -149,7 +149,7 @@ const isContentOk = (threshold: number = 0.9): ContentModerationBlock => ({
|
|
|
149
149
|
});
|
|
150
150
|
|
|
151
151
|
export const Algo = {
|
|
152
|
-
filter: (...filters: Filter
|
|
152
|
+
filter: (...filters: Array<Filter>): { filter: Filter } => ({
|
|
153
153
|
filter: and(...filters),
|
|
154
154
|
}),
|
|
155
155
|
};
|
package/src/common.ts
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import { HttpApiSchema } from "@effect/platform";
|
|
2
1
|
import { Schema } from "effect";
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export const FeedIdParam = HttpApiSchema.param(
|
|
9
|
-
"feedId",
|
|
10
|
-
Schema.NumberFromString
|
|
11
|
-
);
|
|
3
|
+
// v4 has no `HttpApiSchema.param`: path params are declared inline in the
|
|
4
|
+
// endpoint path (`:feedId`) with a `params: { feedId: FeedIdParam }` schema map.
|
|
5
|
+
export const UserIdParam = Schema.NumberFromString;
|
|
6
|
+
export const FeedIdParam = Schema.NumberFromString;
|
package/src/index.ts
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { ConfigProvider, Effect
|
|
2
|
-
import { GrazeClient } from "./GrazeClient.js";
|
|
1
|
+
import { ConfigProvider, Effect } from "effect";
|
|
2
|
+
import { GrazeClient, type GrazeClientService } from "./GrazeClient.js";
|
|
3
3
|
|
|
4
4
|
type Promisify<T> = T extends (
|
|
5
|
-
...args: any
|
|
6
|
-
) => Effect.Effect<infer A, infer
|
|
5
|
+
...args: Array<any>
|
|
6
|
+
) => Effect.Effect<infer A, infer _E, never>
|
|
7
7
|
? (...args: Parameters<T>) => Promise<A>
|
|
8
8
|
: never;
|
|
9
9
|
|
|
10
10
|
export class GrazeService {
|
|
11
|
-
getFeed: Promisify<
|
|
12
|
-
getFeeds: Promisify<
|
|
13
|
-
hidePost: Promisify<
|
|
14
|
-
unhidePost: Promisify<
|
|
15
|
-
updateAlgorithm: Promisify<
|
|
16
|
-
publishAlgorithm: Promisify<
|
|
11
|
+
getFeed: Promisify<GrazeClientService["getFeed"]>;
|
|
12
|
+
getFeeds: Promisify<GrazeClientService["getFeeds"]>;
|
|
13
|
+
hidePost: Promisify<GrazeClientService["hidePost"]>;
|
|
14
|
+
unhidePost: Promisify<GrazeClientService["unhidePost"]>;
|
|
15
|
+
updateAlgorithm: Promisify<GrazeClientService["updateAlgorithm"]>;
|
|
16
|
+
publishAlgorithm: Promisify<GrazeClientService["publishAlgorithm"]>;
|
|
17
17
|
stickyposts: {
|
|
18
|
-
get: Promisify<
|
|
19
|
-
create: Promisify<
|
|
20
|
-
delete: Promisify<
|
|
21
|
-
update: Promisify<
|
|
18
|
+
get: Promisify<GrazeClientService["stickyposts"]["get"]>;
|
|
19
|
+
create: Promisify<GrazeClientService["stickyposts"]["create"]>;
|
|
20
|
+
delete: Promisify<GrazeClientService["stickyposts"]["delete"]>;
|
|
21
|
+
update: Promisify<GrazeClientService["stickyposts"]["update"]>;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
constructor({
|
|
@@ -35,11 +35,16 @@ export class GrazeService {
|
|
|
35
35
|
["GRAZE_COOKIE", cookie],
|
|
36
36
|
["GRAZE_USER_ID", userId.toString()],
|
|
37
37
|
]);
|
|
38
|
-
const provider = ConfigProvider.
|
|
39
|
-
|
|
38
|
+
const provider = ConfigProvider.make((path) => {
|
|
39
|
+
const value = envMap.get(path.join("."));
|
|
40
|
+
return Effect.succeed(
|
|
41
|
+
value !== undefined ? ConfigProvider.makeValue(value) : undefined,
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
const layer = ConfigProvider.layer(provider);
|
|
40
45
|
const make = setup.pipe(
|
|
41
|
-
Effect.provide(GrazeClient.
|
|
42
|
-
Effect.provide(layer)
|
|
46
|
+
Effect.provide(GrazeClient.layer),
|
|
47
|
+
Effect.provide(layer),
|
|
43
48
|
);
|
|
44
49
|
const api = Effect.runSync(make);
|
|
45
50
|
this.getFeed = api.getFeed;
|
|
@@ -99,5 +104,5 @@ const setup = Effect.gen(function* () {
|
|
|
99
104
|
};
|
|
100
105
|
});
|
|
101
106
|
|
|
107
|
+
export { Algo, F } from "./builder.js";
|
|
102
108
|
export * from "./schema/index.js";
|
|
103
|
-
export { F, Algo } from "./builder.js";
|
package/src/schema/Post.ts
CHANGED
|
@@ -12,21 +12,21 @@ export const Author = S.Struct({
|
|
|
12
12
|
labels: S.Array(S.Any),
|
|
13
13
|
viewer: S.Any,
|
|
14
14
|
createdAt: S.String,
|
|
15
|
-
associated: S.Union(S.Null, S.Any),
|
|
15
|
+
associated: S.Union([S.Null, S.Any]),
|
|
16
16
|
displayName: S.String,
|
|
17
17
|
});
|
|
18
18
|
export type Author = typeof Author.Type;
|
|
19
19
|
|
|
20
20
|
export const Record = S.Struct({
|
|
21
|
-
tags: S.Union(S.Null, S.Any),
|
|
21
|
+
tags: S.Union([S.Null, S.Any]),
|
|
22
22
|
text: S.String,
|
|
23
23
|
$type: S.String,
|
|
24
24
|
embed: S.Any,
|
|
25
25
|
langs: S.NullOr(S.Array(S.String)),
|
|
26
|
-
reply: S.Union(S.Null, S.Any),
|
|
26
|
+
reply: S.Union([S.Null, S.Any]),
|
|
27
27
|
facets: S.NullOr(S.Array(S.Any)),
|
|
28
|
-
labels: S.Union(S.Null, S.Any),
|
|
29
|
-
entities: S.Union(S.Null, S.Any),
|
|
28
|
+
labels: S.Union([S.Null, S.Any]),
|
|
29
|
+
entities: S.Union([S.Null, S.Any]),
|
|
30
30
|
createdAt: S.String,
|
|
31
31
|
});
|
|
32
32
|
export type Record = typeof Record.Type;
|
|
@@ -44,7 +44,7 @@ export const Post = S.Struct({
|
|
|
44
44
|
likeCount: S.Number,
|
|
45
45
|
quoteCount: S.Number,
|
|
46
46
|
replyCount: S.Number,
|
|
47
|
-
threadgate: S.Union(S.Null, S.Unknown),
|
|
47
|
+
threadgate: S.Union([S.Null, S.Unknown]),
|
|
48
48
|
repostCount: S.Number,
|
|
49
49
|
});
|
|
50
50
|
export type Post = typeof Post.Type;
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { Schema as S } from "effect";
|
|
2
2
|
import { Post } from "./Post.js";
|
|
3
|
-
import { HttpApiSchema } from "@effect/platform";
|
|
4
3
|
|
|
5
|
-
export const StickyPostIdParam =
|
|
6
|
-
"stickyPostId",
|
|
7
|
-
S.NumberFromString
|
|
8
|
-
);
|
|
4
|
+
export const StickyPostIdParam = S.NumberFromString;
|
|
9
5
|
export type StickyPostIdParam = typeof StickyPostIdParam.Type;
|
|
10
6
|
|
|
11
7
|
export const StoppingCriteria = S.Struct({
|
|
@@ -13,7 +9,7 @@ export const StoppingCriteria = S.Struct({
|
|
|
13
9
|
});
|
|
14
10
|
export type StoppingCriteria = typeof StoppingCriteria.Type;
|
|
15
11
|
|
|
16
|
-
export const StickyType = S.
|
|
12
|
+
export const StickyType = S.Literals(["pinned", "rotating"]);
|
|
17
13
|
export type StickyType = typeof StickyType.Type;
|
|
18
14
|
|
|
19
15
|
const StickyPostBase = S.Struct({
|
|
@@ -41,7 +37,7 @@ export const GetStickyPostsBody = S.Struct({
|
|
|
41
37
|
author: S.String,
|
|
42
38
|
created_at: S.String,
|
|
43
39
|
updated_at: S.String,
|
|
44
|
-
})
|
|
40
|
+
}),
|
|
45
41
|
),
|
|
46
42
|
});
|
|
47
43
|
export type GetStickyPostsBody = typeof GetStickyPostsBody.Type;
|