@shuffl/sdk 0.6.0 → 0.6.2
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 +18 -2
- package/dist/index.d.ts +6 -1
- package/dist/index.js +21 -6
- package/dist/version.d.ts +1 -0
- package/dist/version.js +3 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -32,7 +32,17 @@ const preview = await shuffl.programs.preview({
|
|
|
32
32
|
|
|
33
33
|
`users` means people in the team directory, including people who have no web login. IDs are Shuffl person IDs, not Slack IDs or authentication account IDs.
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
A team key never gains company scope; company settings have their own key and live under `shuffl.company`, below. See the [permission reference](https://shuffl-rebuild.vercel.app/docs/api-permissions) for every method. Input and output types come directly from the portable public oRPC contract.
|
|
36
|
+
|
|
37
|
+
## What the client covers
|
|
38
|
+
|
|
39
|
+
- People: `users`, `profiles`, `identities`, `invitations`, `access`, `manager`, `timeOff` and `sync` (People Sync).
|
|
40
|
+
- Groups: `groups` (lists, departments, synced groups, automations and their runs), `units` and `communities`.
|
|
41
|
+
- Programs: `programs` and `runs` (Connections), `mentorship`, `network` (the org chart and introductions) and `playbooks` (onboarding, buddies, 30/60/90 plans and leaving).
|
|
42
|
+
- Culture: `celebrations`, `pulse`, `praise`, `badges`, `reminders`, `home`, `getStarted` and `digest`.
|
|
43
|
+
- Knowledge and HR: `knowledge` (pages, sources, templates, read-and-confirm and the handbook), `hr` (HR requests), `support` and `assistant`.
|
|
44
|
+
- Workspace: `teams`, `team`, `channels`, `integrations`, `notifications`, `reports`, `exports` and `webhooks`.
|
|
45
|
+
- Keys and receipts: `credentials`, `permissions`, `commands` and `operations`.
|
|
36
46
|
|
|
37
47
|
Program creation requires a stable `requestKey`. Repeating the same creation request returns the existing program; using that key with different settings returns `CONFLICT`. Programs start paused unless `draft: false` is explicitly supplied. Updates require `expectedRevision`. Run requests require a preview and request key and return a durable run ID; poll `runs.get` for status. The application scheduler owns execution and delivery.
|
|
38
48
|
|
|
@@ -42,11 +52,13 @@ Dates in the public API are ISO strings. Directory lists use an opaque cursor an
|
|
|
42
52
|
new Shuffl({ apiKey: async () => credentialStore.read() });
|
|
43
53
|
```
|
|
44
54
|
|
|
55
|
+
Every request carries an `x-shuffl-client` header naming the SDK release (`shuffl-sdk/0.6.1`; the CLI adds `shuffl-cli/0.6.1`), so Shuffl can count requests by release. Pass `client: 'billing-sync/1.2.0'` to put your app's name in front; Shuffl never stores that part.
|
|
56
|
+
|
|
45
57
|
Use `ORPCError.code` for errors (`UNAUTHORIZED`, `FORBIDDEN`, `BAD_REQUEST`, `NOT_FOUND`, `CONFLICT`, and others). Calls accept oRPC's second options argument, including an abort signal. HTTPS is required except on loopback; redirects are refused to avoid forwarding credentials to another origin. The public API currently allows same-origin browser calls and server/CLI clients; cross-origin browser CORS is not enabled.
|
|
46
58
|
|
|
47
59
|
## Webhooks
|
|
48
60
|
|
|
49
|
-
Shuffl can call your HTTPS endpoint when something happens in a workspace
|
|
61
|
+
Shuffl can call your HTTPS endpoint when something happens in a workspace. Add an endpoint in Settings → Webhooks or with `webhooks.create`, keep the `whsec_…` signing secret it returns, and check every delivery against it before you trust it. Pass the raw body, before any JSON parsing:
|
|
50
62
|
|
|
51
63
|
```ts
|
|
52
64
|
import { verifyWebhook, WebhookVerificationError } from '@shuffl/sdk';
|
|
@@ -103,3 +115,7 @@ await shuffl.company.members.remove({ userId: page.items[0]!.userId });
|
|
|
103
115
|
`shuffl.company.current()` returns the key's company and grants. Every other method needs its grant: `company.details`, `company.workspaces.list`, `company.members.list`, `company.emailDomains.list`, `company.slack.list`, `company.rename`, `company.workspaces.setDefault` and `company.members.remove`. `members.list` pages with `limit` and `cursor` like `users.list`. Company writes run once when called and take no `requestKey`. A company key can't call the workspace methods, and a workspace key can't call `shuffl.company`; the SDK refuses the wrong kind with `UNAUTHORIZED` before sending a request. See [company keys](https://shuffl-rebuild.vercel.app/docs/api-permissions#company-keys).
|
|
104
116
|
|
|
105
117
|
Full guide: [Use the SDK and HTTP API](https://shuffl-rebuild.vercel.app/docs/sdk).
|
|
118
|
+
|
|
119
|
+
## License
|
|
120
|
+
|
|
121
|
+
MIT © Shuffl LLC. See [LICENSE](./LICENSE).
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export { ORPCError } from '@orpc/client';
|
|
|
5
5
|
export type { CompanyPermission, Permission, PermissionDefinition, Scope, } from '@shuffl/api-contracts';
|
|
6
6
|
export { isWebhookEventType, signWebhook, verifyWebhook, type WebhookActor, type WebhookEvent, type WebhookEventData, type WebhookEventGroup, type WebhookEventType, WebhookVerificationError, webhookApiVersion, webhookEventCatalog, webhookEventGroups, webhookEventTypes, } from '@shuffl/api-contracts/webhooks';
|
|
7
7
|
export type ShufflClient = ContractRouterClient<ShufflContract>;
|
|
8
|
-
/** The company API
|
|
8
|
+
/** The company API, for a company key (shuffl_company_). */
|
|
9
9
|
export type ShufflCompanyClient = ContractRouterClient<ShufflCompanyContract>;
|
|
10
10
|
export interface ShufflOptions {
|
|
11
11
|
/**
|
|
@@ -15,6 +15,11 @@ export interface ShufflOptions {
|
|
|
15
15
|
apiKey: string | (() => string | Promise<string>);
|
|
16
16
|
/** Shuffl application origin, without /api/v1. Defaults to production. */
|
|
17
17
|
baseUrl?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Your app's name and version, such as "hris-sync/2.1". Sent ahead of the
|
|
20
|
+
* SDK's own in the x-shuffl-client header; Shuffl doesn't store it.
|
|
21
|
+
*/
|
|
22
|
+
client?: string;
|
|
18
23
|
fetch?: typeof globalThis.fetch;
|
|
19
24
|
}
|
|
20
25
|
export interface Shuffl extends ShufflClient {
|
package/dist/index.js
CHANGED
|
@@ -4,8 +4,20 @@ import { isContractProcedure } from '@orpc/contract';
|
|
|
4
4
|
import { contract } from '@shuffl/api-contracts';
|
|
5
5
|
import { companyContract, } from '@shuffl/api-contracts/company';
|
|
6
6
|
export { ORPCError } from '@orpc/client';
|
|
7
|
-
//
|
|
7
|
+
// Check and type the webhooks Shuffl sends.
|
|
8
8
|
export { isWebhookEventType, signWebhook, verifyWebhook, WebhookVerificationError, webhookApiVersion, webhookEventCatalog, webhookEventGroups, webhookEventTypes, } from '@shuffl/api-contracts/webhooks';
|
|
9
|
+
import { sdkVersion } from './version.js';
|
|
10
|
+
// Which SDK release (and, for the CLI, which CLI release) made a request,
|
|
11
|
+
// for Shuffl's own usage counts. One header line, no spaces inside a part.
|
|
12
|
+
function clientHeader(client) {
|
|
13
|
+
const own = `shuffl-sdk/${sdkVersion}`;
|
|
14
|
+
const name = client?.trim();
|
|
15
|
+
if (!name)
|
|
16
|
+
return own;
|
|
17
|
+
if (!/^[\x21-\x7e]+(?: [\x21-\x7e]+)*$/.test(name) || name.length > 128)
|
|
18
|
+
throw new Error('client is a short name/version, such as billing-sync/1.2.0.');
|
|
19
|
+
return `${name} ${own}`;
|
|
20
|
+
}
|
|
9
21
|
const defaultBaseUrl = 'https://shuffl-rebuild.vercel.app';
|
|
10
22
|
const companyKeyPrefix = 'shuffl_company_';
|
|
11
23
|
function origin(baseUrl) {
|
|
@@ -31,7 +43,7 @@ const bearer = async (apiKey, kind) => {
|
|
|
31
43
|
});
|
|
32
44
|
return `Bearer ${key}`;
|
|
33
45
|
};
|
|
34
|
-
function workspaceClient(base, options) {
|
|
46
|
+
function workspaceClient(base, options, client) {
|
|
35
47
|
return createORPCClient(new RPCLink({
|
|
36
48
|
// Writes are not automatically retried. Callers own stable request keys.
|
|
37
49
|
fetch: async (request, init) => (options.fetch ?? globalThis.fetch)(request, {
|
|
@@ -40,6 +52,7 @@ function workspaceClient(base, options) {
|
|
|
40
52
|
}),
|
|
41
53
|
headers: async () => ({
|
|
42
54
|
authorization: await bearer(options.apiKey, 'workspace'),
|
|
55
|
+
'x-shuffl-client': client,
|
|
43
56
|
}),
|
|
44
57
|
url: new URL('/api/v1/rpc', base).toString(),
|
|
45
58
|
}));
|
|
@@ -53,9 +66,9 @@ const statusCodes = {
|
|
|
53
66
|
409: 'CONFLICT',
|
|
54
67
|
429: 'TOO_MANY_REQUESTS',
|
|
55
68
|
};
|
|
56
|
-
// The company API
|
|
69
|
+
// The company API is REST under /api/v1/company, so its client is
|
|
57
70
|
// built from the contract's routes rather than the RPC link.
|
|
58
|
-
function companyClient(base, options) {
|
|
71
|
+
function companyClient(base, options, client) {
|
|
59
72
|
const procedure = ({ method, path }) => async (input, call) => {
|
|
60
73
|
const url = new URL(`/api/v1${path}`, base);
|
|
61
74
|
const read = method === 'GET';
|
|
@@ -68,6 +81,7 @@ function companyClient(base, options) {
|
|
|
68
81
|
headers: {
|
|
69
82
|
accept: 'application/json',
|
|
70
83
|
authorization: await bearer(options.apiKey, 'company'),
|
|
84
|
+
'x-shuffl-client': client,
|
|
71
85
|
...(read ? {} : { 'content-type': 'application/json' }),
|
|
72
86
|
},
|
|
73
87
|
method,
|
|
@@ -117,12 +131,13 @@ export class Shuffl {
|
|
|
117
131
|
company;
|
|
118
132
|
constructor(options) {
|
|
119
133
|
const base = origin(options.baseUrl ?? defaultBaseUrl);
|
|
120
|
-
const
|
|
134
|
+
const client = clientHeader(options.client);
|
|
135
|
+
const workspace = workspaceClient(base, options, client);
|
|
121
136
|
for (const key of Object.keys(contract))
|
|
122
137
|
Object.defineProperty(this, key, {
|
|
123
138
|
enumerable: true,
|
|
124
139
|
value: workspace[key],
|
|
125
140
|
});
|
|
126
|
-
this.company = companyClient(base, options);
|
|
141
|
+
this.company = companyClient(base, options, client);
|
|
127
142
|
}
|
|
128
143
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const sdkVersion = "0.6.2";
|
package/dist/version.js
ADDED
package/package.json
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"dependencies": {
|
|
3
3
|
"@orpc/client": "1.15.3",
|
|
4
4
|
"@orpc/contract": "1.15.3",
|
|
5
|
-
"@shuffl/api-contracts": "0.6.
|
|
5
|
+
"@shuffl/api-contracts": "0.6.2"
|
|
6
6
|
},
|
|
7
|
-
"description": "TypeScript client for the Shuffl API: people,
|
|
7
|
+
"description": "TypeScript client for the Shuffl API: people, groups, knowledge, playbooks, programs and management commands.",
|
|
8
8
|
"engines": {
|
|
9
9
|
"node": ">=22"
|
|
10
10
|
},
|
|
@@ -34,5 +34,5 @@
|
|
|
34
34
|
"sideEffects": false,
|
|
35
35
|
"type": "module",
|
|
36
36
|
"types": "./dist/index.d.ts",
|
|
37
|
-
"version": "0.6.
|
|
37
|
+
"version": "0.6.2"
|
|
38
38
|
}
|