@superdurable/connector-hackernews 0.1.0 → 0.2.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/dex-connector.json +55 -3
- package/dist/{chunk-KZXAW7VV.js → chunk-23APJHSI.js} +63 -0
- package/dist/{connection-BabsoorY.d.ts → connection-fC9QqgNx.d.ts} +11 -1
- package/dist/hackernewsmock.d.ts +2 -1
- package/dist/hackernewsmock.js +5 -62
- package/dist/index.d.ts +3 -2
- package/dist/index.js +5 -1
- package/package.json +3 -2
package/dex-connector.json
CHANGED
|
@@ -4,13 +4,22 @@
|
|
|
4
4
|
"package": {
|
|
5
5
|
"ecosystem": "npm",
|
|
6
6
|
"name": "@superdurable/connector-hackernews",
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.2.0"
|
|
8
8
|
},
|
|
9
9
|
"factories": [
|
|
10
10
|
{
|
|
11
11
|
"name": "newListStoryIDsStep",
|
|
12
12
|
"kind": "query",
|
|
13
13
|
"operationId": "listStoryIDs",
|
|
14
|
+
"inputType": "ListStoryIDsInput",
|
|
15
|
+
"description": "List current Hacker News story IDs in feed order. Choose feed top, best, new, ask (Ask HN), or show (Show HN), and limit from 1 to 500. Read each returned ID as a Hacker News item for its title and links.",
|
|
16
|
+
"agent": {
|
|
17
|
+
"exposed": true,
|
|
18
|
+
"branches": {
|
|
19
|
+
"defect": "rejected",
|
|
20
|
+
"providerRejected": "rejected"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
14
23
|
"fields": {
|
|
15
24
|
"stepType": "stepType",
|
|
16
25
|
"annotations": "annotations",
|
|
@@ -38,12 +47,41 @@
|
|
|
38
47
|
"field": "defect",
|
|
39
48
|
"optional": true
|
|
40
49
|
}
|
|
41
|
-
]
|
|
50
|
+
],
|
|
51
|
+
"inputSchema": {
|
|
52
|
+
"additionalProperties": false,
|
|
53
|
+
"description": "ListStoryIDsInput selects one feed snapshot. It does not select a historical time window.",
|
|
54
|
+
"properties": {
|
|
55
|
+
"feed": {
|
|
56
|
+
"description": "Feed is top, best, new, ask, or show. Empty selects top.",
|
|
57
|
+
"type": "string"
|
|
58
|
+
},
|
|
59
|
+
"limit": {
|
|
60
|
+
"description": "Limit bounds returned IDs from 1 through 500. Zero selects 50.",
|
|
61
|
+
"type": "integer"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"required": [
|
|
65
|
+
"feed",
|
|
66
|
+
"limit"
|
|
67
|
+
],
|
|
68
|
+
"type": "object"
|
|
69
|
+
}
|
|
42
70
|
},
|
|
43
71
|
{
|
|
44
72
|
"name": "newGetItemStep",
|
|
45
73
|
"kind": "query",
|
|
46
74
|
"operationId": "getItem",
|
|
75
|
+
"inputType": "GetItemInput",
|
|
76
|
+
"description": "Read one public Hacker News story, comment, job, or poll by its positive item ID. Returns title, author, score, source URL, discussion URL, text as untrusted HTML, and child comment IDs to read next.",
|
|
77
|
+
"agent": {
|
|
78
|
+
"exposed": true,
|
|
79
|
+
"branches": {
|
|
80
|
+
"defect": "rejected",
|
|
81
|
+
"notFound": "rejected",
|
|
82
|
+
"providerRejected": "rejected"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
47
85
|
"fields": {
|
|
48
86
|
"stepType": "stepType",
|
|
49
87
|
"annotations": "annotations",
|
|
@@ -76,7 +114,21 @@
|
|
|
76
114
|
"field": "defect",
|
|
77
115
|
"optional": true
|
|
78
116
|
}
|
|
79
|
-
]
|
|
117
|
+
],
|
|
118
|
+
"inputSchema": {
|
|
119
|
+
"additionalProperties": false,
|
|
120
|
+
"description": "GetItemInput identifies one story, comment, job, poll, or poll option.",
|
|
121
|
+
"properties": {
|
|
122
|
+
"id": {
|
|
123
|
+
"description": "ID is a positive Hacker News item ID.",
|
|
124
|
+
"type": "integer"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"required": [
|
|
128
|
+
"id"
|
|
129
|
+
],
|
|
130
|
+
"type": "object"
|
|
131
|
+
}
|
|
80
132
|
}
|
|
81
133
|
]
|
|
82
134
|
}
|
|
@@ -1,3 +1,62 @@
|
|
|
1
|
+
// src/generated/models.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
var goTimeJSONPattern = /^(\d{4})-(\d{2})-(\d{2})T(\d{1,2}):(\d{2}):(\d{2})(?:[.,](\d+))?(Z|([+-])(\d{2}):(\d{2}))$/;
|
|
4
|
+
function isGoTimeJSON(value) {
|
|
5
|
+
const match = goTimeJSONPattern.exec(value);
|
|
6
|
+
if (!match) return false;
|
|
7
|
+
const [, yearText, monthText, dayText, hourText, minuteText, secondText, , zone, , zoneHourText, zoneMinuteText] = match;
|
|
8
|
+
const year = Number(yearText);
|
|
9
|
+
const month = Number(monthText);
|
|
10
|
+
const day = Number(dayText);
|
|
11
|
+
const isLeap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
12
|
+
const monthDays = [31, isLeap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
13
|
+
return month >= 1 && month <= 12 && day >= 1 && day <= monthDays[month - 1] && Number(hourText) <= 23 && Number(minuteText) <= 59 && Number(secondText) <= 59 && (zone === "Z" || Number(zoneHourText) <= 24 && Number(zoneMinuteText) <= 60);
|
|
14
|
+
}
|
|
15
|
+
function canonicalGoTimeJSON(value) {
|
|
16
|
+
const match = goTimeJSONPattern.exec(value);
|
|
17
|
+
const [, year, month, day, hour, minute, second, fraction, zone, sign, zoneHour, zoneMinute] = match;
|
|
18
|
+
const clock = year + "-" + month + "-" + day + "T" + hour.padStart(2, "0") + ":" + minute + ":" + second;
|
|
19
|
+
const digits = (fraction ?? "").slice(0, 9).replace(/0+$/, "");
|
|
20
|
+
const offsetMinutes = zone === "Z" ? 0 : (Number(zoneHour) * 60 + Number(zoneMinute)) * (sign === "+" ? 1 : -1);
|
|
21
|
+
if (Math.abs(offsetMinutes) >= 1440) return value;
|
|
22
|
+
const offset = offsetMinutes === 0 ? "Z" : (offsetMinutes > 0 ? "+" : "-") + String(Math.floor(Math.abs(offsetMinutes) / 60)).padStart(2, "0") + ":" + String(Math.abs(offsetMinutes) % 60).padStart(2, "0");
|
|
23
|
+
return clock + (digits ? "." + digits : "") + offset;
|
|
24
|
+
}
|
|
25
|
+
var GoTimeJSONSchema = z.string().refine(isGoTimeJSON, "invalid Go time.Time JSON timestamp").transform(canonicalGoTimeJSON);
|
|
26
|
+
var ConfigSchema = z.object({
|
|
27
|
+
"baseUrl": z.string().optional(),
|
|
28
|
+
"timeoutMs": z.number().int().optional(),
|
|
29
|
+
"maxResponseBytes": z.number().int().optional()
|
|
30
|
+
});
|
|
31
|
+
var ListStoryIDsInputSchema = z.strictObject({
|
|
32
|
+
"feed": z.string(),
|
|
33
|
+
"limit": z.number().int()
|
|
34
|
+
});
|
|
35
|
+
var StoryIDsSchema = z.strictObject({
|
|
36
|
+
"ids": z.array(z.number().int()).nullable(),
|
|
37
|
+
"hasMore": z.boolean(),
|
|
38
|
+
"observedAt": GoTimeJSONSchema
|
|
39
|
+
});
|
|
40
|
+
var GetItemInputSchema = z.strictObject({
|
|
41
|
+
"id": z.number().int()
|
|
42
|
+
});
|
|
43
|
+
var ItemSchema = z.strictObject({
|
|
44
|
+
"id": z.number().int(),
|
|
45
|
+
"type": z.string(),
|
|
46
|
+
"by": z.string().optional(),
|
|
47
|
+
"time": z.number().int().optional(),
|
|
48
|
+
"title": z.string().optional(),
|
|
49
|
+
"text": z.string().optional(),
|
|
50
|
+
"url": z.string().optional(),
|
|
51
|
+
"discussionUrl": z.string(),
|
|
52
|
+
"score": z.number().int().optional(),
|
|
53
|
+
"descendants": z.number().int().optional(),
|
|
54
|
+
"parent": z.number().int().optional(),
|
|
55
|
+
"kids": z.array(z.number().int()).optional(),
|
|
56
|
+
"deleted": z.boolean().optional(),
|
|
57
|
+
"dead": z.boolean().optional()
|
|
58
|
+
});
|
|
59
|
+
|
|
1
60
|
// src/generated/definitions.ts
|
|
2
61
|
var ConnectorID = "hacker-news-daily";
|
|
3
62
|
var ProviderID = "hacker-news";
|
|
@@ -78,6 +137,10 @@ function newProjectConnection(project, connectionName, createClient) {
|
|
|
78
137
|
}
|
|
79
138
|
|
|
80
139
|
export {
|
|
140
|
+
ListStoryIDsInputSchema,
|
|
141
|
+
StoryIDsSchema,
|
|
142
|
+
GetItemInputSchema,
|
|
143
|
+
ItemSchema,
|
|
81
144
|
ConnectorID,
|
|
82
145
|
ProviderID,
|
|
83
146
|
ListStoryIDsBranch,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Query, ConnectionRef } from '@superdurable/connectors-sdk';
|
|
2
|
+
import { z } from 'zod';
|
|
2
3
|
|
|
3
4
|
/** Connector configuration; omitted fields use manifest defaults. */
|
|
4
5
|
interface Config {
|
|
@@ -65,6 +66,15 @@ interface Item {
|
|
|
65
66
|
/** Dead reports a moderated item. GetItem selects notFound instead of returning it. */
|
|
66
67
|
"dead"?: boolean | undefined;
|
|
67
68
|
}
|
|
69
|
+
/** Runtime validator for ListStoryIDsInput. */
|
|
70
|
+
declare const ListStoryIDsInputSchema: z.ZodObject<{
|
|
71
|
+
feed: z.ZodString;
|
|
72
|
+
limit: z.ZodNumber;
|
|
73
|
+
}, z.core.$strict>;
|
|
74
|
+
/** Runtime validator for GetItemInput. */
|
|
75
|
+
declare const GetItemInputSchema: z.ZodObject<{
|
|
76
|
+
id: z.ZodNumber;
|
|
77
|
+
}, z.core.$strict>;
|
|
68
78
|
|
|
69
79
|
/** Typed operations supplied by a client or mock. */
|
|
70
80
|
interface Operations {
|
|
@@ -87,4 +97,4 @@ declare function newConnection(client: Operations, reference: ConnectionRef): Co
|
|
|
87
97
|
/** Bind scripted operations to a named connection. */
|
|
88
98
|
declare function newConnectionWithOperations(operations: Operations, reference: ConnectionRef): Connection;
|
|
89
99
|
|
|
90
|
-
export { Connection as C, type GetItemInput as G, type Item as I, type ListStoryIDsInput as L, type Operations as O, type StoryIDs as S, type Config as a, type Credentials as b,
|
|
100
|
+
export { Connection as C, type GetItemInput as G, type Item as I, type ListStoryIDsInput as L, type Operations as O, type StoryIDs as S, type Config as a, type Credentials as b, GetItemInputSchema as c, ListStoryIDsInputSchema as d, newConnectionWithOperations as e, newConnection as n };
|
package/dist/hackernewsmock.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MockQuery, Case } from '@superdurable/connectors-sdk/connectormock';
|
|
2
2
|
import { Failure } from '@superdurable/connectors-sdk';
|
|
3
|
-
import { O as Operations, C as Connection, L as ListStoryIDsInput, S as StoryIDs, G as GetItemInput, I as Item } from './connection-
|
|
3
|
+
import { O as Operations, C as Connection, L as ListStoryIDsInput, S as StoryIDs, G as GetItemInput, I as Item } from './connection-fC9QqgNx.js';
|
|
4
|
+
import 'zod';
|
|
4
5
|
|
|
5
6
|
/** Go zero value for ListStoryIDsInput in scripted cases. */
|
|
6
7
|
declare const emptyListStoryIDsInput: ListStoryIDsInput;
|
package/dist/hackernewsmock.js
CHANGED
|
@@ -1,74 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ConnectorID,
|
|
3
3
|
GetItemDefinition,
|
|
4
|
+
GetItemInputSchema,
|
|
5
|
+
ItemSchema,
|
|
4
6
|
ListStoryIDsDefinition,
|
|
7
|
+
ListStoryIDsInputSchema,
|
|
5
8
|
ProviderID,
|
|
9
|
+
StoryIDsSchema,
|
|
6
10
|
newConnectionWithOperations
|
|
7
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-23APJHSI.js";
|
|
8
12
|
|
|
9
13
|
// src/generated/mock.ts
|
|
10
14
|
import { branchCase, retryCase, newQuery } from "@superdurable/connectors-sdk/connectormock";
|
|
11
|
-
|
|
12
|
-
// src/generated/models.ts
|
|
13
|
-
import { z } from "zod";
|
|
14
|
-
var goTimeJSONPattern = /^(\d{4})-(\d{2})-(\d{2})T(\d{1,2}):(\d{2}):(\d{2})(?:[.,](\d+))?(Z|([+-])(\d{2}):(\d{2}))$/;
|
|
15
|
-
function isGoTimeJSON(value) {
|
|
16
|
-
const match = goTimeJSONPattern.exec(value);
|
|
17
|
-
if (!match) return false;
|
|
18
|
-
const [, yearText, monthText, dayText, hourText, minuteText, secondText, , zone, , zoneHourText, zoneMinuteText] = match;
|
|
19
|
-
const year = Number(yearText);
|
|
20
|
-
const month = Number(monthText);
|
|
21
|
-
const day = Number(dayText);
|
|
22
|
-
const isLeap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
23
|
-
const monthDays = [31, isLeap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
24
|
-
return month >= 1 && month <= 12 && day >= 1 && day <= monthDays[month - 1] && Number(hourText) <= 23 && Number(minuteText) <= 59 && Number(secondText) <= 59 && (zone === "Z" || Number(zoneHourText) <= 24 && Number(zoneMinuteText) <= 60);
|
|
25
|
-
}
|
|
26
|
-
function canonicalGoTimeJSON(value) {
|
|
27
|
-
const match = goTimeJSONPattern.exec(value);
|
|
28
|
-
const [, year, month, day, hour, minute, second, fraction, zone, sign, zoneHour, zoneMinute] = match;
|
|
29
|
-
const clock = year + "-" + month + "-" + day + "T" + hour.padStart(2, "0") + ":" + minute + ":" + second;
|
|
30
|
-
const digits = (fraction ?? "").slice(0, 9).replace(/0+$/, "");
|
|
31
|
-
const offsetMinutes = zone === "Z" ? 0 : (Number(zoneHour) * 60 + Number(zoneMinute)) * (sign === "+" ? 1 : -1);
|
|
32
|
-
if (Math.abs(offsetMinutes) >= 1440) return value;
|
|
33
|
-
const offset = offsetMinutes === 0 ? "Z" : (offsetMinutes > 0 ? "+" : "-") + String(Math.floor(Math.abs(offsetMinutes) / 60)).padStart(2, "0") + ":" + String(Math.abs(offsetMinutes) % 60).padStart(2, "0");
|
|
34
|
-
return clock + (digits ? "." + digits : "") + offset;
|
|
35
|
-
}
|
|
36
|
-
var GoTimeJSONSchema = z.string().refine(isGoTimeJSON, "invalid Go time.Time JSON timestamp").transform(canonicalGoTimeJSON);
|
|
37
|
-
var ConfigSchema = z.object({
|
|
38
|
-
"baseUrl": z.string().optional(),
|
|
39
|
-
"timeoutMs": z.number().int().optional(),
|
|
40
|
-
"maxResponseBytes": z.number().int().optional()
|
|
41
|
-
});
|
|
42
|
-
var ListStoryIDsInputSchema = z.strictObject({
|
|
43
|
-
"feed": z.string(),
|
|
44
|
-
"limit": z.number().int()
|
|
45
|
-
});
|
|
46
|
-
var StoryIDsSchema = z.strictObject({
|
|
47
|
-
"ids": z.array(z.number().int()).nullable(),
|
|
48
|
-
"hasMore": z.boolean(),
|
|
49
|
-
"observedAt": GoTimeJSONSchema
|
|
50
|
-
});
|
|
51
|
-
var GetItemInputSchema = z.strictObject({
|
|
52
|
-
"id": z.number().int()
|
|
53
|
-
});
|
|
54
|
-
var ItemSchema = z.strictObject({
|
|
55
|
-
"id": z.number().int(),
|
|
56
|
-
"type": z.string(),
|
|
57
|
-
"by": z.string().optional(),
|
|
58
|
-
"time": z.number().int().optional(),
|
|
59
|
-
"title": z.string().optional(),
|
|
60
|
-
"text": z.string().optional(),
|
|
61
|
-
"url": z.string().optional(),
|
|
62
|
-
"discussionUrl": z.string(),
|
|
63
|
-
"score": z.number().int().optional(),
|
|
64
|
-
"descendants": z.number().int().optional(),
|
|
65
|
-
"parent": z.number().int().optional(),
|
|
66
|
-
"kids": z.array(z.number().int()).optional(),
|
|
67
|
-
"deleted": z.boolean().optional(),
|
|
68
|
-
"dead": z.boolean().optional()
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
// src/generated/mock.ts
|
|
72
15
|
var emptyListStoryIDsInput = ListStoryIDsInputSchema.parse({
|
|
73
16
|
"feed": "",
|
|
74
17
|
"limit": 0
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { G as GetItemInput, I as Item, a as Config, L as ListStoryIDsInput, S as StoryIDs, C as Connection, O as Operations } from './connection-
|
|
2
|
-
export { b as Credentials, n as newConnection,
|
|
1
|
+
import { G as GetItemInput, I as Item, a as Config, L as ListStoryIDsInput, S as StoryIDs, C as Connection, O as Operations } from './connection-fC9QqgNx.js';
|
|
2
|
+
export { b as Credentials, c as GetItemInputSchema, d as ListStoryIDsInputSchema, n as newConnection, e as newConnectionWithOperations } from './connection-fC9QqgNx.js';
|
|
3
3
|
import { LoadedProject } from '@superdurable/connectors-sdk/projectconfig';
|
|
4
4
|
import * as _superdurable_connectors_sdk from '@superdurable/connectors-sdk';
|
|
5
5
|
import { Query, Call, QueryAttempt, QueryStepConfig, QueryResult, QueryStep, QueryDefinition } from '@superdurable/connectors-sdk';
|
|
6
6
|
import { ProviderRequest, ProviderResponse } from '@superdurable/connectors-sdk/providerhttp';
|
|
7
7
|
import { StepTarget } from '@superdurable/dex';
|
|
8
|
+
import 'zod';
|
|
8
9
|
|
|
9
10
|
/** Injectable HTTP sender and clock for deterministic provider replay. */
|
|
10
11
|
interface HackerNewsClientOptions {
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
GetItemBranchNotFound,
|
|
9
9
|
GetItemBranchProviderRejected,
|
|
10
10
|
GetItemDefinition,
|
|
11
|
+
GetItemInputSchema,
|
|
11
12
|
GetItemMetadata,
|
|
12
13
|
ListStoryIDsBranch,
|
|
13
14
|
ListStoryIDsBranchDefect,
|
|
@@ -15,12 +16,13 @@ import {
|
|
|
15
16
|
ListStoryIDsBranchListed,
|
|
16
17
|
ListStoryIDsBranchProviderRejected,
|
|
17
18
|
ListStoryIDsDefinition,
|
|
19
|
+
ListStoryIDsInputSchema,
|
|
18
20
|
ListStoryIDsMetadata,
|
|
19
21
|
ProviderID,
|
|
20
22
|
newConnection,
|
|
21
23
|
newConnectionWithOperations,
|
|
22
24
|
newProjectConnection
|
|
23
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-23APJHSI.js";
|
|
24
26
|
|
|
25
27
|
// src/index.ts
|
|
26
28
|
import { z } from "zod";
|
|
@@ -276,6 +278,7 @@ export {
|
|
|
276
278
|
GetItemBranchNotFound,
|
|
277
279
|
GetItemBranchProviderRejected,
|
|
278
280
|
GetItemDefinition,
|
|
281
|
+
GetItemInputSchema,
|
|
279
282
|
GetItemMetadata,
|
|
280
283
|
GetItemOperation,
|
|
281
284
|
HackerNewsClient,
|
|
@@ -285,6 +288,7 @@ export {
|
|
|
285
288
|
ListStoryIDsBranchListed,
|
|
286
289
|
ListStoryIDsBranchProviderRejected,
|
|
287
290
|
ListStoryIDsDefinition,
|
|
291
|
+
ListStoryIDsInputSchema,
|
|
288
292
|
ListStoryIDsMetadata,
|
|
289
293
|
ListStoryIDsOperation,
|
|
290
294
|
ProviderID,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superdurable/connector-hackernews",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Hacker News connector for Dex TypeScript applications",
|
|
6
6
|
"repository": {
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
"./hackernewsmock": {
|
|
23
23
|
"types": "./dist/hackernewsmock.d.ts",
|
|
24
24
|
"import": "./dist/hackernewsmock.js"
|
|
25
|
-
}
|
|
25
|
+
},
|
|
26
|
+
"./dex-connector.json": "./dex-connector.json"
|
|
26
27
|
},
|
|
27
28
|
"files": [
|
|
28
29
|
"dist",
|