@superdurable/connector-posthog 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +5 -2
- package/dex-connector.json +135 -0
- package/dist/chunk-JWKU3SHH.js +153 -0
- package/dist/connection-BmXhoEU7.d.ts +135 -0
- package/dist/index.d.ts +159 -0
- package/dist/index.js +380 -0
- package/dist/mock.d.ts +54 -0
- package/dist/mock.js +127 -0
- package/package.json +61 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Super Durable
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# PostHog TypeScript connector
|
|
2
2
|
|
|
3
|
-
This
|
|
3
|
+
This package implements `captureEvent` and `listInsights` for Dex TypeScript
|
|
4
|
+
Flows. The project token sends events; a personal API key with `insight:read`
|
|
5
|
+
lists saved insight identities. Both operations replay the Go provider
|
|
6
|
+
conformance scenarios. Runnable Flows are under `examples/`.
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
{
|
|
2
|
+
"connectorId": "posthog",
|
|
3
|
+
"releaseTag": "connectors/posthog/go/v0.1.0",
|
|
4
|
+
"package": {
|
|
5
|
+
"ecosystem": "npm",
|
|
6
|
+
"name": "@superdurable/connector-posthog",
|
|
7
|
+
"version": "0.1.0"
|
|
8
|
+
},
|
|
9
|
+
"factories": [
|
|
10
|
+
{
|
|
11
|
+
"name": "newCaptureEventStep",
|
|
12
|
+
"kind": "mutation",
|
|
13
|
+
"operationId": "captureEvent",
|
|
14
|
+
"inputType": "CaptureEventInput",
|
|
15
|
+
"description": "Submit one event with stable timestamp, distinct ID, and derived UUID; acknowledgment does not guarantee later ingestion.",
|
|
16
|
+
"fields": {
|
|
17
|
+
"stepType": "stepType",
|
|
18
|
+
"annotations": "annotations",
|
|
19
|
+
"connectionName": "connectionName",
|
|
20
|
+
"resultAttribute": "resultAttribute"
|
|
21
|
+
},
|
|
22
|
+
"branches": [
|
|
23
|
+
{
|
|
24
|
+
"id": "accepted",
|
|
25
|
+
"field": "accepted",
|
|
26
|
+
"optional": false
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "quotaLimited",
|
|
30
|
+
"field": "quotaLimited",
|
|
31
|
+
"optional": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "providerRejected",
|
|
35
|
+
"field": "providerRejected",
|
|
36
|
+
"optional": true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "defect",
|
|
40
|
+
"field": "defect",
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"inputSchema": {
|
|
45
|
+
"additionalProperties": false,
|
|
46
|
+
"description": "CaptureEventInput is one event with stable identity and time across retries.",
|
|
47
|
+
"properties": {
|
|
48
|
+
"distinctId": {
|
|
49
|
+
"description": "DistinctID is the stable person or anonymous identity.",
|
|
50
|
+
"type": "string"
|
|
51
|
+
},
|
|
52
|
+
"event": {
|
|
53
|
+
"description": "Event is a nonempty custom event name.",
|
|
54
|
+
"type": "string"
|
|
55
|
+
},
|
|
56
|
+
"properties": {
|
|
57
|
+
"additionalProperties": {
|
|
58
|
+
"type": "string"
|
|
59
|
+
},
|
|
60
|
+
"description": "Properties contains non-secret string dimensions, excluding identity and person mutations.",
|
|
61
|
+
"type": "object"
|
|
62
|
+
},
|
|
63
|
+
"timestamp": {
|
|
64
|
+
"description": "Timestamp is the event time in RFC3339 format and must remain fixed across retries.",
|
|
65
|
+
"type": "string"
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"required": [
|
|
69
|
+
"distinctId",
|
|
70
|
+
"event",
|
|
71
|
+
"timestamp"
|
|
72
|
+
],
|
|
73
|
+
"type": "object"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name": "newListInsightsStep",
|
|
78
|
+
"kind": "query",
|
|
79
|
+
"operationId": "listInsights",
|
|
80
|
+
"inputType": "ListInsightsInput",
|
|
81
|
+
"description": "List one bounded page of saved insight IDs and names without query results or private metadata.",
|
|
82
|
+
"fields": {
|
|
83
|
+
"stepType": "stepType",
|
|
84
|
+
"annotations": "annotations",
|
|
85
|
+
"connectionName": "connectionName",
|
|
86
|
+
"resultAttribute": "resultAttribute"
|
|
87
|
+
},
|
|
88
|
+
"branches": [
|
|
89
|
+
{
|
|
90
|
+
"id": "listed",
|
|
91
|
+
"field": "listed",
|
|
92
|
+
"optional": false
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"id": "providerRejected",
|
|
96
|
+
"field": "providerRejected",
|
|
97
|
+
"optional": true
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"id": "invalidResponse",
|
|
101
|
+
"field": "invalidResponse",
|
|
102
|
+
"optional": true
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "defect",
|
|
106
|
+
"field": "defect",
|
|
107
|
+
"optional": true
|
|
108
|
+
}
|
|
109
|
+
],
|
|
110
|
+
"inputSchema": {
|
|
111
|
+
"additionalProperties": false,
|
|
112
|
+
"description": "ListInsightsInput selects a project and bounded offset page of saved insights.",
|
|
113
|
+
"properties": {
|
|
114
|
+
"limit": {
|
|
115
|
+
"description": "Limit is the maximum count from 1 through 100; zero uses 20.",
|
|
116
|
+
"type": "integer"
|
|
117
|
+
},
|
|
118
|
+
"offset": {
|
|
119
|
+
"description": "Offset is the zero-based page offset.",
|
|
120
|
+
"type": "integer"
|
|
121
|
+
},
|
|
122
|
+
"projectId": {
|
|
123
|
+
"description": "ProjectID is the positive ID shown in the PostHog project URL or settings.",
|
|
124
|
+
"type": "integer"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"required": [
|
|
128
|
+
"offset",
|
|
129
|
+
"projectId"
|
|
130
|
+
],
|
|
131
|
+
"type": "object"
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
// src/generated/models.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { SecretString } from "@superdurable/connectors-sdk";
|
|
4
|
+
var ConfigSchema = z.object({
|
|
5
|
+
"captureUrl": z.string().optional(),
|
|
6
|
+
"appUrl": z.string().optional(),
|
|
7
|
+
"timeoutMs": z.number().int().optional(),
|
|
8
|
+
"maxResponseBytes": z.number().int().optional()
|
|
9
|
+
});
|
|
10
|
+
function decodeCredentials(value) {
|
|
11
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new TypeError("credential fields are invalid");
|
|
12
|
+
const fields = value;
|
|
13
|
+
const allowed = /* @__PURE__ */ new Set(["personal_api_key", "project_token"]);
|
|
14
|
+
if (Object.keys(fields).some((key) => !allowed.has(key))) throw new TypeError("stored credential does not match the connector credential fields");
|
|
15
|
+
if (fields["personal_api_key"] != null && !(typeof fields["personal_api_key"] === "string")) throw new TypeError("credential personal_api_key has an invalid type");
|
|
16
|
+
if (fields["project_token"] != null && !(typeof fields["project_token"] === "string")) throw new TypeError("credential project_token has an invalid type");
|
|
17
|
+
const credentials = {};
|
|
18
|
+
if (!fields["project_token"]) throw new TypeError("credential project_token is required");
|
|
19
|
+
credentials.projectToken = new SecretString(fields["project_token"] ?? "");
|
|
20
|
+
credentials.personalApiKey = new SecretString(fields["personal_api_key"] ?? "");
|
|
21
|
+
return credentials;
|
|
22
|
+
}
|
|
23
|
+
var CaptureEventInputSchema = z.strictObject({
|
|
24
|
+
"event": z.string(),
|
|
25
|
+
"distinctId": z.string(),
|
|
26
|
+
"timestamp": z.string(),
|
|
27
|
+
"properties": z.record(z.string(), z.string()).optional()
|
|
28
|
+
});
|
|
29
|
+
var CapturedEventSchema = z.strictObject({
|
|
30
|
+
"eventId": z.string(),
|
|
31
|
+
"accepted": z.boolean()
|
|
32
|
+
});
|
|
33
|
+
var ListInsightsInputSchema = z.strictObject({
|
|
34
|
+
"projectId": z.number().int(),
|
|
35
|
+
"offset": z.number().int(),
|
|
36
|
+
"limit": z.number().int().optional()
|
|
37
|
+
});
|
|
38
|
+
var InsightMetadataSchema = z.strictObject({
|
|
39
|
+
"id": z.number().int(),
|
|
40
|
+
"name": z.string()
|
|
41
|
+
});
|
|
42
|
+
var InsightsPageSchema = z.strictObject({
|
|
43
|
+
"insights": z.array(InsightMetadataSchema).nullable(),
|
|
44
|
+
"hasMore": z.boolean(),
|
|
45
|
+
"offset": z.number().int(),
|
|
46
|
+
"limit": z.number().int()
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// src/generated/definitions.ts
|
|
50
|
+
var ConnectorID = "posthog";
|
|
51
|
+
var ProviderID = "posthog";
|
|
52
|
+
var CaptureEventBranch = {
|
|
53
|
+
Accepted: "accepted",
|
|
54
|
+
QuotaLimited: "quotaLimited",
|
|
55
|
+
ProviderRejected: "providerRejected",
|
|
56
|
+
Defect: "defect"
|
|
57
|
+
};
|
|
58
|
+
var CaptureEventBranchAccepted = CaptureEventBranch.Accepted;
|
|
59
|
+
var CaptureEventBranchQuotaLimited = CaptureEventBranch.QuotaLimited;
|
|
60
|
+
var CaptureEventBranchProviderRejected = CaptureEventBranch.ProviderRejected;
|
|
61
|
+
var CaptureEventBranchDefect = CaptureEventBranch.Defect;
|
|
62
|
+
var CaptureEventDefinition = {
|
|
63
|
+
operation: { connectorId: ConnectorID, operationId: "captureEvent" },
|
|
64
|
+
branches: [
|
|
65
|
+
{ id: "accepted", description: "PostHog accepted the event for processing, without confirming ingestion." },
|
|
66
|
+
{ id: "quotaLimited", description: "PostHog reported a billing quota limit and may not ingest the event.", optional: true },
|
|
67
|
+
{ id: "providerRejected", description: "PostHog conclusively rejected the request.", optional: true },
|
|
68
|
+
{ id: "defect", description: "Local event input or project token is invalid.", optional: true }
|
|
69
|
+
],
|
|
70
|
+
stepDefaults: { executeMethodTimeoutMs: 3e4, executeDurability: "async" }
|
|
71
|
+
};
|
|
72
|
+
var CaptureEventMetadata = { kind: "mutation", idempotency: "required", authorization: "required" };
|
|
73
|
+
var ListInsightsBranch = {
|
|
74
|
+
Listed: "listed",
|
|
75
|
+
ProviderRejected: "providerRejected",
|
|
76
|
+
InvalidResponse: "invalidResponse",
|
|
77
|
+
Defect: "defect"
|
|
78
|
+
};
|
|
79
|
+
var ListInsightsBranchListed = ListInsightsBranch.Listed;
|
|
80
|
+
var ListInsightsBranchProviderRejected = ListInsightsBranch.ProviderRejected;
|
|
81
|
+
var ListInsightsBranchInvalidResponse = ListInsightsBranch.InvalidResponse;
|
|
82
|
+
var ListInsightsBranchDefect = ListInsightsBranch.Defect;
|
|
83
|
+
var ListInsightsDefinition = {
|
|
84
|
+
operation: { connectorId: ConnectorID, operationId: "listInsights" },
|
|
85
|
+
branches: [
|
|
86
|
+
{ id: "listed", description: "PostHog returned the insight page, possibly empty." },
|
|
87
|
+
{ id: "providerRejected", description: "PostHog denied the query or project access.", optional: true },
|
|
88
|
+
{ id: "invalidResponse", description: "PostHog returned malformed or oversized page JSON.", optional: true },
|
|
89
|
+
{ id: "defect", description: "Local project ID, page input, or personal API key is invalid.", optional: true }
|
|
90
|
+
],
|
|
91
|
+
stepDefaults: { executeMethodTimeoutMs: 3e4, executeDurability: "async" }
|
|
92
|
+
};
|
|
93
|
+
var ListInsightsMetadata = { kind: "query", idempotency: "none", authorization: "required" };
|
|
94
|
+
|
|
95
|
+
// src/generated/connection.ts
|
|
96
|
+
import { ConnectionRefSchema } from "@superdurable/connectors-sdk";
|
|
97
|
+
var Connection = class {
|
|
98
|
+
/** Stable provider and connection name. */
|
|
99
|
+
reference;
|
|
100
|
+
/** Bound provider operations. */
|
|
101
|
+
operations;
|
|
102
|
+
/** Validate a reference and bind operations. */
|
|
103
|
+
constructor(reference, operations) {
|
|
104
|
+
this.reference = ConnectionRefSchema.parse(reference);
|
|
105
|
+
if (this.reference.provider !== ProviderID) throw new TypeError("connection provider differs from the manifest");
|
|
106
|
+
if (!operations) throw new TypeError("connector operations are required");
|
|
107
|
+
this.operations = operations;
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
function newConnection(client, reference) {
|
|
111
|
+
if (!client) throw new TypeError("connector client is required");
|
|
112
|
+
return new Connection(reference, client);
|
|
113
|
+
}
|
|
114
|
+
function newConnectionWithOperations(operations, reference) {
|
|
115
|
+
return new Connection(reference, operations);
|
|
116
|
+
}
|
|
117
|
+
function newProjectConnection(project, connectionName, createClient) {
|
|
118
|
+
if (!project) throw new TypeError("loaded project is required");
|
|
119
|
+
const reference = ConnectionRefSchema.parse({ provider: ProviderID, name: connectionName });
|
|
120
|
+
const selected = project.configuration.connections.find((entry) => entry.connectorId === ConnectorID && entry.connectionName === connectionName);
|
|
121
|
+
if (!selected || selected.provider !== ProviderID) throw new TypeError("project connection is not configured");
|
|
122
|
+
return newConnection(createClient(project, connectionName), reference);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export {
|
|
126
|
+
ConfigSchema,
|
|
127
|
+
decodeCredentials,
|
|
128
|
+
CaptureEventInputSchema,
|
|
129
|
+
CapturedEventSchema,
|
|
130
|
+
ListInsightsInputSchema,
|
|
131
|
+
InsightMetadataSchema,
|
|
132
|
+
InsightsPageSchema,
|
|
133
|
+
ConnectorID,
|
|
134
|
+
ProviderID,
|
|
135
|
+
CaptureEventBranch,
|
|
136
|
+
CaptureEventBranchAccepted,
|
|
137
|
+
CaptureEventBranchQuotaLimited,
|
|
138
|
+
CaptureEventBranchProviderRejected,
|
|
139
|
+
CaptureEventBranchDefect,
|
|
140
|
+
CaptureEventDefinition,
|
|
141
|
+
CaptureEventMetadata,
|
|
142
|
+
ListInsightsBranch,
|
|
143
|
+
ListInsightsBranchListed,
|
|
144
|
+
ListInsightsBranchProviderRejected,
|
|
145
|
+
ListInsightsBranchInvalidResponse,
|
|
146
|
+
ListInsightsBranchDefect,
|
|
147
|
+
ListInsightsDefinition,
|
|
148
|
+
ListInsightsMetadata,
|
|
149
|
+
Connection,
|
|
150
|
+
newConnection,
|
|
151
|
+
newConnectionWithOperations,
|
|
152
|
+
newProjectConnection
|
|
153
|
+
};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { SecretString, CredentialProvider, Mutation, Query, ConnectionRef } from '@superdurable/connectors-sdk';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/** Connector configuration; omitted fields use manifest defaults. */
|
|
5
|
+
interface Config {
|
|
6
|
+
/** Public capture API base URL. Blank uses the displayed US default; use https://eu.i.posthog.com for an EU Cloud project or your self-hosted HTTPS origin. Find your region in PostHog Project Settings > Project variables. Do not append /i/v0/e. */
|
|
7
|
+
captureUrl?: string;
|
|
8
|
+
/** Private API base URL. Blank uses the displayed US default; use https://eu.posthog.com for EU Cloud or your self-hosted HTTPS origin. Find your region in PostHog Project Settings > Project variables. Do not append /api. */
|
|
9
|
+
appUrl?: string;
|
|
10
|
+
/** Maximum duration of one request as a positive Go duration such as 15s or 1m. Blank uses the displayed default; increase only for slow responses. Runtime value in milliseconds. */
|
|
11
|
+
timeoutMs?: number;
|
|
12
|
+
/** Maximum complete JSON response in bytes as a positive integer. Blank uses the displayed default; increase only for larger insight pages. Oversized responses select invalidResponse. */
|
|
13
|
+
maxResponseBytes?: number;
|
|
14
|
+
}
|
|
15
|
+
/** Runtime schema for manifest configuration. */
|
|
16
|
+
declare const ConfigSchema: z.ZodObject<{
|
|
17
|
+
captureUrl: z.ZodOptional<z.ZodString>;
|
|
18
|
+
appUrl: z.ZodOptional<z.ZodString>;
|
|
19
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
20
|
+
maxResponseBytes: z.ZodOptional<z.ZodNumber>;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
/** Private connector credentials resolved by the host. */
|
|
23
|
+
interface Credentials {
|
|
24
|
+
/** Secret personal API key (phx_ prefix) from your PostHog instance > avatar > Account settings > Personal API Keys > Create personal API key. Select `insight:read` scope, copy the one-time value into Dex, and revoke it there when retired. Blank permits captureEvent but makes listInsights select defect. */
|
|
25
|
+
personalApiKey?: SecretString;
|
|
26
|
+
/** PostHog project token (phc_ prefix) from your PostHog project URL > Settings > Project > Project variables > Project API key. Copy the exact value into this Dex secret field; blank prevents capture. It is sent only in the capture request body. */
|
|
27
|
+
projectToken: SecretString;
|
|
28
|
+
}
|
|
29
|
+
/** Decode private credential fields for the connector. */
|
|
30
|
+
declare function decodeCredentials(value: unknown): Credentials;
|
|
31
|
+
/** Host-owned source of private connector credentials. */
|
|
32
|
+
type CredentialSource = CredentialProvider<Credentials>;
|
|
33
|
+
/** CaptureEventInput is one event with stable identity and time across retries. */
|
|
34
|
+
interface CaptureEventInput {
|
|
35
|
+
/** Event is a nonempty custom event name. */
|
|
36
|
+
"event": string;
|
|
37
|
+
/** DistinctID is the stable person or anonymous identity. */
|
|
38
|
+
"distinctId": string;
|
|
39
|
+
/** Timestamp is the event time in RFC3339 format and must remain fixed across retries. */
|
|
40
|
+
"timestamp": string;
|
|
41
|
+
/** Properties contains non-secret string dimensions, excluding identity and person mutations. */
|
|
42
|
+
"properties"?: {
|
|
43
|
+
[key: string]: string;
|
|
44
|
+
} | undefined;
|
|
45
|
+
}
|
|
46
|
+
/** CapturedEvent reports acceptance for processing, not confirmed ingestion. */
|
|
47
|
+
interface CapturedEvent {
|
|
48
|
+
/** EventID is the stable UUID sent to PostHog for retry deduplication. */
|
|
49
|
+
"eventId": string;
|
|
50
|
+
/** Accepted is true only when PostHog acknowledged the event without a quota limit. */
|
|
51
|
+
"accepted": boolean;
|
|
52
|
+
}
|
|
53
|
+
/** ListInsightsInput selects a project and bounded offset page of saved insights. */
|
|
54
|
+
interface ListInsightsInput {
|
|
55
|
+
/** ProjectID is the positive ID shown in the PostHog project URL or settings. */
|
|
56
|
+
"projectId": number;
|
|
57
|
+
/** Offset is the zero-based page offset. */
|
|
58
|
+
"offset": number;
|
|
59
|
+
/** Limit is the maximum count from 1 through 100; zero uses 20. */
|
|
60
|
+
"limit"?: number | undefined;
|
|
61
|
+
}
|
|
62
|
+
/** InsightMetadata contains only a saved insight's identity and display name. */
|
|
63
|
+
interface InsightMetadata {
|
|
64
|
+
/** ID is the stable numeric insight ID. */
|
|
65
|
+
"id": number;
|
|
66
|
+
/** Name is the untrusted display name. */
|
|
67
|
+
"name": string;
|
|
68
|
+
}
|
|
69
|
+
/** InsightsPage is one bounded saved-insight page without analysis results. */
|
|
70
|
+
interface InsightsPage {
|
|
71
|
+
/** Insights contains the selected metadata page. */
|
|
72
|
+
"insights": Array<InsightMetadata> | null;
|
|
73
|
+
/** HasMore indicates a provider next page. */
|
|
74
|
+
"hasMore": boolean;
|
|
75
|
+
/** Offset is the requested zero-based offset. */
|
|
76
|
+
"offset": number;
|
|
77
|
+
/** Limit is the requested maximum count. */
|
|
78
|
+
"limit": number;
|
|
79
|
+
}
|
|
80
|
+
/** Runtime validator for CaptureEventInput. */
|
|
81
|
+
declare const CaptureEventInputSchema: z.ZodObject<{
|
|
82
|
+
event: z.ZodString;
|
|
83
|
+
distinctId: z.ZodString;
|
|
84
|
+
timestamp: z.ZodString;
|
|
85
|
+
properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
86
|
+
}, z.core.$strict>;
|
|
87
|
+
/** Runtime validator for CapturedEvent. */
|
|
88
|
+
declare const CapturedEventSchema: z.ZodObject<{
|
|
89
|
+
eventId: z.ZodString;
|
|
90
|
+
accepted: z.ZodBoolean;
|
|
91
|
+
}, z.core.$strict>;
|
|
92
|
+
/** Runtime validator for ListInsightsInput. */
|
|
93
|
+
declare const ListInsightsInputSchema: z.ZodObject<{
|
|
94
|
+
projectId: z.ZodNumber;
|
|
95
|
+
offset: z.ZodNumber;
|
|
96
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
97
|
+
}, z.core.$strict>;
|
|
98
|
+
/** Runtime validator for InsightMetadata. */
|
|
99
|
+
declare const InsightMetadataSchema: z.ZodObject<{
|
|
100
|
+
id: z.ZodNumber;
|
|
101
|
+
name: z.ZodString;
|
|
102
|
+
}, z.core.$strict>;
|
|
103
|
+
/** Runtime validator for InsightsPage. */
|
|
104
|
+
declare const InsightsPageSchema: z.ZodObject<{
|
|
105
|
+
insights: z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
106
|
+
id: z.ZodNumber;
|
|
107
|
+
name: z.ZodString;
|
|
108
|
+
}, z.core.$strict>>>;
|
|
109
|
+
hasMore: z.ZodBoolean;
|
|
110
|
+
offset: z.ZodNumber;
|
|
111
|
+
limit: z.ZodNumber;
|
|
112
|
+
}, z.core.$strict>;
|
|
113
|
+
|
|
114
|
+
/** Typed operations supplied by a client or mock. */
|
|
115
|
+
interface Operations {
|
|
116
|
+
/** Invoke captureEvent through this connection. */
|
|
117
|
+
captureEvent(): Mutation<CaptureEventInput, CapturedEvent>;
|
|
118
|
+
/** Invoke listInsights through this connection. */
|
|
119
|
+
listInsights(): Query<ListInsightsInput, InsightsPage>;
|
|
120
|
+
}
|
|
121
|
+
/** Named connector connection kept outside Flow state. */
|
|
122
|
+
declare class Connection<BoundOperations = Operations> {
|
|
123
|
+
/** Stable provider and connection name. */
|
|
124
|
+
readonly reference: ConnectionRef;
|
|
125
|
+
/** Bound provider operations. */
|
|
126
|
+
readonly operations: BoundOperations;
|
|
127
|
+
/** Validate a reference and bind operations. */
|
|
128
|
+
constructor(reference: ConnectionRef, operations: BoundOperations);
|
|
129
|
+
}
|
|
130
|
+
/** Bind a client to a named connection. */
|
|
131
|
+
declare function newConnection(client: Operations, reference: ConnectionRef): Connection;
|
|
132
|
+
/** Bind scripted operations to a named connection. */
|
|
133
|
+
declare function newConnectionWithOperations(operations: Operations, reference: ConnectionRef): Connection;
|
|
134
|
+
|
|
135
|
+
export { type CaptureEventInput as C, type InsightsPage as I, type ListInsightsInput as L, type Operations as O, type CapturedEvent as a, Connection as b, type Config as c, type Credentials as d, CaptureEventInputSchema as e, CapturedEventSchema as f, ConfigSchema as g, type CredentialSource as h, type InsightMetadata as i, InsightMetadataSchema as j, InsightsPageSchema as k, ListInsightsInputSchema as l, decodeCredentials as m, newConnection as n, newConnectionWithOperations as o };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { C as CaptureEventInput, a as CapturedEvent, b as Connection, L as ListInsightsInput, I as InsightsPage, c as Config, d as Credentials, O as Operations } from './connection-BmXhoEU7.js';
|
|
2
|
+
export { e as CaptureEventInputSchema, f as CapturedEventSchema, g as ConfigSchema, h as CredentialSource, i as InsightMetadata, j as InsightMetadataSchema, k as InsightsPageSchema, l as ListInsightsInputSchema, m as decodeCredentials, n as newConnection, o as newConnectionWithOperations } from './connection-BmXhoEU7.js';
|
|
3
|
+
import * as _superdurable_connectors_sdk from '@superdurable/connectors-sdk';
|
|
4
|
+
import { MutationDefinition, QueryDefinition, MutationStepConfig, Mutation, MutationResult, QueryStepConfig, Query, QueryResult, MutationStep, QueryStep, CredentialProvider, Call, QueryAttempt, MutationAttempt } from '@superdurable/connectors-sdk';
|
|
5
|
+
import { StepTarget } from '@superdurable/dex';
|
|
6
|
+
import { LoadedProject } from '@superdurable/connectors-sdk/projectconfig';
|
|
7
|
+
import { ProviderRequest, ProviderResponse } from '@superdurable/connectors-sdk/providerhttp';
|
|
8
|
+
import 'zod';
|
|
9
|
+
|
|
10
|
+
/** Stable connector identity. */
|
|
11
|
+
declare const ConnectorID = "posthog";
|
|
12
|
+
/** Provider identity for named connections. */
|
|
13
|
+
declare const ProviderID = "posthog";
|
|
14
|
+
/** Branch IDs for captureEvent. */
|
|
15
|
+
declare const CaptureEventBranch: {
|
|
16
|
+
readonly Accepted: "accepted";
|
|
17
|
+
readonly QuotaLimited: "quotaLimited";
|
|
18
|
+
readonly ProviderRejected: "providerRejected";
|
|
19
|
+
readonly Defect: "defect";
|
|
20
|
+
};
|
|
21
|
+
/** PostHog accepted the event for processing, without confirming ingestion. */
|
|
22
|
+
declare const CaptureEventBranchAccepted: "accepted";
|
|
23
|
+
/** PostHog reported a billing quota limit and may not ingest the event. */
|
|
24
|
+
declare const CaptureEventBranchQuotaLimited: "quotaLimited";
|
|
25
|
+
/** PostHog conclusively rejected the request. */
|
|
26
|
+
declare const CaptureEventBranchProviderRejected: "providerRejected";
|
|
27
|
+
/** Local event input or project token is invalid. */
|
|
28
|
+
declare const CaptureEventBranchDefect: "defect";
|
|
29
|
+
/** Manifest definition for captureEvent. */
|
|
30
|
+
declare const CaptureEventDefinition: MutationDefinition;
|
|
31
|
+
/** Manifest metadata for captureEvent. */
|
|
32
|
+
declare const CaptureEventMetadata: {
|
|
33
|
+
readonly kind: "mutation";
|
|
34
|
+
readonly idempotency: "required";
|
|
35
|
+
readonly authorization: "required";
|
|
36
|
+
};
|
|
37
|
+
/** Branch IDs for listInsights. */
|
|
38
|
+
declare const ListInsightsBranch: {
|
|
39
|
+
readonly Listed: "listed";
|
|
40
|
+
readonly ProviderRejected: "providerRejected";
|
|
41
|
+
readonly InvalidResponse: "invalidResponse";
|
|
42
|
+
readonly Defect: "defect";
|
|
43
|
+
};
|
|
44
|
+
/** PostHog returned the insight page, possibly empty. */
|
|
45
|
+
declare const ListInsightsBranchListed: "listed";
|
|
46
|
+
/** PostHog denied the query or project access. */
|
|
47
|
+
declare const ListInsightsBranchProviderRejected: "providerRejected";
|
|
48
|
+
/** PostHog returned malformed or oversized page JSON. */
|
|
49
|
+
declare const ListInsightsBranchInvalidResponse: "invalidResponse";
|
|
50
|
+
/** Local project ID, page input, or personal API key is invalid. */
|
|
51
|
+
declare const ListInsightsBranchDefect: "defect";
|
|
52
|
+
/** Manifest definition for listInsights. */
|
|
53
|
+
declare const ListInsightsDefinition: QueryDefinition;
|
|
54
|
+
/** Manifest metadata for listInsights. */
|
|
55
|
+
declare const ListInsightsMetadata: {
|
|
56
|
+
readonly kind: "query";
|
|
57
|
+
readonly idempotency: "none";
|
|
58
|
+
readonly authorization: "required";
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/** Configuration for the captureEvent connector Step. */
|
|
62
|
+
interface CaptureEventStepConfig<StepInput, OperationInput = CaptureEventInput, OperationOutput = CapturedEvent> extends Omit<MutationStepConfig<StepInput, OperationInput, OperationOutput>, 'operation' | 'connection' | 'branches'> {
|
|
63
|
+
/** Named connection supplying this operation. */
|
|
64
|
+
connection: Connection<{
|
|
65
|
+
captureEvent(): Mutation<OperationInput, OperationOutput>;
|
|
66
|
+
}>;
|
|
67
|
+
/** Name matching the bound connection. */
|
|
68
|
+
connectionName: string;
|
|
69
|
+
/** PostHog accepted the event for processing, without confirming ingestion. */
|
|
70
|
+
accepted: StepTarget<MutationResult<OperationOutput>>;
|
|
71
|
+
/** PostHog reported a billing quota limit and may not ingest the event. */
|
|
72
|
+
quotaLimited?: StepTarget<MutationResult<OperationOutput>>;
|
|
73
|
+
/** PostHog conclusively rejected the request. */
|
|
74
|
+
providerRejected?: StepTarget<MutationResult<OperationOutput>>;
|
|
75
|
+
/** Local event input or project token is invalid. */
|
|
76
|
+
defect?: StepTarget<MutationResult<OperationOutput>>;
|
|
77
|
+
}
|
|
78
|
+
/** Build the captureEvent Step from a named connection. */
|
|
79
|
+
declare function newCaptureEventStep<StepInput, OperationInput = CaptureEventInput, OperationOutput = CapturedEvent>(configuration: CaptureEventStepConfig<StepInput, OperationInput, OperationOutput>): MutationStep<StepInput, OperationInput, OperationOutput>;
|
|
80
|
+
/** Configuration for the listInsights connector Step. */
|
|
81
|
+
interface ListInsightsStepConfig<StepInput, OperationInput = ListInsightsInput, OperationOutput = InsightsPage> extends Omit<QueryStepConfig<StepInput, OperationInput, OperationOutput>, 'operation' | 'connection' | 'branches'> {
|
|
82
|
+
/** Named connection supplying this operation. */
|
|
83
|
+
connection: Connection<{
|
|
84
|
+
listInsights(): Query<OperationInput, OperationOutput>;
|
|
85
|
+
}>;
|
|
86
|
+
/** Name matching the bound connection. */
|
|
87
|
+
connectionName: string;
|
|
88
|
+
/** PostHog returned the insight page, possibly empty. */
|
|
89
|
+
listed: StepTarget<QueryResult<OperationOutput>>;
|
|
90
|
+
/** PostHog denied the query or project access. */
|
|
91
|
+
providerRejected?: StepTarget<QueryResult<OperationOutput>>;
|
|
92
|
+
/** PostHog returned malformed or oversized page JSON. */
|
|
93
|
+
invalidResponse?: StepTarget<QueryResult<OperationOutput>>;
|
|
94
|
+
/** Local project ID, page input, or personal API key is invalid. */
|
|
95
|
+
defect?: StepTarget<QueryResult<OperationOutput>>;
|
|
96
|
+
}
|
|
97
|
+
/** Build the listInsights Step from a named connection. */
|
|
98
|
+
declare function newListInsightsStep<StepInput, OperationInput = ListInsightsInput, OperationOutput = InsightsPage>(configuration: ListInsightsStepConfig<StepInput, OperationInput, OperationOutput>): QueryStep<StepInput, OperationInput, OperationOutput>;
|
|
99
|
+
|
|
100
|
+
/** Injectable provider transport and clock for deterministic replay. */
|
|
101
|
+
interface PostHogClientOptions {
|
|
102
|
+
/** Provider sender; omitted uses the SDK's redirect-safe transport. */
|
|
103
|
+
send?: (request: ProviderRequest) => Promise<ProviderResponse>;
|
|
104
|
+
/** Clock for Retry-After dates. */
|
|
105
|
+
now?: () => Date;
|
|
106
|
+
}
|
|
107
|
+
type Exchange = {
|
|
108
|
+
response: ProviderResponse;
|
|
109
|
+
tooLarge: boolean;
|
|
110
|
+
} | {
|
|
111
|
+
transportFailure: true;
|
|
112
|
+
};
|
|
113
|
+
/** PostHog public capture and private insight API client. */
|
|
114
|
+
declare class PostHogClient {
|
|
115
|
+
/** Public event capture API base URL. */ readonly captureUrl: string;
|
|
116
|
+
/** Private insight API base URL. */ readonly appUrl: string;
|
|
117
|
+
/** Complete response bound in bytes. */ readonly maxResponseBytes: number;
|
|
118
|
+
private readonly timeoutMs;
|
|
119
|
+
private readonly credentials;
|
|
120
|
+
private readonly send;
|
|
121
|
+
private readonly now;
|
|
122
|
+
/** Validate configuration without contacting the provider. */
|
|
123
|
+
constructor(config: Config, credentials: CredentialProvider<Credentials>, options?: PostHogClientOptions);
|
|
124
|
+
/** Bind a deduplicated event Mutation. */
|
|
125
|
+
captureEvent(): CaptureEventOperation;
|
|
126
|
+
/** Bind a bounded saved insight Query. */
|
|
127
|
+
listInsights(): ListInsightsOperation;
|
|
128
|
+
/** Resolve a project token for an individual provider attempt. */
|
|
129
|
+
projectToken(call: Call): Promise<string | undefined>;
|
|
130
|
+
/** Resolve a scoped personal API key for an individual provider attempt. */
|
|
131
|
+
personalApiKey(call: Call): Promise<string | undefined>;
|
|
132
|
+
/** Send one bounded provider request, preserving response status on body overflow. */
|
|
133
|
+
exchange(call: Call, method: 'GET' | 'POST', url: string, headers: Record<string, string>, body?: Uint8Array): Promise<Exchange>;
|
|
134
|
+
/** Parse the provider's Retry-After header in milliseconds. */
|
|
135
|
+
retryAfter(response: ProviderResponse): number;
|
|
136
|
+
}
|
|
137
|
+
/** Send a stable PostHog capture event. */
|
|
138
|
+
declare class CaptureEventOperation implements Mutation<CaptureEventInput, CapturedEvent> {
|
|
139
|
+
private readonly client;
|
|
140
|
+
/** Bind the provider client. */ constructor(client: PostHogClient);
|
|
141
|
+
/** Return the generated Mutation contract. */ definition(): _superdurable_connectors_sdk.QueryDefinition;
|
|
142
|
+
/** Derive Go's UUID-shaped SHA-256 identity from the Dex call ID. */
|
|
143
|
+
idempotencyKey(callId: string): string;
|
|
144
|
+
/** Validate, submit, and classify one event with a stable timestamp. */
|
|
145
|
+
invoke(call: Call, input: CaptureEventInput): Promise<MutationAttempt<CapturedEvent>>;
|
|
146
|
+
}
|
|
147
|
+
/** List saved insight IDs and names for one PostHog project. */
|
|
148
|
+
declare class ListInsightsOperation implements Query<ListInsightsInput, InsightsPage> {
|
|
149
|
+
private readonly client;
|
|
150
|
+
/** Bind the provider client. */ constructor(client: PostHogClient);
|
|
151
|
+
/** Return the generated Query contract. */ definition(): _superdurable_connectors_sdk.QueryDefinition;
|
|
152
|
+
/** Validate, request, and classify one bounded insight page. */
|
|
153
|
+
invoke(call: Call, input: ListInsightsInput): Promise<QueryAttempt<InsightsPage>>;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** Bind a static PostHog connection declared in a Dex project. */
|
|
157
|
+
declare function newProjectConnection(project: LoadedProject, connectionName: string, options?: PostHogClientOptions): Connection<Operations>;
|
|
158
|
+
|
|
159
|
+
export { CaptureEventBranch, CaptureEventBranchAccepted, CaptureEventBranchDefect, CaptureEventBranchProviderRejected, CaptureEventBranchQuotaLimited, CaptureEventDefinition, CaptureEventInput, CaptureEventMetadata, CaptureEventOperation, type CaptureEventStepConfig, CapturedEvent, Config, Connection, ConnectorID, Credentials, InsightsPage, ListInsightsBranch, ListInsightsBranchDefect, ListInsightsBranchInvalidResponse, ListInsightsBranchListed, ListInsightsBranchProviderRejected, ListInsightsDefinition, ListInsightsInput, ListInsightsMetadata, ListInsightsOperation, type ListInsightsStepConfig, PostHogClient, type PostHogClientOptions, ProviderID, newCaptureEventStep, newListInsightsStep, newProjectConnection };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CaptureEventBranch,
|
|
3
|
+
CaptureEventBranchAccepted,
|
|
4
|
+
CaptureEventBranchDefect,
|
|
5
|
+
CaptureEventBranchProviderRejected,
|
|
6
|
+
CaptureEventBranchQuotaLimited,
|
|
7
|
+
CaptureEventDefinition,
|
|
8
|
+
CaptureEventInputSchema,
|
|
9
|
+
CaptureEventMetadata,
|
|
10
|
+
CapturedEventSchema,
|
|
11
|
+
ConfigSchema,
|
|
12
|
+
Connection,
|
|
13
|
+
ConnectorID,
|
|
14
|
+
InsightMetadataSchema,
|
|
15
|
+
InsightsPageSchema,
|
|
16
|
+
ListInsightsBranch,
|
|
17
|
+
ListInsightsBranchDefect,
|
|
18
|
+
ListInsightsBranchInvalidResponse,
|
|
19
|
+
ListInsightsBranchListed,
|
|
20
|
+
ListInsightsBranchProviderRejected,
|
|
21
|
+
ListInsightsDefinition,
|
|
22
|
+
ListInsightsInputSchema,
|
|
23
|
+
ListInsightsMetadata,
|
|
24
|
+
ProviderID,
|
|
25
|
+
decodeCredentials,
|
|
26
|
+
newConnection,
|
|
27
|
+
newConnectionWithOperations,
|
|
28
|
+
newProjectConnection
|
|
29
|
+
} from "./chunk-JWKU3SHH.js";
|
|
30
|
+
|
|
31
|
+
// src/generated/steps.ts
|
|
32
|
+
import { goToBranch, newMutationStep, newQueryStep } from "@superdurable/connectors-sdk";
|
|
33
|
+
function newCaptureEventStep(configuration) {
|
|
34
|
+
const { connection, connectionName, accepted, quotaLimited, providerRejected, defect, ...stepConfiguration } = configuration;
|
|
35
|
+
if (!connection || connection.reference.name !== connectionName) throw new TypeError("Step connection name differs from the bound connection");
|
|
36
|
+
return newMutationStep({ ...stepConfiguration, operation: connection.operations.captureEvent(), connection: connection.reference, branches: [
|
|
37
|
+
goToBranch("accepted", accepted),
|
|
38
|
+
...quotaLimited ? [goToBranch("quotaLimited", quotaLimited)] : [],
|
|
39
|
+
...providerRejected ? [goToBranch("providerRejected", providerRejected)] : [],
|
|
40
|
+
...defect ? [goToBranch("defect", defect)] : []
|
|
41
|
+
] });
|
|
42
|
+
}
|
|
43
|
+
function newListInsightsStep(configuration) {
|
|
44
|
+
const { connection, connectionName, listed, providerRejected, invalidResponse, defect, ...stepConfiguration } = configuration;
|
|
45
|
+
if (!connection || connection.reference.name !== connectionName) throw new TypeError("Step connection name differs from the bound connection");
|
|
46
|
+
return newQueryStep({ ...stepConfiguration, operation: connection.operations.listInsights(), connection: connection.reference, branches: [
|
|
47
|
+
goToBranch("listed", listed),
|
|
48
|
+
...providerRejected ? [goToBranch("providerRejected", providerRejected)] : [],
|
|
49
|
+
...invalidResponse ? [goToBranch("invalidResponse", invalidResponse)] : [],
|
|
50
|
+
...defect ? [goToBranch("defect", defect)] : []
|
|
51
|
+
] });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/project.ts
|
|
55
|
+
import { z } from "zod";
|
|
56
|
+
|
|
57
|
+
// src/client.ts
|
|
58
|
+
import { createHash } from "crypto";
|
|
59
|
+
import {
|
|
60
|
+
newMutationBranch,
|
|
61
|
+
newMutationRetry,
|
|
62
|
+
newQueryBranch,
|
|
63
|
+
newQueryRetry
|
|
64
|
+
} from "@superdurable/connectors-sdk";
|
|
65
|
+
import {
|
|
66
|
+
BodyTooLargeError,
|
|
67
|
+
isHeaderSafeCredential,
|
|
68
|
+
parseRetryAfter,
|
|
69
|
+
sendProviderRequest,
|
|
70
|
+
validateBaseURL
|
|
71
|
+
} from "@superdurable/connectors-sdk/providerhttp";
|
|
72
|
+
var emptyEvent = { eventId: "", accepted: false };
|
|
73
|
+
var emptyPage = { insights: [], hasMore: false, offset: 0, limit: 0 };
|
|
74
|
+
var PostHogClient = class {
|
|
75
|
+
/** Public event capture API base URL. */
|
|
76
|
+
captureUrl;
|
|
77
|
+
/** Private insight API base URL. */
|
|
78
|
+
appUrl;
|
|
79
|
+
/** Complete response bound in bytes. */
|
|
80
|
+
maxResponseBytes;
|
|
81
|
+
timeoutMs;
|
|
82
|
+
credentials;
|
|
83
|
+
send;
|
|
84
|
+
now;
|
|
85
|
+
/** Validate configuration without contacting the provider. */
|
|
86
|
+
constructor(config, credentials, options = {}) {
|
|
87
|
+
if (!config || !credentials) throw new TypeError("PostHog configuration and credential source are required");
|
|
88
|
+
this.captureUrl = validateBaseURL(config.captureUrl || "https://us.i.posthog.com");
|
|
89
|
+
this.appUrl = validateBaseURL(config.appUrl || "https://us.posthog.com");
|
|
90
|
+
this.timeoutMs = config.timeoutMs || 15e3;
|
|
91
|
+
this.maxResponseBytes = config.maxResponseBytes || 2097152;
|
|
92
|
+
if (!Number.isSafeInteger(this.timeoutMs) || this.timeoutMs <= 0 || !Number.isSafeInteger(this.maxResponseBytes) || this.maxResponseBytes <= 0)
|
|
93
|
+
throw new TypeError("PostHog timeout and response limit must be positive integers");
|
|
94
|
+
this.credentials = credentials;
|
|
95
|
+
this.send = options.send ?? sendProviderRequest;
|
|
96
|
+
this.now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
97
|
+
}
|
|
98
|
+
/** Bind a deduplicated event Mutation. */
|
|
99
|
+
captureEvent() {
|
|
100
|
+
return new CaptureEventOperation(this);
|
|
101
|
+
}
|
|
102
|
+
/** Bind a bounded saved insight Query. */
|
|
103
|
+
listInsights() {
|
|
104
|
+
return new ListInsightsOperation(this);
|
|
105
|
+
}
|
|
106
|
+
/** Resolve a project token for an individual provider attempt. */
|
|
107
|
+
async projectToken(call) {
|
|
108
|
+
try {
|
|
109
|
+
const credentials = await this.credentials.resolve(call, call.context.cancellationSignal);
|
|
110
|
+
const token = credentials.projectToken.reveal();
|
|
111
|
+
return token && isHeaderSafeCredential(token) ? token : void 0;
|
|
112
|
+
} catch {
|
|
113
|
+
return void 0;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/** Resolve a scoped personal API key for an individual provider attempt. */
|
|
117
|
+
async personalApiKey(call) {
|
|
118
|
+
try {
|
|
119
|
+
const credentials = await this.credentials.resolve(call, call.context.cancellationSignal);
|
|
120
|
+
const key = credentials.personalApiKey?.reveal();
|
|
121
|
+
return key && isHeaderSafeCredential(key) ? key : void 0;
|
|
122
|
+
} catch {
|
|
123
|
+
return void 0;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** Send one bounded provider request, preserving response status on body overflow. */
|
|
127
|
+
async exchange(call, method, url, headers, body) {
|
|
128
|
+
const request = {
|
|
129
|
+
url,
|
|
130
|
+
method,
|
|
131
|
+
headers,
|
|
132
|
+
maxResponseBytes: this.maxResponseBytes,
|
|
133
|
+
timeoutMs: this.timeoutMs,
|
|
134
|
+
addressPolicy: url.startsWith("https://") ? "publicHTTPS" : "privateNetworkHTTP",
|
|
135
|
+
signal: call.context.cancellationSignal,
|
|
136
|
+
...body ? { body } : {}
|
|
137
|
+
};
|
|
138
|
+
try {
|
|
139
|
+
return { response: await this.send(request), tooLarge: false };
|
|
140
|
+
} catch (error) {
|
|
141
|
+
if (error instanceof BodyTooLargeError && error.status !== void 0)
|
|
142
|
+
return { response: { status: error.status, headers: error.headers ?? {}, body: new Uint8Array() }, tooLarge: true };
|
|
143
|
+
return { transportFailure: true };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/** Parse the provider's Retry-After header in milliseconds. */
|
|
147
|
+
retryAfter(response) {
|
|
148
|
+
const entry = Object.entries(response.headers).find(([key]) => key.toLowerCase() === "retry-after")?.[1];
|
|
149
|
+
return parseRetryAfter(Array.isArray(entry) ? entry[0] ?? "" : entry ?? "", this.now());
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
var CaptureEventOperation = class {
|
|
153
|
+
/** Bind the provider client. */
|
|
154
|
+
constructor(client) {
|
|
155
|
+
this.client = client;
|
|
156
|
+
}
|
|
157
|
+
client;
|
|
158
|
+
/** Return the generated Mutation contract. */
|
|
159
|
+
definition() {
|
|
160
|
+
return CaptureEventDefinition;
|
|
161
|
+
}
|
|
162
|
+
/** Derive Go's UUID-shaped SHA-256 identity from the Dex call ID. */
|
|
163
|
+
idempotencyKey(callId) {
|
|
164
|
+
const hex = createHash("sha256").update(callId, "utf8").digest("hex").slice(0, 32);
|
|
165
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
166
|
+
}
|
|
167
|
+
/** Validate, submit, and classify one event with a stable timestamp. */
|
|
168
|
+
async invoke(call, input) {
|
|
169
|
+
if (!validEvent(input) || call.idempotencyKey?.length !== 36)
|
|
170
|
+
return eventFailure("defect", "VALIDATION", "event, distinct ID, or stable call identity is invalid");
|
|
171
|
+
const timestamp = canonicalTimestamp(input.timestamp);
|
|
172
|
+
if (!timestamp) return eventFailure("defect", "VALIDATION", "timestamp must be an RFC3339 instant");
|
|
173
|
+
const token = await this.client.projectToken(call);
|
|
174
|
+
if (!token) return eventFailure("defect", "AUTHENTICATION", "PostHog project token is unavailable or invalid");
|
|
175
|
+
let body;
|
|
176
|
+
try {
|
|
177
|
+
body = Buffer.from(JSON.stringify({
|
|
178
|
+
token,
|
|
179
|
+
event: input.event,
|
|
180
|
+
distinct_id: input.distinctId,
|
|
181
|
+
timestamp,
|
|
182
|
+
uuid: call.idempotencyKey,
|
|
183
|
+
...input.properties && Object.keys(input.properties).length ? { properties: input.properties } : {}
|
|
184
|
+
}));
|
|
185
|
+
} catch {
|
|
186
|
+
return eventFailure("defect", "VALIDATION", "event payload exceeds the limit");
|
|
187
|
+
}
|
|
188
|
+
if (body.byteLength > 1 << 20) return eventFailure("defect", "VALIDATION", "event payload exceeds the limit");
|
|
189
|
+
const exchange = await this.client.exchange(
|
|
190
|
+
call,
|
|
191
|
+
"POST",
|
|
192
|
+
`${this.client.captureUrl}/i/v0/e/`,
|
|
193
|
+
{ Accept: "application/json", "Content-Type": "application/json" },
|
|
194
|
+
body
|
|
195
|
+
);
|
|
196
|
+
if ("transportFailure" in exchange) return eventRetry("TRANSPORT", "PostHog capture response is unavailable");
|
|
197
|
+
const { response, tooLarge } = exchange;
|
|
198
|
+
const retryAfter = this.client.retryAfter(response);
|
|
199
|
+
if (response.status === 429) return eventRetry("RATE_LIMIT", "PostHog rate limited capture", retryAfter);
|
|
200
|
+
if (response.status === 408 || response.status >= 500) return eventRetry("AVAILABILITY", "PostHog capture is temporarily unavailable", retryAfter);
|
|
201
|
+
if (response.status !== 200) return eventFailure("providerRejected", rejectionKind(response.status), `PostHog rejected capture with HTTP ${response.status}`);
|
|
202
|
+
if (tooLarge || response.body.byteLength > this.client.maxResponseBytes)
|
|
203
|
+
return eventRetry("RESPONSE_TOO_LARGE", "PostHog capture confirmation exceeded the limit");
|
|
204
|
+
let answer;
|
|
205
|
+
try {
|
|
206
|
+
answer = JSON.parse(Buffer.from(response.body).toString("utf8"));
|
|
207
|
+
} catch {
|
|
208
|
+
return eventRetry("PROTOCOL", "PostHog capture confirmation is unusable");
|
|
209
|
+
}
|
|
210
|
+
if (!isRecord(answer) || answer.status !== "Ok") return eventRetry("PROTOCOL", "PostHog capture confirmation is unusable");
|
|
211
|
+
if (answer.quota_limited !== void 0 && answer.quota_limited !== null && JSON.stringify(answer.quota_limited) !== "[]" && JSON.stringify(answer.quota_limited) !== "{}")
|
|
212
|
+
return eventFailure("quotaLimited", "PROVIDER_REJECTION", "PostHog reported an event quota limit");
|
|
213
|
+
return newMutationBranch("accepted", { eventId: call.idempotencyKey, accepted: true });
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
var ListInsightsOperation = class {
|
|
217
|
+
/** Bind the provider client. */
|
|
218
|
+
constructor(client) {
|
|
219
|
+
this.client = client;
|
|
220
|
+
}
|
|
221
|
+
client;
|
|
222
|
+
/** Return the generated Query contract. */
|
|
223
|
+
definition() {
|
|
224
|
+
return ListInsightsDefinition;
|
|
225
|
+
}
|
|
226
|
+
/** Validate, request, and classify one bounded insight page. */
|
|
227
|
+
async invoke(call, input) {
|
|
228
|
+
if (!input || !Number.isSafeInteger(input.projectId) || input.projectId <= 0 || !Number.isSafeInteger(input.offset) || input.offset < 0 || !Number.isSafeInteger(input.limit ?? 0) || (input.limit ?? 0) < 0 || (input.limit ?? 0) > 100)
|
|
229
|
+
return pageFailure("defect", "VALIDATION", "project ID, offset, or limit is invalid");
|
|
230
|
+
const limit = input.limit || 20;
|
|
231
|
+
const key = await this.client.personalApiKey(call);
|
|
232
|
+
if (!key) return pageFailure("defect", "AUTHENTICATION", "PostHog personal API key is unavailable or invalid");
|
|
233
|
+
const url = `${this.client.appUrl}/api/projects/${input.projectId}/insights/?limit=${limit}&offset=${input.offset}`;
|
|
234
|
+
const exchange = await this.client.exchange(
|
|
235
|
+
call,
|
|
236
|
+
"GET",
|
|
237
|
+
url,
|
|
238
|
+
{ Accept: "application/json", Authorization: `Bearer ${key}` }
|
|
239
|
+
);
|
|
240
|
+
if ("transportFailure" in exchange) return pageRetry("TRANSPORT", "PostHog insight response is unavailable");
|
|
241
|
+
const { response, tooLarge } = exchange;
|
|
242
|
+
const retryAfter = this.client.retryAfter(response);
|
|
243
|
+
if (response.status === 429) return pageRetry("RATE_LIMIT", "PostHog rate limited insight listing", retryAfter);
|
|
244
|
+
if (response.status === 408 || response.status >= 500)
|
|
245
|
+
return pageRetry("AVAILABILITY", "PostHog insight listing is temporarily unavailable", retryAfter);
|
|
246
|
+
if (response.status !== 200) return pageFailure(
|
|
247
|
+
"providerRejected",
|
|
248
|
+
rejectionKind(response.status),
|
|
249
|
+
`PostHog rejected insight listing with HTTP ${response.status}`
|
|
250
|
+
);
|
|
251
|
+
if (tooLarge || response.body.byteLength > this.client.maxResponseBytes)
|
|
252
|
+
return pageFailure("invalidResponse", "RESPONSE_TOO_LARGE", "PostHog insight page exceeded the limit");
|
|
253
|
+
let answer;
|
|
254
|
+
try {
|
|
255
|
+
answer = JSON.parse(Buffer.from(response.body).toString("utf8"));
|
|
256
|
+
} catch {
|
|
257
|
+
return pageFailure("invalidResponse", "PROTOCOL", "PostHog returned an invalid insight page");
|
|
258
|
+
}
|
|
259
|
+
const page = decodePage(answer, input.offset, limit);
|
|
260
|
+
if (!page) return pageFailure("invalidResponse", "PROTOCOL", "PostHog returned an invalid insight page");
|
|
261
|
+
return newQueryBranch("listed", page);
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
function validEvent(input) {
|
|
265
|
+
if (!input || typeof input.event !== "string" || !input.event.trim() || typeof input.distinctId !== "string" || !input.distinctId.trim() || Buffer.byteLength(input.event) > 256 || Buffer.byteLength(input.distinctId) > 512) return false;
|
|
266
|
+
return Object.entries(input.properties ?? {}).every(([name, value]) => !!name.trim() && !name.startsWith("$") && !["token", "api_key", "password", "secret"].includes(name.toLowerCase()) && Buffer.byteLength(name) <= 128 && typeof value === "string" && Buffer.byteLength(value) <= 4096);
|
|
267
|
+
}
|
|
268
|
+
function canonicalTimestamp(value) {
|
|
269
|
+
if (typeof value !== "string" || !/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.\d+)?(?:Z|[+-]\d\d:\d\d)$/.test(value)) return void 0;
|
|
270
|
+
const milliseconds = Date.parse(value);
|
|
271
|
+
if (!Number.isFinite(milliseconds) || milliseconds === 0) return void 0;
|
|
272
|
+
return new Date(milliseconds).toISOString().replace(/\.000Z$/, "Z");
|
|
273
|
+
}
|
|
274
|
+
function decodePage(value, offset, limit) {
|
|
275
|
+
if (!isRecord(value) || !Array.isArray(value.results) || value.results.length > limit || value.next !== void 0 && value.next !== null && typeof value.next !== "string") return void 0;
|
|
276
|
+
const insights = [];
|
|
277
|
+
for (const raw of value.results) {
|
|
278
|
+
if (!isRecord(raw) || !Number.isSafeInteger(raw.id) || raw.id <= 0 || raw.name !== void 0 && raw.name !== null && typeof raw.name !== "string") return void 0;
|
|
279
|
+
insights.push({ id: raw.id, name: typeof raw.name === "string" ? raw.name : "" });
|
|
280
|
+
}
|
|
281
|
+
return { insights, hasMore: !!value.next, offset, limit };
|
|
282
|
+
}
|
|
283
|
+
function isRecord(value) {
|
|
284
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
285
|
+
}
|
|
286
|
+
function rejectionKind(status) {
|
|
287
|
+
return status === 401 ? "AUTHENTICATION" : status === 403 ? "AUTHORIZATION" : "PROVIDER_REJECTION";
|
|
288
|
+
}
|
|
289
|
+
function failure(operation, kind, message) {
|
|
290
|
+
return { kind, provider: "posthog", operation, message };
|
|
291
|
+
}
|
|
292
|
+
function eventFailure(branch, kind, message) {
|
|
293
|
+
return newMutationBranch(branch, emptyEvent, {}, failure("captureEvent", kind, message));
|
|
294
|
+
}
|
|
295
|
+
function eventRetry(kind, message, after = 0) {
|
|
296
|
+
return newMutationRetry(failure("captureEvent", kind, message), after);
|
|
297
|
+
}
|
|
298
|
+
function pageFailure(branch, kind, message) {
|
|
299
|
+
return newQueryBranch(branch, emptyPage, {}, failure("listInsights", kind, message));
|
|
300
|
+
}
|
|
301
|
+
function pageRetry(kind, message, after = 0) {
|
|
302
|
+
return newQueryRetry(failure("listInsights", kind, message), after);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// src/project.ts
|
|
306
|
+
var settingsSchema = z.strictObject({
|
|
307
|
+
captureUrl: z.string().optional(),
|
|
308
|
+
appUrl: z.string().optional(),
|
|
309
|
+
timeout: z.union([z.string(), z.number().int()]).optional(),
|
|
310
|
+
maxResponseBytes: z.number().int().optional()
|
|
311
|
+
});
|
|
312
|
+
function newProjectConnection2(project, connectionName, options = {}) {
|
|
313
|
+
return newProjectConnection(project, connectionName, (loadedProject, name) => {
|
|
314
|
+
const selected = loadedProject.configuration.connections.find((entry) => entry.connectorId === "posthog" && entry.connectionName === name);
|
|
315
|
+
if (!selected) throw new TypeError("PostHog project connection is not configured");
|
|
316
|
+
const settings = settingsSchema.parse(selected.configuration);
|
|
317
|
+
const timeoutMs = typeof settings.timeout === "number" ? Math.ceil(settings.timeout / 1e6) : settings.timeout !== void 0 ? parseDurationMilliseconds(settings.timeout) : void 0;
|
|
318
|
+
const config = {
|
|
319
|
+
...settings.captureUrl !== void 0 ? { captureUrl: settings.captureUrl } : {},
|
|
320
|
+
...settings.appUrl !== void 0 ? { appUrl: settings.appUrl } : {},
|
|
321
|
+
...timeoutMs !== void 0 ? { timeoutMs } : {},
|
|
322
|
+
...settings.maxResponseBytes !== void 0 ? { maxResponseBytes: settings.maxResponseBytes } : {}
|
|
323
|
+
};
|
|
324
|
+
const credentials = {
|
|
325
|
+
async resolve(call, signal) {
|
|
326
|
+
void call;
|
|
327
|
+
return decodeCredentials(await loadedProject.resolveCredential("posthog", name, signal));
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
return new PostHogClient(config, credentials, options);
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
function parseDurationMilliseconds(value) {
|
|
334
|
+
let remaining = value;
|
|
335
|
+
let milliseconds = 0;
|
|
336
|
+
const units = { ns: 1e-6, us: 1e-3, "\xB5s": 1e-3, ms: 1, s: 1e3, m: 6e4, h: 36e5 };
|
|
337
|
+
while (remaining) {
|
|
338
|
+
const component = /^(\d+(?:\.\d+)?)(ns|us|µs|ms|s|m|h)/.exec(remaining);
|
|
339
|
+
if (!component) throw new TypeError("PostHog timeout must be a positive Go duration");
|
|
340
|
+
milliseconds += Number(component[1]) * (units[component[2] ?? ""] ?? NaN);
|
|
341
|
+
remaining = remaining.slice(component[0].length);
|
|
342
|
+
}
|
|
343
|
+
if (!Number.isSafeInteger(milliseconds) || milliseconds <= 0)
|
|
344
|
+
throw new TypeError("PostHog timeout must resolve to positive whole milliseconds");
|
|
345
|
+
return milliseconds;
|
|
346
|
+
}
|
|
347
|
+
export {
|
|
348
|
+
CaptureEventBranch,
|
|
349
|
+
CaptureEventBranchAccepted,
|
|
350
|
+
CaptureEventBranchDefect,
|
|
351
|
+
CaptureEventBranchProviderRejected,
|
|
352
|
+
CaptureEventBranchQuotaLimited,
|
|
353
|
+
CaptureEventDefinition,
|
|
354
|
+
CaptureEventInputSchema,
|
|
355
|
+
CaptureEventMetadata,
|
|
356
|
+
CaptureEventOperation,
|
|
357
|
+
CapturedEventSchema,
|
|
358
|
+
ConfigSchema,
|
|
359
|
+
Connection,
|
|
360
|
+
ConnectorID,
|
|
361
|
+
InsightMetadataSchema,
|
|
362
|
+
InsightsPageSchema,
|
|
363
|
+
ListInsightsBranch,
|
|
364
|
+
ListInsightsBranchDefect,
|
|
365
|
+
ListInsightsBranchInvalidResponse,
|
|
366
|
+
ListInsightsBranchListed,
|
|
367
|
+
ListInsightsBranchProviderRejected,
|
|
368
|
+
ListInsightsDefinition,
|
|
369
|
+
ListInsightsInputSchema,
|
|
370
|
+
ListInsightsMetadata,
|
|
371
|
+
ListInsightsOperation,
|
|
372
|
+
PostHogClient,
|
|
373
|
+
ProviderID,
|
|
374
|
+
decodeCredentials,
|
|
375
|
+
newCaptureEventStep,
|
|
376
|
+
newConnection,
|
|
377
|
+
newConnectionWithOperations,
|
|
378
|
+
newListInsightsStep,
|
|
379
|
+
newProjectConnection2 as newProjectConnection
|
|
380
|
+
};
|
package/dist/mock.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { MockMutation, MockQuery, Case } from '@superdurable/connectors-sdk/connectormock';
|
|
2
|
+
import { Failure } from '@superdurable/connectors-sdk';
|
|
3
|
+
import { O as Operations, b as Connection, C as CaptureEventInput, a as CapturedEvent, L as ListInsightsInput, I as InsightsPage, i as InsightMetadata } from './connection-BmXhoEU7.js';
|
|
4
|
+
import 'zod';
|
|
5
|
+
|
|
6
|
+
/** Go zero value for CaptureEventInput in scripted cases. */
|
|
7
|
+
declare const emptyCaptureEventInput: CaptureEventInput;
|
|
8
|
+
/** Go zero value for CapturedEvent in scripted cases. */
|
|
9
|
+
declare const emptyCapturedEvent: CapturedEvent;
|
|
10
|
+
/** Go zero value for ListInsightsInput in scripted cases. */
|
|
11
|
+
declare const emptyListInsightsInput: ListInsightsInput;
|
|
12
|
+
/** Go zero value for InsightMetadata in scripted cases. */
|
|
13
|
+
declare const emptyInsightMetadata: InsightMetadata;
|
|
14
|
+
/** Go zero value for InsightsPage in scripted cases. */
|
|
15
|
+
declare const emptyInsightsPage: InsightsPage;
|
|
16
|
+
/** Script the accepted branch. */
|
|
17
|
+
declare function captureEventAccepted(value: CapturedEvent, failure?: Failure): Case<CapturedEvent>;
|
|
18
|
+
/** Script the quotaLimited branch. */
|
|
19
|
+
declare function captureEventQuotaLimited(value: CapturedEvent, failure?: Failure): Case<CapturedEvent>;
|
|
20
|
+
/** Script the providerRejected branch. */
|
|
21
|
+
declare function captureEventProviderRejected(value: CapturedEvent, failure?: Failure): Case<CapturedEvent>;
|
|
22
|
+
/** Script the defect branch. */
|
|
23
|
+
declare function captureEventDefect(value: CapturedEvent, failure?: Failure): Case<CapturedEvent>;
|
|
24
|
+
/** Script a safe retry of captureEvent. */
|
|
25
|
+
declare function captureEventRetry(failure: Failure, retryAfterMs?: number): Case<CapturedEvent>;
|
|
26
|
+
/** Manifest scenario acceptedSignup for captureEvent. */
|
|
27
|
+
declare function captureEventAcceptedSignup(): Case<CapturedEvent>;
|
|
28
|
+
/** Default captureEvent scenario. */
|
|
29
|
+
declare function captureEventDefault(): Case<CapturedEvent>;
|
|
30
|
+
/** Script the listed branch. */
|
|
31
|
+
declare function listInsightsListed(value: InsightsPage, failure?: Failure): Case<InsightsPage>;
|
|
32
|
+
/** Script the providerRejected branch. */
|
|
33
|
+
declare function listInsightsProviderRejected(value: InsightsPage, failure?: Failure): Case<InsightsPage>;
|
|
34
|
+
/** Script the invalidResponse branch. */
|
|
35
|
+
declare function listInsightsInvalidResponse(value: InsightsPage, failure?: Failure): Case<InsightsPage>;
|
|
36
|
+
/** Script the defect branch. */
|
|
37
|
+
declare function listInsightsDefect(value: InsightsPage, failure?: Failure): Case<InsightsPage>;
|
|
38
|
+
/** Script a safe retry of listInsights. */
|
|
39
|
+
declare function listInsightsRetry(failure: Failure, retryAfterMs?: number): Case<InsightsPage>;
|
|
40
|
+
/** Manifest scenario listedSignupInsight for listInsights. */
|
|
41
|
+
declare function listInsightsListedSignupInsight(): Case<InsightsPage>;
|
|
42
|
+
/** Default listInsights scenario. */
|
|
43
|
+
declare function listInsightsDefault(): Case<InsightsPage>;
|
|
44
|
+
/** Scripted operations and manifest defaults for this connector. */
|
|
45
|
+
declare class GeneratedMock implements Operations {
|
|
46
|
+
#private;
|
|
47
|
+
constructor(connectionName: string);
|
|
48
|
+
connection(): Connection;
|
|
49
|
+
captureEvent(): MockMutation<CaptureEventInput, CapturedEvent>;
|
|
50
|
+
listInsights(): MockQuery<ListInsightsInput, InsightsPage>;
|
|
51
|
+
assertNoFailures(): void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { GeneratedMock, GeneratedMock as Mock, captureEventAccepted, captureEventAcceptedSignup, captureEventDefault, captureEventDefect, captureEventProviderRejected, captureEventQuotaLimited, captureEventRetry, emptyCaptureEventInput, emptyCapturedEvent, emptyInsightMetadata, emptyInsightsPage, emptyListInsightsInput, listInsightsDefault, listInsightsDefect, listInsightsInvalidResponse, listInsightsListed, listInsightsListedSignupInsight, listInsightsProviderRejected, listInsightsRetry };
|
package/dist/mock.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CaptureEventDefinition,
|
|
3
|
+
CaptureEventInputSchema,
|
|
4
|
+
CapturedEventSchema,
|
|
5
|
+
InsightMetadataSchema,
|
|
6
|
+
InsightsPageSchema,
|
|
7
|
+
ListInsightsDefinition,
|
|
8
|
+
ListInsightsInputSchema,
|
|
9
|
+
ProviderID,
|
|
10
|
+
newConnectionWithOperations
|
|
11
|
+
} from "./chunk-JWKU3SHH.js";
|
|
12
|
+
|
|
13
|
+
// src/generated/mock.ts
|
|
14
|
+
import { branchCase, retryCase, newMutation, newQuery } from "@superdurable/connectors-sdk/connectormock";
|
|
15
|
+
var emptyCaptureEventInput = CaptureEventInputSchema.parse({
|
|
16
|
+
"event": "",
|
|
17
|
+
"distinctId": "",
|
|
18
|
+
"timestamp": ""
|
|
19
|
+
});
|
|
20
|
+
var emptyCapturedEvent = CapturedEventSchema.parse({
|
|
21
|
+
"eventId": "",
|
|
22
|
+
"accepted": false
|
|
23
|
+
});
|
|
24
|
+
var emptyListInsightsInput = ListInsightsInputSchema.parse({
|
|
25
|
+
"projectId": 0,
|
|
26
|
+
"offset": 0
|
|
27
|
+
});
|
|
28
|
+
var emptyInsightMetadata = InsightMetadataSchema.parse({
|
|
29
|
+
"id": 0,
|
|
30
|
+
"name": ""
|
|
31
|
+
});
|
|
32
|
+
var emptyInsightsPage = InsightsPageSchema.parse({
|
|
33
|
+
"insights": [],
|
|
34
|
+
"hasMore": false,
|
|
35
|
+
"offset": 0,
|
|
36
|
+
"limit": 0
|
|
37
|
+
});
|
|
38
|
+
function captureEventAccepted(value, failure) {
|
|
39
|
+
return branchCase("accepted", value, failure);
|
|
40
|
+
}
|
|
41
|
+
function captureEventQuotaLimited(value, failure) {
|
|
42
|
+
return branchCase("quotaLimited", value, failure);
|
|
43
|
+
}
|
|
44
|
+
function captureEventProviderRejected(value, failure) {
|
|
45
|
+
return branchCase("providerRejected", value, failure);
|
|
46
|
+
}
|
|
47
|
+
function captureEventDefect(value, failure) {
|
|
48
|
+
return branchCase("defect", value, failure);
|
|
49
|
+
}
|
|
50
|
+
function captureEventRetry(failure, retryAfterMs = 0) {
|
|
51
|
+
return retryCase(failure, retryAfterMs);
|
|
52
|
+
}
|
|
53
|
+
function captureEventAcceptedSignup() {
|
|
54
|
+
const value = CapturedEventSchema.parse({ "accepted": true, "eventId": "4b5d3f33-2e21-4c1c-b392-2dae2a74a2ed" });
|
|
55
|
+
return branchCase("accepted", value);
|
|
56
|
+
}
|
|
57
|
+
function captureEventDefault() {
|
|
58
|
+
return captureEventAcceptedSignup();
|
|
59
|
+
}
|
|
60
|
+
function listInsightsListed(value, failure) {
|
|
61
|
+
return branchCase("listed", value, failure);
|
|
62
|
+
}
|
|
63
|
+
function listInsightsProviderRejected(value, failure) {
|
|
64
|
+
return branchCase("providerRejected", value, failure);
|
|
65
|
+
}
|
|
66
|
+
function listInsightsInvalidResponse(value, failure) {
|
|
67
|
+
return branchCase("invalidResponse", value, failure);
|
|
68
|
+
}
|
|
69
|
+
function listInsightsDefect(value, failure) {
|
|
70
|
+
return branchCase("defect", value, failure);
|
|
71
|
+
}
|
|
72
|
+
function listInsightsRetry(failure, retryAfterMs = 0) {
|
|
73
|
+
return retryCase(failure, retryAfterMs);
|
|
74
|
+
}
|
|
75
|
+
function listInsightsListedSignupInsight() {
|
|
76
|
+
const value = InsightsPageSchema.parse({ "hasMore": false, "insights": [{ "id": 42, "name": "Signups by day" }], "limit": 20, "offset": 0 });
|
|
77
|
+
return branchCase("listed", value);
|
|
78
|
+
}
|
|
79
|
+
function listInsightsDefault() {
|
|
80
|
+
return listInsightsListedSignupInsight();
|
|
81
|
+
}
|
|
82
|
+
var GeneratedMock = class {
|
|
83
|
+
#captureEvent;
|
|
84
|
+
#listInsights;
|
|
85
|
+
#connection;
|
|
86
|
+
constructor(connectionName) {
|
|
87
|
+
this.#captureEvent = newMutation(CaptureEventDefinition).default(captureEventDefault());
|
|
88
|
+
this.#listInsights = newQuery(ListInsightsDefinition).default(listInsightsDefault());
|
|
89
|
+
this.#connection = newConnectionWithOperations(this, { provider: ProviderID, name: connectionName });
|
|
90
|
+
}
|
|
91
|
+
connection() {
|
|
92
|
+
return this.#connection;
|
|
93
|
+
}
|
|
94
|
+
captureEvent() {
|
|
95
|
+
return this.#captureEvent;
|
|
96
|
+
}
|
|
97
|
+
listInsights() {
|
|
98
|
+
return this.#listInsights;
|
|
99
|
+
}
|
|
100
|
+
assertNoFailures() {
|
|
101
|
+
this.#captureEvent.assertNoFailures();
|
|
102
|
+
this.#listInsights.assertNoFailures();
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
export {
|
|
106
|
+
GeneratedMock,
|
|
107
|
+
GeneratedMock as Mock,
|
|
108
|
+
captureEventAccepted,
|
|
109
|
+
captureEventAcceptedSignup,
|
|
110
|
+
captureEventDefault,
|
|
111
|
+
captureEventDefect,
|
|
112
|
+
captureEventProviderRejected,
|
|
113
|
+
captureEventQuotaLimited,
|
|
114
|
+
captureEventRetry,
|
|
115
|
+
emptyCaptureEventInput,
|
|
116
|
+
emptyCapturedEvent,
|
|
117
|
+
emptyInsightMetadata,
|
|
118
|
+
emptyInsightsPage,
|
|
119
|
+
emptyListInsightsInput,
|
|
120
|
+
listInsightsDefault,
|
|
121
|
+
listInsightsDefect,
|
|
122
|
+
listInsightsInvalidResponse,
|
|
123
|
+
listInsightsListed,
|
|
124
|
+
listInsightsListedSignupInsight,
|
|
125
|
+
listInsightsProviderRejected,
|
|
126
|
+
listInsightsRetry
|
|
127
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,63 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superdurable/connector-posthog",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"description": "
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "PostHog event capture and saved insight listing for Dex TypeScript applications",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/superdurable/dex-connectors-library.git",
|
|
9
|
+
"directory": "connectors/posthog/typescript"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public",
|
|
14
|
+
"registry": "https://registry.npmjs.org"
|
|
15
|
+
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": "^22.0.0 || ^24.0.0"
|
|
18
|
+
},
|
|
19
|
+
"module": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./mock": {
|
|
27
|
+
"types": "./dist/mock.d.ts",
|
|
28
|
+
"import": "./dist/mock.js"
|
|
29
|
+
},
|
|
30
|
+
"./dex-connector.json": "./dex-connector.json"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE",
|
|
36
|
+
"dex-connector.json"
|
|
37
|
+
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"prepack": "npm run build",
|
|
40
|
+
"build": "tsup src/index.ts src/mock.ts --format esm --dts --clean",
|
|
41
|
+
"typecheck": "tsc --noEmit",
|
|
42
|
+
"lint": "eslint src test examples",
|
|
43
|
+
"test": "vitest run --exclude 'test/integration/**'",
|
|
44
|
+
"test:integration": "vitest run test/integration/*.integration.test.ts",
|
|
45
|
+
"example:worker": "tsx examples/provider-operations/worker.ts",
|
|
46
|
+
"check": "npm run typecheck && npm run lint && npm test && npm run build"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@superdurable/connectors-sdk": "0.7.0",
|
|
50
|
+
"@superdurable/dex": ">=1.28.0",
|
|
51
|
+
"zod": "^4.1.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@eslint/js": "^9.0.0",
|
|
55
|
+
"@types/node": "^22.0.0",
|
|
56
|
+
"eslint": "^9.0.0",
|
|
57
|
+
"tsup": "^8.0.0",
|
|
58
|
+
"tsx": "^4.23.15",
|
|
59
|
+
"typescript": "^5.9.0",
|
|
60
|
+
"typescript-eslint": "^8.0.0",
|
|
61
|
+
"vitest": "^3.0.0"
|
|
62
|
+
}
|
|
63
|
+
}
|