@relayfile/relay-helpers 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/README.md +48 -0
- package/dist/generated/clients.d.ts +29 -0
- package/dist/generated/clients.d.ts.map +1 -0
- package/dist/generated/clients.js +34 -0
- package/dist/generated/clients.js.map +1 -0
- package/dist/generic.d.ts +37 -0
- package/dist/generic.d.ts.map +1 -0
- package/dist/generic.js +46 -0
- package/dist/generic.js.map +1 -0
- package/dist/github.d.ts +57 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +39 -0
- package/dist/github.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/linear.d.ts +41 -0
- package/dist/linear.d.ts.map +1 -0
- package/dist/linear.js +31 -0
- package/dist/linear.js.map +1 -0
- package/dist/provider-client.d.ts +36 -0
- package/dist/provider-client.d.ts.map +1 -0
- package/dist/provider-client.js +32 -0
- package/dist/provider-client.js.map +1 -0
- package/dist/receipt.d.ts +11 -0
- package/dist/receipt.d.ts.map +1 -0
- package/dist/receipt.js +12 -0
- package/dist/receipt.js.map +1 -0
- package/dist/relay-helpers.test.d.ts +2 -0
- package/dist/relay-helpers.test.d.ts.map +1 -0
- package/dist/relay-helpers.test.js +109 -0
- package/dist/relay-helpers.test.js.map +1 -0
- package/dist/slack.d.ts +27 -0
- package/dist/slack.d.ts.map +1 -0
- package/dist/slack.js +30 -0
- package/dist/slack.js.map +1 -0
- package/package.json +31 -0
package/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# @relayfile/relay-helpers
|
|
2
|
+
|
|
3
|
+
Ergonomic, catalog-backed provider clients for Workforce agent handlers.
|
|
4
|
+
|
|
5
|
+
The runtime exposes only generic VFS helpers (`writeJsonFile`, `readJsonFile`, …);
|
|
6
|
+
the per-provider typed clients (`ctx.linear.comment(...)`) were removed. This
|
|
7
|
+
package recovers that ergonomics as an **opt-in factory**, with every path
|
|
8
|
+
sourced from [`@relayfile/adapter-core/writeback-paths`](https://www.npmjs.com/package/@relayfile/adapter-core)
|
|
9
|
+
(the adapter-owned source of truth) instead of hardcoded — so paths never drift
|
|
10
|
+
from the adapter that materializes the draft.
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { linearClient, githubClient, slackClient } from '@relayfile/relay-helpers';
|
|
14
|
+
|
|
15
|
+
const linear = linearClient(); // binds the mount root once (RELAYFILE_MOUNT_ROOT)
|
|
16
|
+
const issue = await linear.getIssue(issueId);
|
|
17
|
+
await linear.comment(issueId, ':rocket: done');
|
|
18
|
+
|
|
19
|
+
await githubClient().mergePullRequest({ owner, repo, number });
|
|
20
|
+
await slackClient().post('#eng', 'shipped');
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## A named client for every provider
|
|
24
|
+
|
|
25
|
+
Every provider in the catalog has a named client (`asanaClient`, `notionClient`,
|
|
26
|
+
`jiraClient`, … — all 29), exposing its resources as
|
|
27
|
+
`.{resource}.{path,write,read,list}`:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { notionClient } from '@relayfile/relay-helpers';
|
|
31
|
+
|
|
32
|
+
const notion = notionClient();
|
|
33
|
+
notion.pages.path({ databaseId }); // resolve a path (no IO)
|
|
34
|
+
await notion.pages.write({ databaseId }, { /* … */ }); // collection create or item write
|
|
35
|
+
await notion.pages.list({ databaseId }); // list a collection
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
- `write(params, body)` drops a uniquely-named draft for a collection resource,
|
|
39
|
+
or writes directly to an item resource (a path ending in `.json`). The
|
|
40
|
+
Relayfile writeback worker turns the draft into the real provider call.
|
|
41
|
+
- `read` / `list` operate over the catalog paths.
|
|
42
|
+
- Unknown providers/resources or missing path params throw loudly — never a
|
|
43
|
+
guessed path.
|
|
44
|
+
|
|
45
|
+
`linearClient` / `githubClient` / `slackClient` are the same resource-keyed
|
|
46
|
+
clients **plus** named ergonomic methods (`comment`, `post`, `mergePullRequest`,
|
|
47
|
+
…). `relayClient(provider)` is the dynamic, string-keyed escape hatch when the
|
|
48
|
+
provider isn't known at author time.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { IntegrationClientOptions } from '@relayfile/adapter-core/vfs-client';
|
|
2
|
+
import { type ProviderClient } from '../provider-client.js';
|
|
3
|
+
export declare const asanaClient: (opts?: IntegrationClientOptions) => ProviderClient<"asana">;
|
|
4
|
+
export declare const azureBlobClient: (opts?: IntegrationClientOptions) => ProviderClient<"azure-blob">;
|
|
5
|
+
export declare const boxClient: (opts?: IntegrationClientOptions) => ProviderClient<"box">;
|
|
6
|
+
export declare const clickupClient: (opts?: IntegrationClientOptions) => ProviderClient<"clickup">;
|
|
7
|
+
export declare const confluenceClient: (opts?: IntegrationClientOptions) => ProviderClient<"confluence">;
|
|
8
|
+
export declare const dropboxClient: (opts?: IntegrationClientOptions) => ProviderClient<"dropbox">;
|
|
9
|
+
export declare const gcsClient: (opts?: IntegrationClientOptions) => ProviderClient<"gcs">;
|
|
10
|
+
export declare const gitlabClient: (opts?: IntegrationClientOptions) => ProviderClient<"gitlab">;
|
|
11
|
+
export declare const gmailClient: (opts?: IntegrationClientOptions) => ProviderClient<"gmail">;
|
|
12
|
+
export declare const googleCalendarClient: (opts?: IntegrationClientOptions) => ProviderClient<"google-calendar">;
|
|
13
|
+
export declare const googleDriveClient: (opts?: IntegrationClientOptions) => ProviderClient<"google-drive">;
|
|
14
|
+
export declare const granolaClient: (opts?: IntegrationClientOptions) => ProviderClient<"granola">;
|
|
15
|
+
export declare const hubspotClient: (opts?: IntegrationClientOptions) => ProviderClient<"hubspot">;
|
|
16
|
+
export declare const intercomClient: (opts?: IntegrationClientOptions) => ProviderClient<"intercom">;
|
|
17
|
+
export declare const jiraClient: (opts?: IntegrationClientOptions) => ProviderClient<"jira">;
|
|
18
|
+
export declare const notionClient: (opts?: IntegrationClientOptions) => ProviderClient<"notion">;
|
|
19
|
+
export declare const onedriveClient: (opts?: IntegrationClientOptions) => ProviderClient<"onedrive">;
|
|
20
|
+
export declare const pipedriveClient: (opts?: IntegrationClientOptions) => ProviderClient<"pipedrive">;
|
|
21
|
+
export declare const postgresClient: (opts?: IntegrationClientOptions) => ProviderClient<"postgres">;
|
|
22
|
+
export declare const redditClient: (opts?: IntegrationClientOptions) => ProviderClient<"reddit">;
|
|
23
|
+
export declare const redisClient: (opts?: IntegrationClientOptions) => ProviderClient<"redis">;
|
|
24
|
+
export declare const s3Client: (opts?: IntegrationClientOptions) => ProviderClient<"s3">;
|
|
25
|
+
export declare const salesforceClient: (opts?: IntegrationClientOptions) => ProviderClient<"salesforce">;
|
|
26
|
+
export declare const sharepointClient: (opts?: IntegrationClientOptions) => ProviderClient<"sharepoint">;
|
|
27
|
+
export declare const teamsClient: (opts?: IntegrationClientOptions) => ProviderClient<"teams">;
|
|
28
|
+
export declare const zendeskClient: (opts?: IntegrationClientOptions) => ProviderClient<"zendesk">;
|
|
29
|
+
//# sourceMappingURL=clients.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clients.d.ts","sourceRoot":"","sources":["../../src/generated/clients.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5E,eAAO,MAAM,WAAW,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,OAAO,CACrD,CAAC;AAEhC,eAAO,MAAM,eAAe,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,YAAY,CACzD,CAAC;AAErC,eAAO,MAAM,SAAS,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,KAAK,CACnD,CAAC;AAE9B,eAAO,MAAM,aAAa,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,SAAS,CACvD,CAAC;AAElC,eAAO,MAAM,gBAAgB,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,YAAY,CAC1D,CAAC;AAErC,eAAO,MAAM,aAAa,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,SAAS,CACvD,CAAC;AAElC,eAAO,MAAM,SAAS,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,KAAK,CACnD,CAAC;AAE9B,eAAO,MAAM,YAAY,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,QAAQ,CACtD,CAAC;AAEjC,eAAO,MAAM,WAAW,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,OAAO,CACrD,CAAC;AAEhC,eAAO,MAAM,oBAAoB,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,iBAAiB,CAC9D,CAAC;AAE1C,eAAO,MAAM,iBAAiB,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,cAAc,CAC3D,CAAC;AAEvC,eAAO,MAAM,aAAa,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,SAAS,CACvD,CAAC;AAElC,eAAO,MAAM,aAAa,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,SAAS,CACvD,CAAC;AAElC,eAAO,MAAM,cAAc,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,UAAU,CACxD,CAAC;AAEnC,eAAO,MAAM,UAAU,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,MAAM,CACpD,CAAC;AAE/B,eAAO,MAAM,YAAY,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,QAAQ,CACtD,CAAC;AAEjC,eAAO,MAAM,cAAc,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,UAAU,CACxD,CAAC;AAEnC,eAAO,MAAM,eAAe,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,WAAW,CACzD,CAAC;AAEpC,eAAO,MAAM,cAAc,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,UAAU,CACxD,CAAC;AAEnC,eAAO,MAAM,YAAY,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,QAAQ,CACtD,CAAC;AAEjC,eAAO,MAAM,WAAW,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,OAAO,CACrD,CAAC;AAEhC,eAAO,MAAM,QAAQ,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,IAAI,CAClD,CAAC;AAE7B,eAAO,MAAM,gBAAgB,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,YAAY,CAC1D,CAAC;AAErC,eAAO,MAAM,gBAAgB,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,YAAY,CAC1D,CAAC;AAErC,eAAO,MAAM,WAAW,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,OAAO,CACrD,CAAC;AAEhC,eAAO,MAAM,aAAa,GAAI,OAAO,wBAAwB,KAAG,cAAc,CAAC,SAAS,CACvD,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// GENERATED by scripts/generate-clients.mjs from
|
|
2
|
+
// @relayfile/adapter-core/writeback-paths — do not edit by hand.
|
|
3
|
+
// Run `npm run gen -w @relayfile/relay-helpers` after bumping adapter-core.
|
|
4
|
+
//
|
|
5
|
+
// linear / github / slack have bespoke ergonomic clients in their own modules;
|
|
6
|
+
// every other catalog provider gets a uniform resource-keyed client here.
|
|
7
|
+
import { providerClient } from '../provider-client.js';
|
|
8
|
+
export const asanaClient = (opts) => providerClient('asana', opts);
|
|
9
|
+
export const azureBlobClient = (opts) => providerClient('azure-blob', opts);
|
|
10
|
+
export const boxClient = (opts) => providerClient('box', opts);
|
|
11
|
+
export const clickupClient = (opts) => providerClient('clickup', opts);
|
|
12
|
+
export const confluenceClient = (opts) => providerClient('confluence', opts);
|
|
13
|
+
export const dropboxClient = (opts) => providerClient('dropbox', opts);
|
|
14
|
+
export const gcsClient = (opts) => providerClient('gcs', opts);
|
|
15
|
+
export const gitlabClient = (opts) => providerClient('gitlab', opts);
|
|
16
|
+
export const gmailClient = (opts) => providerClient('gmail', opts);
|
|
17
|
+
export const googleCalendarClient = (opts) => providerClient('google-calendar', opts);
|
|
18
|
+
export const googleDriveClient = (opts) => providerClient('google-drive', opts);
|
|
19
|
+
export const granolaClient = (opts) => providerClient('granola', opts);
|
|
20
|
+
export const hubspotClient = (opts) => providerClient('hubspot', opts);
|
|
21
|
+
export const intercomClient = (opts) => providerClient('intercom', opts);
|
|
22
|
+
export const jiraClient = (opts) => providerClient('jira', opts);
|
|
23
|
+
export const notionClient = (opts) => providerClient('notion', opts);
|
|
24
|
+
export const onedriveClient = (opts) => providerClient('onedrive', opts);
|
|
25
|
+
export const pipedriveClient = (opts) => providerClient('pipedrive', opts);
|
|
26
|
+
export const postgresClient = (opts) => providerClient('postgres', opts);
|
|
27
|
+
export const redditClient = (opts) => providerClient('reddit', opts);
|
|
28
|
+
export const redisClient = (opts) => providerClient('redis', opts);
|
|
29
|
+
export const s3Client = (opts) => providerClient('s3', opts);
|
|
30
|
+
export const salesforceClient = (opts) => providerClient('salesforce', opts);
|
|
31
|
+
export const sharepointClient = (opts) => providerClient('sharepoint', opts);
|
|
32
|
+
export const teamsClient = (opts) => providerClient('teams', opts);
|
|
33
|
+
export const zendeskClient = (opts) => providerClient('zendesk', opts);
|
|
34
|
+
//# sourceMappingURL=clients.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clients.js","sourceRoot":"","sources":["../../src/generated/clients.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { encodeSegment, type IntegrationClientOptions, type WritebackResult } from '@relayfile/adapter-core/vfs-client';
|
|
2
|
+
import { type WritebackProvider, type WritebackResource } from '@relayfile/adapter-core/writeback-paths';
|
|
3
|
+
export type RelayParams = Record<string, string | number>;
|
|
4
|
+
/**
|
|
5
|
+
* A catalog-backed client for one provider. Every path comes from
|
|
6
|
+
* `@relayfile/adapter-core/writeback-paths` (the adapter-owned source of
|
|
7
|
+
* truth), so handlers never hardcode `/linear/issues/...` strings that drift
|
|
8
|
+
* from the adapter. Works for any provider in the catalog; the
|
|
9
|
+
* `linearClient` / `githubClient` / `slackClient` factories wrap this with
|
|
10
|
+
* named, ergonomic methods.
|
|
11
|
+
*/
|
|
12
|
+
export interface RelayClient<P extends WritebackProvider> {
|
|
13
|
+
readonly provider: P;
|
|
14
|
+
/** Resolve a resource's canonical mount path (no IO). */
|
|
15
|
+
path(resource: WritebackResource<P> & string, params?: RelayParams): string;
|
|
16
|
+
/**
|
|
17
|
+
* Write `body`. For a collection resource (e.g. `/linear/issues/{id}/comments`)
|
|
18
|
+
* this drops a uniquely-named draft the Relayfile writeback worker turns into
|
|
19
|
+
* the create call. For an item resource (a path ending in `.json`, e.g.
|
|
20
|
+
* `…/pulls/{n}/merge.json`) this writes the body to that exact path.
|
|
21
|
+
*/
|
|
22
|
+
write(resource: WritebackResource<P> & string, params: RelayParams, body: unknown): Promise<WritebackResult>;
|
|
23
|
+
/** Read a single item resource (a `.json` path). */
|
|
24
|
+
read<T>(resource: WritebackResource<P> & string, params?: RelayParams): Promise<T>;
|
|
25
|
+
/** List the records of a collection resource. */
|
|
26
|
+
list<T>(resource: WritebackResource<P> & string, params?: RelayParams): Promise<T[]>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Build a {@link RelayClient} for `provider`. `opts` (mount root, writeback
|
|
30
|
+
* timeout, …) is bound once and reused by every method; it defaults to the
|
|
31
|
+
* ambient `RELAYFILE_MOUNT_ROOT` env, so `relayClient('linear')` is enough
|
|
32
|
+
* inside a sandbox handler.
|
|
33
|
+
*/
|
|
34
|
+
export declare function relayClient<P extends WritebackProvider>(provider: P, opts?: IntegrationClientOptions): RelayClient<P>;
|
|
35
|
+
/** Re-exported so callers can build item-read paths (`${collection}/${id}.json`). */
|
|
36
|
+
export { encodeSegment, type IntegrationClientOptions, type WritebackResult };
|
|
37
|
+
//# sourceMappingURL=generic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../src/generic.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EAIb,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACrB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACvB,MAAM,yCAAyC,CAAC;AAEjD,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,iBAAiB;IACtD,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IACrB,yDAAyD;IACzD,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC5E;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC7G,oDAAoD;IACpD,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACnF,iDAAiD;IACjD,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;CACtF;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,iBAAiB,EACrD,QAAQ,EAAE,CAAC,EACX,IAAI,GAAE,wBAA6B,GAClC,WAAW,CAAC,CAAC,CAAC,CAmChB;AAED,qFAAqF;AACrF,OAAO,EAAE,aAAa,EAAE,KAAK,wBAAwB,EAAE,KAAK,eAAe,EAAE,CAAC"}
|
package/dist/generic.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { draftFile, encodeSegment, listJsonFiles, readJsonFile, writeJsonFile } from '@relayfile/adapter-core/vfs-client';
|
|
2
|
+
import { WRITEBACK_PATH_CATALOG, writebackPath } from '@relayfile/adapter-core/writeback-paths';
|
|
3
|
+
function isItemPath(path) {
|
|
4
|
+
return path.endsWith('.json');
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Build a {@link RelayClient} for `provider`. `opts` (mount root, writeback
|
|
8
|
+
* timeout, …) is bound once and reused by every method; it defaults to the
|
|
9
|
+
* ambient `RELAYFILE_MOUNT_ROOT` env, so `relayClient('linear')` is enough
|
|
10
|
+
* inside a sandbox handler.
|
|
11
|
+
*/
|
|
12
|
+
export function relayClient(provider, opts = {}) {
|
|
13
|
+
const knownResources = () => Object.keys(WRITEBACK_PATH_CATALOG[provider] ?? {}).join(', ');
|
|
14
|
+
return {
|
|
15
|
+
provider,
|
|
16
|
+
path(resource, params = {}) {
|
|
17
|
+
return writebackPath(provider, resource, params);
|
|
18
|
+
},
|
|
19
|
+
async write(resource, params, body) {
|
|
20
|
+
const base = writebackPath(provider, resource, params);
|
|
21
|
+
const target = isItemPath(base) ? base : `${base}/${draftFile(String(resource))}`;
|
|
22
|
+
return writeJsonFile(opts, provider, `write.${String(resource)}`, target, body);
|
|
23
|
+
},
|
|
24
|
+
async read(resource, params = {}) {
|
|
25
|
+
// `async` so a validation/path error rejects the promise rather than
|
|
26
|
+
// throwing synchronously — keeps `read` consistent with `write`/`list`
|
|
27
|
+
// for callers using `.catch()`.
|
|
28
|
+
const path = writebackPath(provider, resource, params);
|
|
29
|
+
if (!isItemPath(path)) {
|
|
30
|
+
throw new Error(`read("${String(resource)}") resolves to collection "${path}"; read a specific item path or use list(). Known resources for ${provider}: ${knownResources()}`);
|
|
31
|
+
}
|
|
32
|
+
return readJsonFile(opts, provider, `read.${String(resource)}`, path);
|
|
33
|
+
},
|
|
34
|
+
async list(resource, params = {}) {
|
|
35
|
+
const path = writebackPath(provider, resource, params);
|
|
36
|
+
if (isItemPath(path)) {
|
|
37
|
+
throw new Error(`list("${String(resource)}") resolves to item "${path}"; use read() instead. Known resources for ${provider}: ${knownResources()}`);
|
|
38
|
+
}
|
|
39
|
+
const files = await listJsonFiles(opts, provider, `list.${String(resource)}`, path);
|
|
40
|
+
return files.map((file) => file.value);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** Re-exported so callers can build item-read paths (`${collection}/${id}.json`). */
|
|
45
|
+
export { encodeSegment };
|
|
46
|
+
//# sourceMappingURL=generic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic.js","sourceRoot":"","sources":["../src/generic.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,aAAa,EACb,aAAa,EACb,YAAY,EACZ,aAAa,EAGd,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,sBAAsB,EACtB,aAAa,EAGd,MAAM,yCAAyC,CAAC;AA6BjD,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,QAAW,EACX,OAAiC,EAAE;IAEnC,MAAM,cAAc,GAAG,GAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpG,OAAO;QACL,QAAQ;QACR,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE;YACxB,OAAO,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QACnD,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI;YAChC,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YACvD,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;YAClF,OAAO,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAClF,CAAC;QACD,KAAK,CAAC,IAAI,CAAI,QAAuC,EAAE,SAAsB,EAAE;YAC7E,qEAAqE;YACrE,uEAAuE;YACvE,gCAAgC;YAChC,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YACvD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CACb,SAAS,MAAM,CAAC,QAAQ,CAAC,8BAA8B,IAAI,mEAAmE,QAAQ,KAAK,cAAc,EAAE,EAAE,CAC9J,CAAC;YACJ,CAAC;YACD,OAAO,YAAY,CAAI,IAAI,EAAE,QAAQ,EAAE,QAAQ,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC3E,CAAC;QACD,KAAK,CAAC,IAAI,CAAI,QAAuC,EAAE,SAAsB,EAAE;YAC7E,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YACvD,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CACb,SAAS,MAAM,CAAC,QAAQ,CAAC,wBAAwB,IAAI,8CAA8C,QAAQ,KAAK,cAAc,EAAE,EAAE,CACnI,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,aAAa,CAAI,IAAI,EAAE,QAAQ,EAAE,QAAQ,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YACvF,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC;KACF,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,OAAO,EAAE,aAAa,EAAuD,CAAC"}
|
package/dist/github.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { IntegrationClientOptions } from '@relayfile/adapter-core/vfs-client';
|
|
2
|
+
import { type ProviderClient } from './provider-client.js';
|
|
3
|
+
export interface GithubTarget {
|
|
4
|
+
owner: string;
|
|
5
|
+
repo: string;
|
|
6
|
+
number: number;
|
|
7
|
+
}
|
|
8
|
+
export interface GithubClient extends ProviderClient<'github'> {
|
|
9
|
+
/** Comment on an issue or pull request. */
|
|
10
|
+
comment(target: GithubTarget, body: string): Promise<{
|
|
11
|
+
id: string;
|
|
12
|
+
url: string;
|
|
13
|
+
}>;
|
|
14
|
+
/** Create an issue. */
|
|
15
|
+
createIssue(args: {
|
|
16
|
+
owner: string;
|
|
17
|
+
repo: string;
|
|
18
|
+
title: string;
|
|
19
|
+
body: string;
|
|
20
|
+
labels?: string[];
|
|
21
|
+
}): Promise<{
|
|
22
|
+
id: string;
|
|
23
|
+
url: string;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Merge a pull request. (Named `mergePullRequest`, not `merge`, because
|
|
27
|
+
* `merge` is the catalog resource key exposed as `.merge`.)
|
|
28
|
+
*/
|
|
29
|
+
mergePullRequest(args: {
|
|
30
|
+
owner: string;
|
|
31
|
+
repo: string;
|
|
32
|
+
number: number;
|
|
33
|
+
method?: 'merge' | 'squash' | 'rebase';
|
|
34
|
+
commitTitle?: string;
|
|
35
|
+
commitMessage?: string;
|
|
36
|
+
sha?: string;
|
|
37
|
+
}): Promise<{
|
|
38
|
+
merged: boolean;
|
|
39
|
+
sha?: string;
|
|
40
|
+
}>;
|
|
41
|
+
/** Post a review on a pull request. */
|
|
42
|
+
review(target: GithubTarget, args: {
|
|
43
|
+
body: string;
|
|
44
|
+
event: 'COMMENT' | 'APPROVE' | 'REQUEST_CHANGES';
|
|
45
|
+
comments?: Array<{
|
|
46
|
+
path: string;
|
|
47
|
+
line: number;
|
|
48
|
+
body: string;
|
|
49
|
+
}>;
|
|
50
|
+
}): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Ergonomic GitHub client over the writeback-path catalog, plus the uniform
|
|
54
|
+
* resource-keyed access (`.issues`, `.["issue-comments"]`, `.merge`, `.reviews`).
|
|
55
|
+
*/
|
|
56
|
+
export declare function githubClient(opts?: IntegrationClientOptions): GithubClient;
|
|
57
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3E,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,QAAQ,CAAC;IAC5D,2CAA2C;IAC3C,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClF,uBAAuB;IACvB,WAAW,CAAC,IAAI,EAAE;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;KACnB,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzC;;;OAGG;IACH,gBAAgB,CAAC,IAAI,EAAE;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;QACvC,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,uCAAuC;IACvC,MAAM,CACJ,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,iBAAiB,CAAC;QACjD,QAAQ,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAChE,GACA,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,wBAA6B,GAAG,YAAY,CA+D9E"}
|
package/dist/github.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { providerClient } from './provider-client.js';
|
|
2
|
+
import { created } from './receipt.js';
|
|
3
|
+
/**
|
|
4
|
+
* Ergonomic GitHub client over the writeback-path catalog, plus the uniform
|
|
5
|
+
* resource-keyed access (`.issues`, `.["issue-comments"]`, `.merge`, `.reviews`).
|
|
6
|
+
*/
|
|
7
|
+
export function githubClient(opts = {}) {
|
|
8
|
+
const base = providerClient('github', opts);
|
|
9
|
+
return Object.assign(base, {
|
|
10
|
+
async comment(target, body) {
|
|
11
|
+
return created(await base['issue-comments'].write({ owner: target.owner, repo: target.repo, issueNumber: target.number }, { body }));
|
|
12
|
+
},
|
|
13
|
+
async createIssue(args) {
|
|
14
|
+
return created(await base.issues.write({ owner: args.owner, repo: args.repo }, { title: args.title, body: args.body, ...(args.labels ? { labels: args.labels } : {}) }));
|
|
15
|
+
},
|
|
16
|
+
async mergePullRequest(args) {
|
|
17
|
+
const result = await base.merge.write({ owner: args.owner, repo: args.repo, pullNumber: args.number }, {
|
|
18
|
+
...(args.method !== undefined ? { merge_method: args.method } : {}),
|
|
19
|
+
...(args.commitTitle !== undefined ? { commit_title: args.commitTitle } : {}),
|
|
20
|
+
...(args.commitMessage !== undefined ? { commit_message: args.commitMessage } : {}),
|
|
21
|
+
...(args.sha !== undefined ? { sha: args.sha } : {})
|
|
22
|
+
});
|
|
23
|
+
const sha = typeof result.receipt?.sha === 'string'
|
|
24
|
+
? result.receipt.sha
|
|
25
|
+
: typeof result.receipt?.id === 'string'
|
|
26
|
+
? result.receipt.id
|
|
27
|
+
: undefined;
|
|
28
|
+
const merged = result.receipt?.merged;
|
|
29
|
+
return {
|
|
30
|
+
merged: merged === true || merged === 'true' || (merged === undefined && Boolean(sha)),
|
|
31
|
+
...(sha ? { sha } : {})
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
async review(target, args) {
|
|
35
|
+
await base.reviews.write({ owner: target.owner, repo: target.repo, pullNumber: target.number }, { ...args, comments: args.comments ?? [] });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@relayfile/relay-helpers` — ergonomic, catalog-backed provider clients
|
|
3
|
+
* for Workforce agent handlers.
|
|
4
|
+
*
|
|
5
|
+
* The runtime exposes only generic VFS helpers (`writeJsonFile`, `readJsonFile`,
|
|
6
|
+
* …); the per-provider typed clients (`ctx.linear.comment(...)`) were removed.
|
|
7
|
+
* This package recovers that ergonomics as an opt-in factory, with every path
|
|
8
|
+
* sourced from `@relayfile/adapter-core/writeback-paths` (the adapter-owned
|
|
9
|
+
* source of truth) instead of hardcoded — so paths never drift from the
|
|
10
|
+
* adapter that materializes the draft.
|
|
11
|
+
*
|
|
12
|
+
* import { linearClient } from '@relayfile/relay-helpers';
|
|
13
|
+
* const linear = linearClient(); // binds the mount root once
|
|
14
|
+
* const issue = await linear.getIssue(issueId);
|
|
15
|
+
* await linear.comment(issueId, ':rocket: done');
|
|
16
|
+
*
|
|
17
|
+
* Every provider in the catalog has a named client (`asanaClient`,
|
|
18
|
+
* `notionClient`, … through all 29), exposing its resources as
|
|
19
|
+
* `.{resource}.{path,write,read,list}`. `linear` / `github` / `slack` add
|
|
20
|
+
* named ergonomic methods on top. `relayClient(provider)` is the dynamic,
|
|
21
|
+
* string-keyed escape hatch when the provider isn't known at author time.
|
|
22
|
+
*/
|
|
23
|
+
export { relayClient, encodeSegment, type RelayClient, type RelayParams } from './generic.js';
|
|
24
|
+
export { providerClient, type ProviderClient, type ResourceClient } from './provider-client.js';
|
|
25
|
+
export { created } from './receipt.js';
|
|
26
|
+
export { linearClient, type LinearClient, type LinearCreateIssueArgs } from './linear.js';
|
|
27
|
+
export { githubClient, type GithubClient, type GithubTarget } from './github.js';
|
|
28
|
+
export { slackClient, type SlackClient } from './slack.js';
|
|
29
|
+
export * from './generated/clients.js';
|
|
30
|
+
export type { IntegrationClientOptions, WritebackResult } from '@relayfile/adapter-core/vfs-client';
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9F,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAChG,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAK3D,cAAc,wBAAwB,CAAC;AAEvC,YAAY,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@relayfile/relay-helpers` — ergonomic, catalog-backed provider clients
|
|
3
|
+
* for Workforce agent handlers.
|
|
4
|
+
*
|
|
5
|
+
* The runtime exposes only generic VFS helpers (`writeJsonFile`, `readJsonFile`,
|
|
6
|
+
* …); the per-provider typed clients (`ctx.linear.comment(...)`) were removed.
|
|
7
|
+
* This package recovers that ergonomics as an opt-in factory, with every path
|
|
8
|
+
* sourced from `@relayfile/adapter-core/writeback-paths` (the adapter-owned
|
|
9
|
+
* source of truth) instead of hardcoded — so paths never drift from the
|
|
10
|
+
* adapter that materializes the draft.
|
|
11
|
+
*
|
|
12
|
+
* import { linearClient } from '@relayfile/relay-helpers';
|
|
13
|
+
* const linear = linearClient(); // binds the mount root once
|
|
14
|
+
* const issue = await linear.getIssue(issueId);
|
|
15
|
+
* await linear.comment(issueId, ':rocket: done');
|
|
16
|
+
*
|
|
17
|
+
* Every provider in the catalog has a named client (`asanaClient`,
|
|
18
|
+
* `notionClient`, … through all 29), exposing its resources as
|
|
19
|
+
* `.{resource}.{path,write,read,list}`. `linear` / `github` / `slack` add
|
|
20
|
+
* named ergonomic methods on top. `relayClient(provider)` is the dynamic,
|
|
21
|
+
* string-keyed escape hatch when the provider isn't known at author time.
|
|
22
|
+
*/
|
|
23
|
+
export { relayClient, encodeSegment } from './generic.js';
|
|
24
|
+
export { providerClient } from './provider-client.js';
|
|
25
|
+
export { created } from './receipt.js';
|
|
26
|
+
// Ergonomic clients (resource-keyed access + named methods).
|
|
27
|
+
export { linearClient } from './linear.js';
|
|
28
|
+
export { githubClient } from './github.js';
|
|
29
|
+
export { slackClient } from './slack.js';
|
|
30
|
+
// Named resource-keyed clients for the remaining catalog providers
|
|
31
|
+
// (generated from the catalog — see scripts/generate-clients.mjs).
|
|
32
|
+
// `export *` so a newly-added provider needs only a re-`gen`, no edit here.
|
|
33
|
+
export * from './generated/clients.js';
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAsC,MAAM,cAAc,CAAC;AAC9F,OAAO,EAAE,cAAc,EAA4C,MAAM,sBAAsB,CAAC;AAChG,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,6DAA6D;AAC7D,OAAO,EAAE,YAAY,EAAiD,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,YAAY,EAAwC,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,WAAW,EAAoB,MAAM,YAAY,CAAC;AAE3D,mEAAmE;AACnE,mEAAmE;AACnE,4EAA4E;AAC5E,cAAc,wBAAwB,CAAC"}
|
package/dist/linear.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type IntegrationClientOptions } from '@relayfile/adapter-core/vfs-client';
|
|
2
|
+
import { type ProviderClient } from './provider-client.js';
|
|
3
|
+
export interface LinearCreateIssueArgs {
|
|
4
|
+
teamId: string;
|
|
5
|
+
title: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
assigneeId?: string;
|
|
8
|
+
labelIds?: string[];
|
|
9
|
+
projectId?: string;
|
|
10
|
+
stateId?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface LinearClient extends ProviderClient<'linear'> {
|
|
13
|
+
/** Comment on an issue. */
|
|
14
|
+
comment(issueId: string, body: string): Promise<{
|
|
15
|
+
id: string;
|
|
16
|
+
url: string;
|
|
17
|
+
}>;
|
|
18
|
+
/** Create an issue. */
|
|
19
|
+
createIssue(args: LinearCreateIssueArgs): Promise<{
|
|
20
|
+
id: string;
|
|
21
|
+
url: string;
|
|
22
|
+
}>;
|
|
23
|
+
/** Patch an existing issue. */
|
|
24
|
+
updateIssue(issueId: string, args: {
|
|
25
|
+
title?: string;
|
|
26
|
+
description?: string;
|
|
27
|
+
assigneeId?: string;
|
|
28
|
+
stateId?: string;
|
|
29
|
+
}): Promise<void>;
|
|
30
|
+
/** Read one issue by id. */
|
|
31
|
+
getIssue<T = Record<string, unknown>>(issueId: string): Promise<T>;
|
|
32
|
+
/** List issues. */
|
|
33
|
+
listIssues<T = Record<string, unknown>>(): Promise<T[]>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Ergonomic Linear client over the writeback-path catalog. Recovers the
|
|
37
|
+
* `ctx.linear.comment(...)` shape removed from the runtime, plus the uniform
|
|
38
|
+
* resource-keyed access (`.issues`, `.comments`) every provider client has.
|
|
39
|
+
*/
|
|
40
|
+
export declare function linearClient(opts?: IntegrationClientOptions): LinearClient;
|
|
41
|
+
//# sourceMappingURL=linear.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear.d.ts","sourceRoot":"","sources":["../src/linear.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3E,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,QAAQ,CAAC;IAC5D,2BAA2B;IAC3B,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7E,uBAAuB;IACvB,WAAW,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/E,+BAA+B;IAC/B,WAAW,CACT,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GACpF,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,4BAA4B;IAC5B,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACnE,mBAAmB;IACnB,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;CACzD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,wBAA6B,GAAG,YAAY,CAoB9E"}
|
package/dist/linear.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { readJsonFile, writeJsonFile } from '@relayfile/adapter-core/vfs-client';
|
|
2
|
+
import { encodeSegment } from './generic.js';
|
|
3
|
+
import { providerClient } from './provider-client.js';
|
|
4
|
+
import { created } from './receipt.js';
|
|
5
|
+
/**
|
|
6
|
+
* Ergonomic Linear client over the writeback-path catalog. Recovers the
|
|
7
|
+
* `ctx.linear.comment(...)` shape removed from the runtime, plus the uniform
|
|
8
|
+
* resource-keyed access (`.issues`, `.comments`) every provider client has.
|
|
9
|
+
*/
|
|
10
|
+
export function linearClient(opts = {}) {
|
|
11
|
+
const base = providerClient('linear', opts);
|
|
12
|
+
const issuePath = (issueId) => `${base.issues.path()}/${encodeSegment(issueId)}.json`;
|
|
13
|
+
return Object.assign(base, {
|
|
14
|
+
async comment(issueId, body) {
|
|
15
|
+
return created(await base.comments.write({ issueId }, { body }));
|
|
16
|
+
},
|
|
17
|
+
async createIssue(args) {
|
|
18
|
+
return created(await base.issues.write({}, args));
|
|
19
|
+
},
|
|
20
|
+
async updateIssue(issueId, args) {
|
|
21
|
+
await writeJsonFile(opts, 'linear', 'updateIssue', issuePath(issueId), args);
|
|
22
|
+
},
|
|
23
|
+
getIssue(issueId) {
|
|
24
|
+
return readJsonFile(opts, 'linear', 'getIssue', issuePath(issueId));
|
|
25
|
+
},
|
|
26
|
+
listIssues() {
|
|
27
|
+
return base.issues.list();
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=linear.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear.js","sourceRoot":"","sources":["../src/linear.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,aAAa,EAEd,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAuB,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AA4BvC;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,OAAiC,EAAE;IAC9D,MAAM,IAAI,GAAG,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC;IAC9F,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;QACzB,KAAK,CAAC,OAAO,CAAC,OAAe,EAAE,IAAY;YACzC,OAAO,OAAO,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACnE,CAAC;QACD,KAAK,CAAC,WAAW,CAAC,IAA2B;YAC3C,OAAO,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,IAA6B;YAC9D,MAAM,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/E,CAAC;QACD,QAAQ,CAA8B,OAAe;YACnD,OAAO,YAAY,CAAI,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QACzE,CAAC;QACD,UAAU;YACR,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAK,CAAC;QAC/B,CAAC;KACF,CAAiB,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { IntegrationClientOptions, WritebackResult } from '@relayfile/adapter-core/vfs-client';
|
|
2
|
+
import { type WritebackProvider, type WritebackResource } from '@relayfile/adapter-core/writeback-paths';
|
|
3
|
+
import { type RelayParams } from './generic.js';
|
|
4
|
+
/**
|
|
5
|
+
* One resource of a provider, bound to a client. Every path is resolved from
|
|
6
|
+
* the writeback-path catalog.
|
|
7
|
+
*/
|
|
8
|
+
export interface ResourceClient {
|
|
9
|
+
/** Resolve this resource's canonical mount path (no IO). */
|
|
10
|
+
path(params?: RelayParams): string;
|
|
11
|
+
/**
|
|
12
|
+
* Write `body`: a uniquely-named draft for a collection resource, or a direct
|
|
13
|
+
* write for an item (`.json`) resource. The writeback worker materializes the
|
|
14
|
+
* draft into the real provider call.
|
|
15
|
+
*/
|
|
16
|
+
write(params: RelayParams, body: unknown): Promise<WritebackResult>;
|
|
17
|
+
/** Read a single item resource (a `.json` path). */
|
|
18
|
+
read<T = unknown>(params?: RelayParams): Promise<T>;
|
|
19
|
+
/** List the records of a collection resource. */
|
|
20
|
+
list<T = unknown>(params?: RelayParams): Promise<T[]>;
|
|
21
|
+
}
|
|
22
|
+
/** A provider client: one {@link ResourceClient} per catalog resource. */
|
|
23
|
+
export type ProviderClient<P extends WritebackProvider> = {
|
|
24
|
+
readonly [R in WritebackResource<P> & string]: ResourceClient;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Build a resource-keyed client for any provider in the catalog. The mount
|
|
28
|
+
* root / writeback options are bound once and shared by every resource.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* const notion = providerClient('notion');
|
|
32
|
+
* await notion.pages.write({ databaseId }, { ... });
|
|
33
|
+
* await notion.comments.path({ databaseId, pageId });
|
|
34
|
+
*/
|
|
35
|
+
export declare function providerClient<P extends WritebackProvider>(provider: P, opts?: IntegrationClientOptions): ProviderClient<P>;
|
|
36
|
+
//# sourceMappingURL=provider-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-client.d.ts","sourceRoot":"","sources":["../src/provider-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AACpG,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACvB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAE7D;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IACnC;;;;OAIG;IACH,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACpE,oDAAoD;IACpD,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACpD,iDAAiD;IACjD,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;CACvD;AAED,0EAA0E;AAC1E,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,iBAAiB,IAAI;IACxD,QAAQ,EAAE,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,cAAc;CAC9D,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,iBAAiB,EACxD,QAAQ,EAAE,CAAC,EACX,IAAI,GAAE,wBAA6B,GAClC,cAAc,CAAC,CAAC,CAAC,CAqBnB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { WRITEBACK_PATH_CATALOG } from '@relayfile/adapter-core/writeback-paths';
|
|
2
|
+
import { relayClient } from './generic.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build a resource-keyed client for any provider in the catalog. The mount
|
|
5
|
+
* root / writeback options are bound once and shared by every resource.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const notion = providerClient('notion');
|
|
9
|
+
* await notion.pages.write({ databaseId }, { ... });
|
|
10
|
+
* await notion.comments.path({ databaseId, pageId });
|
|
11
|
+
*/
|
|
12
|
+
export function providerClient(provider, opts = {}) {
|
|
13
|
+
const relay = relayClient(provider, opts);
|
|
14
|
+
const out = {};
|
|
15
|
+
// Typed callers can't reach this, but a runtime/JS caller passing an unknown
|
|
16
|
+
// provider would otherwise hit a cryptic `Object.keys(undefined)` TypeError.
|
|
17
|
+
const resources = WRITEBACK_PATH_CATALOG[provider];
|
|
18
|
+
if (!resources) {
|
|
19
|
+
throw new Error(`Unknown writeback provider "${provider}". Known providers: ${Object.keys(WRITEBACK_PATH_CATALOG).join(", ")}`);
|
|
20
|
+
}
|
|
21
|
+
for (const resource of Object.keys(resources)) {
|
|
22
|
+
const r = resource;
|
|
23
|
+
out[resource] = {
|
|
24
|
+
path: (params) => relay.path(r, params),
|
|
25
|
+
write: (params, body) => relay.write(r, params, body),
|
|
26
|
+
read: (params) => relay.read(r, params),
|
|
27
|
+
list: (params) => relay.list(r, params)
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=provider-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-client.js","sourceRoot":"","sources":["../src/provider-client.ts"],"names":[],"mappings":"AACA,OAAO,EACL,sBAAsB,EAGvB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,WAAW,EAAoB,MAAM,cAAc,CAAC;AA0B7D;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,QAAW,EACX,OAAiC,EAAE;IAEnC,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAmC,EAAE,CAAC;IAC/C,6EAA6E;IAC7E,6EAA6E;IAC7E,MAAM,SAAS,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IACnD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,+BAA+B,QAAQ,uBAAuB,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/G,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9C,MAAM,CAAC,GAAG,QAAyC,CAAC;QACpD,GAAG,CAAC,QAAQ,CAAC,GAAG;YACd,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC;YACvC,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC;YACrD,IAAI,EAAE,CAAI,MAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAI,CAAC,EAAE,MAAM,CAAC;YAC3D,IAAI,EAAE,CAAI,MAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAI,CAAC,EAAE,MAAM,CAAC;SAC5D,CAAC;IACJ,CAAC;IACD,OAAO,GAAwB,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { WritebackResult } from '@relayfile/adapter-core/vfs-client';
|
|
2
|
+
/**
|
|
3
|
+
* Normalize the writeback receipt into the `{ id, url }` shape the old typed
|
|
4
|
+
* clients returned. Falls back to the draft path when the worker hasn't
|
|
5
|
+
* written a receipt yet (fire-and-forget / timeout).
|
|
6
|
+
*/
|
|
7
|
+
export declare function created(result: WritebackResult): {
|
|
8
|
+
id: string;
|
|
9
|
+
url: string;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=receipt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipt.d.ts","sourceRoot":"","sources":["../src/receipt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAK5E"}
|
package/dist/receipt.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize the writeback receipt into the `{ id, url }` shape the old typed
|
|
3
|
+
* clients returned. Falls back to the draft path when the worker hasn't
|
|
4
|
+
* written a receipt yet (fire-and-forget / timeout).
|
|
5
|
+
*/
|
|
6
|
+
export function created(result) {
|
|
7
|
+
return {
|
|
8
|
+
id: result.receipt?.created ?? result.receipt?.id ?? result.path,
|
|
9
|
+
url: result.receipt?.url ?? result.path
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=receipt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipt.js","sourceRoot":"","sources":["../src/receipt.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,MAAuB;IAC7C,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,MAAM,CAAC,IAAI;QAChE,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,MAAM,CAAC,IAAI;KACxC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-helpers.test.d.ts","sourceRoot":"","sources":["../src/relay-helpers.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { mkdtemp, mkdir, readFile, readdir, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import test from 'node:test';
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
7
|
+
import { WRITEBACK_PATH_CATALOG } from '@relayfile/adapter-core/writeback-paths';
|
|
8
|
+
import * as helpers from './index.js';
|
|
9
|
+
import { githubClient, linearClient, notionClient, providerClient, relayClient, slackClient } from './index.js';
|
|
10
|
+
const clientExportName = (provider) => `${provider.replace(/-([a-z])/g, (_m, c) => c.toUpperCase())}Client`;
|
|
11
|
+
/** Fire-and-forget client bound to a throwaway mount; no writeback worker runs. */
|
|
12
|
+
async function mount() {
|
|
13
|
+
const root = await mkdtemp(path.join(tmpdir(), 'relay-helpers-'));
|
|
14
|
+
return { root, opts: { relayfileMountRoot: root, writebackTimeoutMs: 0 } };
|
|
15
|
+
}
|
|
16
|
+
async function onlyJsonIn(dir) {
|
|
17
|
+
const entries = (await readdir(dir)).filter((entry) => entry.endsWith('.json'));
|
|
18
|
+
assert.equal(entries.length, 1, `expected one draft in ${dir}, saw ${entries.join(', ') || 'none'}`);
|
|
19
|
+
return { name: entries[0], body: JSON.parse(await readFile(path.join(dir, entries[0]), 'utf8')) };
|
|
20
|
+
}
|
|
21
|
+
test('relayClient.path resolves catalog paths and write drops a collection draft', async () => {
|
|
22
|
+
const { root, opts } = await mount();
|
|
23
|
+
const linear = relayClient('linear', opts);
|
|
24
|
+
assert.equal(linear.path('comments', { issueId: 'ISS-1' }), '/linear/issues/ISS-1/comments');
|
|
25
|
+
await linear.write('comments', { issueId: 'ISS-1' }, { body: 'hi' });
|
|
26
|
+
const draft = await onlyJsonIn(path.join(root, 'linear/issues/ISS-1/comments'));
|
|
27
|
+
assert.deepEqual(draft.body, { body: 'hi' });
|
|
28
|
+
});
|
|
29
|
+
test('relayClient.write writes item (.json) resources to the exact path', async () => {
|
|
30
|
+
const { root, opts } = await mount();
|
|
31
|
+
const gh = relayClient('github', opts);
|
|
32
|
+
// `merge` resolves to `…/merge.json` — an item path, written directly (no draft).
|
|
33
|
+
await gh.write('merge', { owner: 'o', repo: 'r', pullNumber: 7 }, { merge_method: 'squash' });
|
|
34
|
+
const body = JSON.parse(await readFile(path.join(root, 'github/repos/o/r/pulls/7/merge.json'), 'utf8'));
|
|
35
|
+
assert.deepEqual(body, { merge_method: 'squash' });
|
|
36
|
+
});
|
|
37
|
+
test('relayClient.read / list operate over the catalog paths', async () => {
|
|
38
|
+
const { root, opts } = await mount();
|
|
39
|
+
await mkdir(path.join(root, 'linear/issues'), { recursive: true });
|
|
40
|
+
await writeFile(path.join(root, 'linear/issues/ISS-9.json'), JSON.stringify({ id: 'ISS-9', title: 't' }));
|
|
41
|
+
const linear = relayClient('linear', opts);
|
|
42
|
+
const listed = await linear.list('issues');
|
|
43
|
+
assert.deepEqual(listed.map((i) => i.id), ['ISS-9']);
|
|
44
|
+
});
|
|
45
|
+
test('linearClient recovers comment / createIssue / getIssue ergonomics', async () => {
|
|
46
|
+
const { root, opts } = await mount();
|
|
47
|
+
await mkdir(path.join(root, 'linear/issues'), { recursive: true });
|
|
48
|
+
await writeFile(path.join(root, 'linear/issues/ISS-1.json'), JSON.stringify({ id: 'ISS-1', title: 'Fix' }));
|
|
49
|
+
const linear = linearClient(opts);
|
|
50
|
+
const issue = await linear.getIssue('ISS-1');
|
|
51
|
+
assert.equal(issue.title, 'Fix');
|
|
52
|
+
await linear.comment('ISS-1', ':rocket: done');
|
|
53
|
+
const comment = await onlyJsonIn(path.join(root, 'linear/issues/ISS-1/comments'));
|
|
54
|
+
assert.deepEqual(comment.body, { body: ':rocket: done' });
|
|
55
|
+
// Fresh mount so the create draft is the only file in /linear/issues.
|
|
56
|
+
const fresh = await mount();
|
|
57
|
+
await linearClient(fresh.opts).createIssue({ teamId: 'T', title: 'New' });
|
|
58
|
+
const created = await onlyJsonIn(path.join(fresh.root, 'linear/issues'));
|
|
59
|
+
assert.deepEqual(created.body, { teamId: 'T', title: 'New' });
|
|
60
|
+
});
|
|
61
|
+
test('githubClient.comment and slackClient.post target the canonical paths', async () => {
|
|
62
|
+
const { root, opts } = await mount();
|
|
63
|
+
await githubClient(opts).comment({ owner: 'AgentWorkforce', repo: 'cloud', number: 1643 }, 'hello');
|
|
64
|
+
const ghComment = await onlyJsonIn(path.join(root, 'github/repos/AgentWorkforce/cloud/issues/1643/comments'));
|
|
65
|
+
assert.deepEqual(ghComment.body, { body: 'hello' });
|
|
66
|
+
await slackClient(opts).post('C123', 'shipped');
|
|
67
|
+
const msg = await onlyJsonIn(path.join(root, 'slack/channels/C123/messages'));
|
|
68
|
+
assert.deepEqual(msg.body, { text: 'shipped' });
|
|
69
|
+
});
|
|
70
|
+
test('every catalog provider has a named client export', () => {
|
|
71
|
+
const providers = Object.keys(WRITEBACK_PATH_CATALOG);
|
|
72
|
+
assert.ok(providers.length >= 29, `expected >=29 providers, saw ${providers.length}`);
|
|
73
|
+
const missing = providers.filter((provider) => typeof helpers[clientExportName(provider)] !== 'function');
|
|
74
|
+
assert.deepEqual(missing, [], `providers without a named client export: ${missing.join(', ')}`);
|
|
75
|
+
});
|
|
76
|
+
test('src/generated/clients.ts is in sync with the catalog', async () => {
|
|
77
|
+
// dist/<this>.test.js → package root is one level up.
|
|
78
|
+
const pkgRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
79
|
+
const { renderClients } = await import(pathToFileURL(path.join(pkgRoot, 'scripts/generate-clients.mjs')).href);
|
|
80
|
+
const committed = await readFile(path.join(pkgRoot, 'src/generated/clients.ts'), 'utf8');
|
|
81
|
+
assert.equal(committed, renderClients(), 'generated clients are stale — run `npm run gen -w @relayfile/relay-helpers`');
|
|
82
|
+
});
|
|
83
|
+
test('a named resource-keyed client resolves and writes catalog paths', async () => {
|
|
84
|
+
const { root, opts } = await mount();
|
|
85
|
+
const notion = notionClient(opts);
|
|
86
|
+
assert.equal(notion.pages.path({ databaseId: 'db1' }), '/notion/databases/db1/pages');
|
|
87
|
+
await notion.pages.write({ databaseId: 'db1' }, { title: 'P' });
|
|
88
|
+
const draft = await onlyJsonIn(path.join(root, 'notion/databases/db1/pages'));
|
|
89
|
+
assert.deepEqual(draft.body, { title: 'P' });
|
|
90
|
+
});
|
|
91
|
+
test('read() rejects (not throws synchronously) on a collection resource', async () => {
|
|
92
|
+
const { opts } = await mount();
|
|
93
|
+
// `comments` is a collection path, so read is invalid — but calling it must
|
|
94
|
+
// not throw synchronously; the returned promise rejects so `.catch()` works.
|
|
95
|
+
const promise = relayClient('linear', opts).read('comments', { issueId: 'ISS-1' });
|
|
96
|
+
await assert.rejects(promise, /resolves to collection/);
|
|
97
|
+
});
|
|
98
|
+
test('providerClient throws a clear error for an unknown provider', () => {
|
|
99
|
+
assert.throws(() => providerClient('not-a-provider'), /Unknown writeback provider "not-a-provider"/);
|
|
100
|
+
});
|
|
101
|
+
test('relayClient (dynamic) still resolves paths for every provider', () => {
|
|
102
|
+
for (const provider of Object.keys(WRITEBACK_PATH_CATALOG)) {
|
|
103
|
+
const client = relayClient(provider);
|
|
104
|
+
const [resource, variants] = Object.entries(WRITEBACK_PATH_CATALOG[provider])[0];
|
|
105
|
+
const params = Object.fromEntries(variants[0].params.map((name) => [name, 'x']));
|
|
106
|
+
assert.ok(client.path(resource, params).startsWith(`/${provider}`));
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
//# sourceMappingURL=relay-helpers.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-helpers.test.js","sourceRoot":"","sources":["../src/relay-helpers.test.ts"],"names":[],"mappings":"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"}
|
package/dist/slack.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { IntegrationClientOptions } from '@relayfile/adapter-core/vfs-client';
|
|
2
|
+
import { type ProviderClient } from './provider-client.js';
|
|
3
|
+
export interface SlackClient extends ProviderClient<'slack'> {
|
|
4
|
+
/** Post a message to a channel. */
|
|
5
|
+
post(channel: string, text: string): Promise<{
|
|
6
|
+
channel: string;
|
|
7
|
+
ts: string;
|
|
8
|
+
}>;
|
|
9
|
+
/** Direct-message a user. */
|
|
10
|
+
dm(user: string, text: string): Promise<{
|
|
11
|
+
user: string;
|
|
12
|
+
ts: string;
|
|
13
|
+
}>;
|
|
14
|
+
/** Reply in a thread. */
|
|
15
|
+
reply(channel: string, threadTs: string, text: string): Promise<{
|
|
16
|
+
channel: string;
|
|
17
|
+
ts: string;
|
|
18
|
+
}>;
|
|
19
|
+
/** React to a message. */
|
|
20
|
+
react(channel: string, messageTs: string, emoji: string): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Ergonomic Slack client over the writeback-path catalog, plus the uniform
|
|
24
|
+
* resource-keyed access (`.messages`, `.["direct-messages"]`, `.replies`, `.reactions`).
|
|
25
|
+
*/
|
|
26
|
+
export declare function slackClient(opts?: IntegrationClientOptions): SlackClient;
|
|
27
|
+
//# sourceMappingURL=slack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../src/slack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAO3E,MAAM,WAAW,WAAY,SAAQ,cAAc,CAAC,OAAO,CAAC;IAC1D,mCAAmC;IACnC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9E,6BAA6B;IAC7B,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtE,yBAAyB;IACzB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjG,0BAA0B;IAC1B,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,GAAE,wBAA6B,GAAG,WAAW,CAmB5E"}
|
package/dist/slack.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { providerClient } from './provider-client.js';
|
|
2
|
+
/** Slack message timestamps contain `.`; the mount path encodes it as `_`. */
|
|
3
|
+
function tsParam(ts) {
|
|
4
|
+
return ts.replace(/\./g, '_');
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Ergonomic Slack client over the writeback-path catalog, plus the uniform
|
|
8
|
+
* resource-keyed access (`.messages`, `.["direct-messages"]`, `.replies`, `.reactions`).
|
|
9
|
+
*/
|
|
10
|
+
export function slackClient(opts = {}) {
|
|
11
|
+
const base = providerClient('slack', opts);
|
|
12
|
+
return Object.assign(base, {
|
|
13
|
+
async post(channel, text) {
|
|
14
|
+
const result = await base.messages.write({ channelId: channel }, { text });
|
|
15
|
+
return { channel, ts: result.receipt?.created ?? result.receipt?.id ?? '' };
|
|
16
|
+
},
|
|
17
|
+
async dm(user, text) {
|
|
18
|
+
const result = await base['direct-messages'].write({ userId: user }, { text });
|
|
19
|
+
return { user, ts: result.receipt?.created ?? result.receipt?.id ?? '' };
|
|
20
|
+
},
|
|
21
|
+
async reply(channel, threadTs, text) {
|
|
22
|
+
const result = await base.replies.write({ channelId: channel, messageTs: tsParam(threadTs) }, { text });
|
|
23
|
+
return { channel, ts: result.receipt?.created ?? result.receipt?.id ?? '' };
|
|
24
|
+
},
|
|
25
|
+
async react(channel, messageTs, emoji) {
|
|
26
|
+
await base.reactions.write({ channelId: channel, messageTs: tsParam(messageTs) }, { emoji });
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=slack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../src/slack.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAuB,MAAM,sBAAsB,CAAC;AAE3E,8EAA8E;AAC9E,SAAS,OAAO,CAAC,EAAU;IACzB,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAChC,CAAC;AAaD;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAiC,EAAE;IAC7D,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC3C,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;QACzB,KAAK,CAAC,IAAI,CAAC,OAAe,EAAE,IAAY;YACtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3E,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC;QAC9E,CAAC;QACD,KAAK,CAAC,EAAE,CAAC,IAAY,EAAE,IAAY;YACjC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/E,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC;QAC3E,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,OAAe,EAAE,QAAgB,EAAE,IAAY;YACzD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YACxG,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC;QAC9E,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,OAAe,EAAE,SAAiB,EAAE,KAAa;YAC3D,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/F,CAAC;KACF,CAAgB,CAAC;AACpB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@relayfile/relay-helpers",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Ergonomic, catalog-backed provider clients for Relayfile integration handlers",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"gen": "node scripts/generate-clients.mjs",
|
|
23
|
+
"build": "tsc -p tsconfig.json",
|
|
24
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
25
|
+
"test": "tsc -p tsconfig.json && node --test \"dist/**/*.test.js\"",
|
|
26
|
+
"prepublishOnly": "npm run build"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@relayfile/adapter-core": "^0.3.27"
|
|
30
|
+
}
|
|
31
|
+
}
|