seam 1.232.0 → 1.233.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 +267 -4
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -53,12 +53,19 @@ Instead, it builds on a core set of Seam modules:
|
|
|
53
53
|
- [Advanced Usage](#advanced-usage)
|
|
54
54
|
- [Additional Options](#additional-options)
|
|
55
55
|
- [Setting the endpoint](#setting-the-endpoint)
|
|
56
|
+
- [Setting the request timeout](#setting-the-request-timeout)
|
|
56
57
|
- [Configuring the Axios Client](#configuring-the-axios-client)
|
|
57
58
|
- [Using the Axios Client](#using-the-axios-client)
|
|
58
59
|
- [Overriding the Client](#overriding-the-client)
|
|
59
60
|
- [Alternative endpoint path interface](#alternative-endpoint-path-interface)
|
|
60
61
|
- [Inspecting the Request](#inspecting-the-request)
|
|
62
|
+
- [Serializing URL search params](#serializing-url-search-params)
|
|
61
63
|
- [Command Line Interface](#command-line-interface)
|
|
64
|
+
- [Output](#output)
|
|
65
|
+
- [Pagination](#pagination-1)
|
|
66
|
+
- [JSON](#json)
|
|
67
|
+
- [Selecting an endpoint and a workspace](#selecting-an-endpoint-and-a-workspace)
|
|
68
|
+
- [Environment variables](#environment-variables)
|
|
62
69
|
- [Receiving Webhooks](#receiving-webhooks)
|
|
63
70
|
- [Development and Testing](#development-and-testing)
|
|
64
71
|
- [Quickstart](#quickstart)
|
|
@@ -468,6 +475,7 @@ the constructor takes some advanced options that affect behavior.
|
|
|
468
475
|
const seam = new Seam({
|
|
469
476
|
apiKey: 'your-api-key',
|
|
470
477
|
endpoint: 'https://example.com',
|
|
478
|
+
timeout: 30000,
|
|
471
479
|
axiosOptions: {},
|
|
472
480
|
axiosRetryOptions: {},
|
|
473
481
|
})
|
|
@@ -479,6 +487,7 @@ these options may be passed in as the last argument.
|
|
|
479
487
|
```ts
|
|
480
488
|
const seam = Seam.fromApiKey('some-api-key', {
|
|
481
489
|
endpoint: 'https://example.com',
|
|
490
|
+
timeout: 30000,
|
|
482
491
|
axiosOptions: {},
|
|
483
492
|
axiosRetryOptions: {},
|
|
484
493
|
})
|
|
@@ -492,12 +501,39 @@ This option corresponds to the Axios `baseURL` setting.
|
|
|
492
501
|
|
|
493
502
|
Either pass the `endpoint` option, or set the `SEAM_ENDPOINT` environment variable.
|
|
494
503
|
|
|
504
|
+
#### Setting the request timeout
|
|
505
|
+
|
|
506
|
+
Requests time out after 30 seconds by default.
|
|
507
|
+
Pass the `timeout` option, in milliseconds, to override this:
|
|
508
|
+
|
|
509
|
+
```ts
|
|
510
|
+
const seam = new Seam({
|
|
511
|
+
apiKey: 'your-api-key',
|
|
512
|
+
timeout: 60000,
|
|
513
|
+
})
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
Set `timeout` to `0` to disable the timeout entirely.
|
|
517
|
+
A request that times out rejects with an Axios `ETIMEDOUT` error.
|
|
518
|
+
Timed-out idempotent requests are retried according to the retry options, with
|
|
519
|
+
the timeout reset for each attempt. Non-idempotent requests are not retried by
|
|
520
|
+
default.
|
|
521
|
+
|
|
495
522
|
#### Configuring the Axios Client
|
|
496
523
|
|
|
497
524
|
The Axios client and retry behavior may be configured with custom initiation options
|
|
498
525
|
via [`axiosOptions`][axiosOptions] and [`axiosRetryOptions`][axiosRetryOptions].
|
|
499
526
|
Options are deep merged with the default options.
|
|
500
527
|
|
|
528
|
+
By default, the SDK makes up to three attempts: the initial request and two
|
|
529
|
+
retries. Retries are limited to `GET`, `HEAD`, `OPTIONS`, `PUT`, and `DELETE`
|
|
530
|
+
requests that fail because of a transport error, timeout, HTTP 429 response, or
|
|
531
|
+
HTTP 5xx response. `POST` and `PATCH` requests are not retried.
|
|
532
|
+
|
|
533
|
+
Retries use exponential backoff with jitter: approximately 200–240 ms before
|
|
534
|
+
the first retry and 400–480 ms before the second. A longer `Retry-After` header
|
|
535
|
+
is honored. The request timeout is reset for each attempt.
|
|
536
|
+
|
|
501
537
|
[axiosOptions]: https://axios-http.com/docs/config_defaults
|
|
502
538
|
[axiosRetryOptions]: https://github.com/softonic/axios-retry
|
|
503
539
|
|
|
@@ -550,11 +586,69 @@ console.log(`${request.method} ${request.url}`, JSON.stringify(request.body))
|
|
|
550
586
|
const devices = await request.execute()
|
|
551
587
|
```
|
|
552
588
|
|
|
589
|
+
#### Serializing URL search params
|
|
590
|
+
|
|
591
|
+
The Seam API parses URL search params as complex types.
|
|
592
|
+
If you call it with your own HTTP client, use `serializeUrlSearchParams`:
|
|
593
|
+
|
|
594
|
+
```ts
|
|
595
|
+
import axios from 'axios'
|
|
596
|
+
import { serializeUrlSearchParams } from 'seam'
|
|
597
|
+
|
|
598
|
+
await axios.get('https://connect.getseam.com/devices/list', {
|
|
599
|
+
params: { device_ids: ['device1', 'device2'] },
|
|
600
|
+
paramsSerializer: serializeUrlSearchParams,
|
|
601
|
+
headers: { Authorization: 'Bearer your-api-key' },
|
|
602
|
+
})
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
or `updateUrlSearchParams`:
|
|
606
|
+
|
|
607
|
+
```ts
|
|
608
|
+
import { updateUrlSearchParams } from 'seam'
|
|
609
|
+
|
|
610
|
+
const searchParams = new URLSearchParams()
|
|
611
|
+
updateUrlSearchParams(searchParams, { device_ids: ['device1', 'device2'] })
|
|
612
|
+
|
|
613
|
+
Array.from(searchParams)
|
|
614
|
+
// => [['device_ids', 'device1'], ['device_ids', 'device2'], ['_strict', 'true']]
|
|
615
|
+
|
|
616
|
+
searchParams.toString()
|
|
617
|
+
// => 'device_ids=device1&device_ids=device2&_strict=true'
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
The helpers wrap the [reference implementation].
|
|
621
|
+
The serialization defines the name and string value of each search param.
|
|
622
|
+
[`URLSearchParams`][URLSearchParams] holds those pairs and renders the query string:
|
|
623
|
+
The `_strict=true` parameter is added to any non-empty query so the Seam API uses
|
|
624
|
+
strict, schema-aware parsing.
|
|
625
|
+
A query with no serializable params remains empty.
|
|
626
|
+
|
|
627
|
+
A param set to `undefined` is omitted, while a param set to `null` is serialized
|
|
628
|
+
to an empty value, which the Seam API reads as null.
|
|
629
|
+
A param that cannot be represented raises an `UnserializableParamError`.
|
|
630
|
+
The Seam API parses these params with the corresponding [parser].
|
|
631
|
+
|
|
632
|
+
[URLSearchParams]: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
|
|
633
|
+
[reference implementation]: https://github.com/seamapi/url-search-params-serializer
|
|
634
|
+
[parser]: https://github.com/seamapi/url-search-params-parser
|
|
635
|
+
|
|
553
636
|
### Command Line Interface
|
|
554
637
|
|
|
555
|
-
Every `seam` command
|
|
556
|
-
|
|
557
|
-
|
|
638
|
+
Every `seam` command makes its request as soon as every required property is
|
|
639
|
+
given. When something is missing, the CLI prompts you for it with helpful
|
|
640
|
+
suggestions.
|
|
641
|
+
|
|
642
|
+
Pass `--interactive` (or `-i`) to always be prompted to review and edit
|
|
643
|
+
properties before the request is made. The prompt is prefilled with whatever
|
|
644
|
+
you passed as arguments or piped in as JSON, and each property you open is
|
|
645
|
+
prefilled with the value it has, ready to edit rather than retype. This is the
|
|
646
|
+
way to add optional properties, or to check a request before making it.
|
|
647
|
+
|
|
648
|
+
For scripts and CI, pass `--non-interactive` (or `-y`) to never be prompted.
|
|
649
|
+
The command must then be complete: if the command itself is ambiguous, or any
|
|
650
|
+
required property is missing, the CLI exits with an error naming what is
|
|
651
|
+
missing instead of asking for it.
|
|
558
652
|
|
|
559
653
|
To take a project from zero to a working Seam integration, run the
|
|
560
654
|
[Seam Wizard] from the project's root:
|
|
@@ -581,7 +675,19 @@ seam connect-webviews create
|
|
|
581
675
|
# List devices in your workspace
|
|
582
676
|
seam devices list
|
|
583
677
|
|
|
584
|
-
|
|
678
|
+
# Review and edit filters before listing devices
|
|
679
|
+
seam devices list --interactive
|
|
680
|
+
|
|
681
|
+
# List devices, failing instead of prompting
|
|
682
|
+
seam devices list --non-interactive
|
|
683
|
+
|
|
684
|
+
# Fails with: Missing required parameter for /locks/unlock_door: --device-id
|
|
685
|
+
seam locks unlock-door --non-interactive
|
|
686
|
+
|
|
687
|
+
# Fails with: Unknown parameter for /devices/list: --limitt
|
|
688
|
+
seam devices list --limitt 5
|
|
689
|
+
|
|
690
|
+
MY_DOOR=$(seam devices get --name "Front Door" | jq -r '.device.device_id')
|
|
585
691
|
|
|
586
692
|
# Unlock a lock
|
|
587
693
|
seam locks unlock-door --device-id $MY_DOOR
|
|
@@ -593,6 +699,163 @@ seam access-codes create --code "1234" --name "My Code"
|
|
|
593
699
|
seam access-codes list --device-id $MY_DOOR
|
|
594
700
|
```
|
|
595
701
|
|
|
702
|
+
### Output
|
|
703
|
+
|
|
704
|
+
Only the response is written to stdout, so any command may be piped or
|
|
705
|
+
redirected. Prompts, progress, and other information are written to stderr.
|
|
706
|
+
|
|
707
|
+
The response is trimmed to the response key and pagination: no other top level
|
|
708
|
+
fields are reported.
|
|
709
|
+
|
|
710
|
+
```bash
|
|
711
|
+
# The response, and nothing else, ends up in the file
|
|
712
|
+
seam devices list > devices.json
|
|
713
|
+
|
|
714
|
+
# Prompts and progress still show up in the terminal
|
|
715
|
+
seam devices list | jq '.devices[].device_id'
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
### Pagination
|
|
719
|
+
|
|
720
|
+
Every command that paginates accepts `--page-cursor` to select a page of
|
|
721
|
+
results, alongside `--limit` for the size of that page. Each response reports
|
|
722
|
+
its `pagination`, whose `next_page_cursor` is the cursor for the page after it.
|
|
723
|
+
|
|
724
|
+
```bash
|
|
725
|
+
# The first page, and the cursor for the next one
|
|
726
|
+
seam devices list --limit 2 | jq '.pagination.next_page_cursor'
|
|
727
|
+
|
|
728
|
+
# The page after it
|
|
729
|
+
seam devices list --limit 2 --page-cursor "$CURSOR"
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
A cursor is opaque: pass it back exactly as it was reported, and do not build
|
|
733
|
+
one yourself. Run `seam <command> --help` to see whether a command paginates.
|
|
734
|
+
|
|
735
|
+
### JSON
|
|
736
|
+
|
|
737
|
+
Request params may be piped or redirected in as a JSON object, or passed
|
|
738
|
+
inline with `--raw`. Params given as arguments win over raw or stdin params.
|
|
739
|
+
|
|
740
|
+
An argument the command does not accept is an error, so a typo is reported
|
|
741
|
+
rather than sent. Params read from stdin are passed through as given, so
|
|
742
|
+
anything the API itself accepts may be sent that way.
|
|
743
|
+
|
|
744
|
+
```bash
|
|
745
|
+
# Read params from a file
|
|
746
|
+
seam locks unlock-door < params.json
|
|
747
|
+
|
|
748
|
+
# Or from another program
|
|
749
|
+
echo '{"device_id": "'"$MY_DOOR"'"}' | seam locks unlock-door
|
|
750
|
+
|
|
751
|
+
# Pass request params inline as JSON
|
|
752
|
+
seam devices list --raw '{"search":"bar"}'
|
|
753
|
+
|
|
754
|
+
# --device-id wins over any device_id in params.json
|
|
755
|
+
seam devices list --limit 5 < params.json
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
Pass `--json` to write the response as JSON. It is enabled automatically
|
|
759
|
+
whenever stdout is not a terminal, so piping and redirecting produce JSON
|
|
760
|
+
without passing anything. Pass `--no-json` to opt out and get the pretty
|
|
761
|
+
format instead.
|
|
762
|
+
|
|
763
|
+
```bash
|
|
764
|
+
# Both write JSON
|
|
765
|
+
seam devices list --json
|
|
766
|
+
seam devices list | jq
|
|
767
|
+
|
|
768
|
+
# Pretty printed, even though it is piped
|
|
769
|
+
seam devices list --no-json | less
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
Without a terminal to prompt on, the CLI behaves as though
|
|
773
|
+
`--non-interactive` was given: rather than waiting for an answer nobody can
|
|
774
|
+
give, it exits with an error naming what is missing.
|
|
775
|
+
|
|
776
|
+
```bash
|
|
777
|
+
$ echo '{}' | seam locks unlock-door
|
|
778
|
+
Missing required parameter for /locks/unlock_door: --device-id
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
An error exits non-zero. A request that fails reports its `error` on stdout,
|
|
782
|
+
so it can be inspected from a pipe; anything else is written to stderr only.
|
|
783
|
+
|
|
784
|
+
### Selecting an endpoint and a workspace
|
|
785
|
+
|
|
786
|
+
Two settings say where commands go, and one command each stores them:
|
|
787
|
+
|
|
788
|
+
```bash
|
|
789
|
+
# Every later command runs against this endpoint
|
|
790
|
+
seam select endpoint https://connect.getseam.com
|
|
791
|
+
|
|
792
|
+
# ...and this workspace
|
|
793
|
+
seam select workspace $MY_WORKSPACE
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
Run either without a value to pick one interactively.
|
|
797
|
+
|
|
798
|
+
To send a single command somewhere else, pass `--endpoint` or
|
|
799
|
+
`--workspace-id` to that command. They override what is selected for that one
|
|
800
|
+
invocation and store nothing:
|
|
801
|
+
|
|
802
|
+
```bash
|
|
803
|
+
# List devices in another workspace, without switching to it
|
|
804
|
+
seam devices list --workspace-id $OTHER_WORKSPACE
|
|
805
|
+
|
|
806
|
+
# Run one command against a local Seam Connect instance
|
|
807
|
+
seam devices list --endpoint http://localhost:3020
|
|
808
|
+
|
|
809
|
+
# Log in to another endpoint: the token is stored for that endpoint,
|
|
810
|
+
# and the selected one is left alone
|
|
811
|
+
seam login --endpoint http://localhost:3020 --token $LOCAL_KEY
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
Because the two flags never store anything, they are refused on the commands
|
|
815
|
+
that do: `seam select endpoint --endpoint <url>` is an error, and the value
|
|
816
|
+
belongs after the command instead.
|
|
817
|
+
|
|
818
|
+
### Environment variables
|
|
819
|
+
|
|
820
|
+
Everything `seam login`, `seam select workspace`, and `seam select endpoint`
|
|
821
|
+
store may be given in the environment instead:
|
|
822
|
+
|
|
823
|
+
- `SEAM_CLI_TOKEN`: a Personal Access Token or API Key,
|
|
824
|
+
- `SEAM_CLI_WORKSPACE_ID`: the workspace requests are made against,
|
|
825
|
+
- `SEAM_CLI_ENDPOINT`: the Seam API endpoint requests are made to.
|
|
826
|
+
|
|
827
|
+
Any of them, all of them, or none of them may be set. Each one wins over the
|
|
828
|
+
corresponding stored value and is in turn overridden by `--endpoint` or
|
|
829
|
+
`--workspace-id`, which makes them useful for CI or for working against
|
|
830
|
+
another workspace for a whole shell.
|
|
831
|
+
|
|
832
|
+
```bash
|
|
833
|
+
# One command against another workspace
|
|
834
|
+
SEAM_CLI_WORKSPACE_ID=$OTHER_WORKSPACE seam devices list
|
|
835
|
+
|
|
836
|
+
# No login needed: authenticate from the environment
|
|
837
|
+
export SEAM_CLI_TOKEN=$SEAM_API_KEY
|
|
838
|
+
seam devices list
|
|
839
|
+
|
|
840
|
+
# Work against a local Seam Connect instance
|
|
841
|
+
SEAM_CLI_ENDPOINT=http://localhost:3020 seam devices list
|
|
842
|
+
```
|
|
843
|
+
|
|
844
|
+
An API Key is scoped to a single workspace, so it needs no workspace id. A
|
|
845
|
+
Personal Access Token works across workspaces, so it needs one from
|
|
846
|
+
`--workspace-id`, `SEAM_CLI_WORKSPACE_ID`, or `seam select workspace`.
|
|
847
|
+
|
|
848
|
+
The command that would store an overridden value fails rather than storing
|
|
849
|
+
something the environment ignores: `seam login` and `seam logout` while
|
|
850
|
+
`SEAM_CLI_TOKEN` is set, `seam select workspace` while
|
|
851
|
+
`SEAM_CLI_WORKSPACE_ID` is set, and `seam select endpoint` while
|
|
852
|
+
`SEAM_CLI_ENDPOINT` is set. Unset the variable to use those commands.
|
|
853
|
+
|
|
854
|
+
```bash
|
|
855
|
+
$ SEAM_CLI_TOKEN=$SEAM_API_KEY seam login
|
|
856
|
+
Cannot log in while SEAM_CLI_TOKEN is set: it overrides what would be stored. Unset SEAM_CLI_TOKEN to log in.
|
|
857
|
+
```
|
|
858
|
+
|
|
596
859
|
### Receiving Webhooks
|
|
597
860
|
|
|
598
861
|
The Seam API implements webhooks using [Svix](https://www.svix.com).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "seam",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.233.0",
|
|
4
4
|
"description": "JavaScript SDK for the Seam API written in TypeScript.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -73,9 +73,10 @@
|
|
|
73
73
|
"version": "^11.0.0 || ^10.0.0"
|
|
74
74
|
}
|
|
75
75
|
},
|
|
76
|
+
"packageManager": "npm@11.19.0",
|
|
76
77
|
"dependencies": {
|
|
77
|
-
"@seamapi/cli": "0.
|
|
78
|
-
"@seamapi/http": "2.
|
|
78
|
+
"@seamapi/cli": "0.28.0",
|
|
79
|
+
"@seamapi/http": "2.11.2",
|
|
79
80
|
"@seamapi/webhook": "1.4.1"
|
|
80
81
|
},
|
|
81
82
|
"devDependencies": {
|