@keystrokehq/spotify 0.0.1

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.
Files changed (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +113 -0
  3. package/dist/_official/index.d.mts +32 -0
  4. package/dist/_official/index.mjs +3 -0
  5. package/dist/_runtime/index.d.mts +1 -0
  6. package/dist/_runtime/index.mjs +1 -0
  7. package/dist/albums.d.mts +265 -0
  8. package/dist/albums.mjs +72 -0
  9. package/dist/artists.d.mts +237 -0
  10. package/dist/artists.mjs +84 -0
  11. package/dist/audio-analysis.d.mts +91 -0
  12. package/dist/audio-analysis.mjs +19 -0
  13. package/dist/audio-features.d.mts +61 -0
  14. package/dist/audio-features.mjs +31 -0
  15. package/dist/audiobooks.d.mts +176 -0
  16. package/dist/audiobooks.mjs +59 -0
  17. package/dist/browse.d.mts +74 -0
  18. package/dist/browse.mjs +31 -0
  19. package/dist/categories.d.mts +118 -0
  20. package/dist/categories.mjs +66 -0
  21. package/dist/chapters.d.mts +163 -0
  22. package/dist/chapters.mjs +39 -0
  23. package/dist/client.d.mts +3486 -0
  24. package/dist/client.mjs +758 -0
  25. package/dist/connection.d.mts +2 -0
  26. package/dist/connection.mjs +3 -0
  27. package/dist/episodes.d.mts +149 -0
  28. package/dist/episodes.mjs +39 -0
  29. package/dist/errors.d.mts +34 -0
  30. package/dist/errors.mjs +89 -0
  31. package/dist/events.d.mts +613 -0
  32. package/dist/events.mjs +55 -0
  33. package/dist/factory-tZba6Hij.mjs +8 -0
  34. package/dist/follow.d.mts +83 -0
  35. package/dist/follow.mjs +65 -0
  36. package/dist/genres.d.mts +14 -0
  37. package/dist/genres.mjs +19 -0
  38. package/dist/index.d.mts +1 -0
  39. package/dist/index.mjs +1 -0
  40. package/dist/integration-DQ5Egd4f.d.mts +41 -0
  41. package/dist/integration-ykoImsCq.mjs +78 -0
  42. package/dist/library.d.mts +472 -0
  43. package/dist/library.mjs +225 -0
  44. package/dist/markets.d.mts +14 -0
  45. package/dist/markets.mjs +20 -0
  46. package/dist/me.d.mts +169 -0
  47. package/dist/me.mjs +58 -0
  48. package/dist/messaging.d.mts +1 -0
  49. package/dist/messaging.mjs +1 -0
  50. package/dist/operations.d.mts +6 -0
  51. package/dist/operations.mjs +237 -0
  52. package/dist/player.d.mts +877 -0
  53. package/dist/player.mjs +220 -0
  54. package/dist/playlists.d.mts +546 -0
  55. package/dist/playlists.mjs +243 -0
  56. package/dist/recommendations.d.mts +144 -0
  57. package/dist/recommendations.mjs +137 -0
  58. package/dist/schemas.d.mts +3312 -0
  59. package/dist/schemas.mjs +460 -0
  60. package/dist/search.d.mts +389 -0
  61. package/dist/search.mjs +42 -0
  62. package/dist/shows.d.mts +159 -0
  63. package/dist/shows.mjs +59 -0
  64. package/dist/tracks.d.mts +173 -0
  65. package/dist/tracks.mjs +37 -0
  66. package/dist/triggers.d.mts +45 -0
  67. package/dist/triggers.mjs +201 -0
  68. package/dist/users.d.mts +35 -0
  69. package/dist/users.mjs +20 -0
  70. package/dist/verification.d.mts +1 -0
  71. package/dist/verification.mjs +1 -0
  72. package/package.json +187 -0
@@ -0,0 +1,173 @@
1
+ import { z } from "zod";
2
+ import * as _keystrokehq_core0 from "@keystrokehq/core";
3
+ import * as _keystrokehq_core_credential_set0 from "@keystrokehq/core/credential-set";
4
+
5
+ //#region src/tracks.d.ts
6
+ declare const getTrack: _keystrokehq_core0.Operation<z.ZodObject<{
7
+ id: z.ZodString;
8
+ market: z.ZodOptional<z.ZodString>;
9
+ }, z.core.$strip>, z.ZodObject<{
10
+ album: z.ZodOptional<z.ZodObject<{
11
+ albumType: z.ZodOptional<z.ZodEnum<{
12
+ album: "album";
13
+ single: "single";
14
+ compilation: "compilation";
15
+ }>>;
16
+ artists: z.ZodArray<z.ZodObject<{
17
+ externalUrls: z.ZodOptional<z.ZodObject<{
18
+ spotify: z.ZodOptional<z.ZodURL>;
19
+ }, z.core.$strip>>;
20
+ href: z.ZodOptional<z.ZodURL>;
21
+ id: z.ZodString;
22
+ name: z.ZodString;
23
+ type: z.ZodLiteral<"artist">;
24
+ uri: z.ZodOptional<z.ZodString>;
25
+ }, z.core.$strip>>;
26
+ availableMarkets: z.ZodOptional<z.ZodArray<z.ZodString>>;
27
+ externalUrls: z.ZodOptional<z.ZodObject<{
28
+ spotify: z.ZodOptional<z.ZodURL>;
29
+ }, z.core.$strip>>;
30
+ href: z.ZodOptional<z.ZodURL>;
31
+ id: z.ZodString;
32
+ images: z.ZodArray<z.ZodObject<{
33
+ url: z.ZodURL;
34
+ height: z.ZodNullable<z.ZodNumber>;
35
+ width: z.ZodNullable<z.ZodNumber>;
36
+ }, z.core.$strip>>;
37
+ name: z.ZodString;
38
+ releaseDate: z.ZodOptional<z.ZodString>;
39
+ releaseDatePrecision: z.ZodOptional<z.ZodEnum<{
40
+ year: "year";
41
+ month: "month";
42
+ day: "day";
43
+ }>>;
44
+ totalTracks: z.ZodOptional<z.ZodNumber>;
45
+ type: z.ZodLiteral<"album">;
46
+ uri: z.ZodOptional<z.ZodString>;
47
+ }, z.core.$strip>>;
48
+ artists: z.ZodArray<z.ZodObject<{
49
+ externalUrls: z.ZodOptional<z.ZodObject<{
50
+ spotify: z.ZodOptional<z.ZodURL>;
51
+ }, z.core.$strip>>;
52
+ href: z.ZodOptional<z.ZodURL>;
53
+ id: z.ZodString;
54
+ name: z.ZodString;
55
+ type: z.ZodLiteral<"artist">;
56
+ uri: z.ZodOptional<z.ZodString>;
57
+ }, z.core.$strip>>;
58
+ availableMarkets: z.ZodOptional<z.ZodArray<z.ZodString>>;
59
+ discNumber: z.ZodOptional<z.ZodNumber>;
60
+ durationMs: z.ZodNumber;
61
+ explicit: z.ZodBoolean;
62
+ externalIds: z.ZodOptional<z.ZodObject<{
63
+ isrc: z.ZodOptional<z.ZodString>;
64
+ ean: z.ZodOptional<z.ZodString>;
65
+ upc: z.ZodOptional<z.ZodString>;
66
+ }, z.core.$strip>>;
67
+ externalUrls: z.ZodOptional<z.ZodObject<{
68
+ spotify: z.ZodOptional<z.ZodURL>;
69
+ }, z.core.$strip>>;
70
+ href: z.ZodOptional<z.ZodURL>;
71
+ id: z.ZodString;
72
+ isLocal: z.ZodOptional<z.ZodBoolean>;
73
+ isPlayable: z.ZodOptional<z.ZodBoolean>;
74
+ name: z.ZodString;
75
+ popularity: z.ZodOptional<z.ZodNumber>;
76
+ previewUrl: z.ZodOptional<z.ZodUnion<readonly [z.ZodURL, z.ZodNull]>>;
77
+ restrictions: z.ZodOptional<z.ZodObject<{
78
+ reason: z.ZodString;
79
+ }, z.core.$strip>>;
80
+ trackNumber: z.ZodOptional<z.ZodNumber>;
81
+ type: z.ZodLiteral<"track">;
82
+ uri: z.ZodOptional<z.ZodString>;
83
+ }, z.core.$strip>, readonly [_keystrokehq_core0.CredentialSet<"spotify", z.ZodObject<{
84
+ SPOTIFY_ACCESS_TOKEN: z.ZodString;
85
+ }, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
86
+ SPOTIFY_ACCESS_TOKEN: z.ZodString;
87
+ }, z.core.$strip>>[] | undefined>], undefined>;
88
+ declare const getSeveralTracks: _keystrokehq_core0.Operation<z.ZodObject<{
89
+ ids: z.ZodArray<z.ZodString>;
90
+ market: z.ZodOptional<z.ZodString>;
91
+ }, z.core.$strip>, z.ZodObject<{
92
+ tracks: z.ZodArray<z.ZodObject<{
93
+ album: z.ZodOptional<z.ZodObject<{
94
+ albumType: z.ZodOptional<z.ZodEnum<{
95
+ album: "album";
96
+ single: "single";
97
+ compilation: "compilation";
98
+ }>>;
99
+ artists: z.ZodArray<z.ZodObject<{
100
+ externalUrls: z.ZodOptional<z.ZodObject<{
101
+ spotify: z.ZodOptional<z.ZodURL>;
102
+ }, z.core.$strip>>;
103
+ href: z.ZodOptional<z.ZodURL>;
104
+ id: z.ZodString;
105
+ name: z.ZodString;
106
+ type: z.ZodLiteral<"artist">;
107
+ uri: z.ZodOptional<z.ZodString>;
108
+ }, z.core.$strip>>;
109
+ availableMarkets: z.ZodOptional<z.ZodArray<z.ZodString>>;
110
+ externalUrls: z.ZodOptional<z.ZodObject<{
111
+ spotify: z.ZodOptional<z.ZodURL>;
112
+ }, z.core.$strip>>;
113
+ href: z.ZodOptional<z.ZodURL>;
114
+ id: z.ZodString;
115
+ images: z.ZodArray<z.ZodObject<{
116
+ url: z.ZodURL;
117
+ height: z.ZodNullable<z.ZodNumber>;
118
+ width: z.ZodNullable<z.ZodNumber>;
119
+ }, z.core.$strip>>;
120
+ name: z.ZodString;
121
+ releaseDate: z.ZodOptional<z.ZodString>;
122
+ releaseDatePrecision: z.ZodOptional<z.ZodEnum<{
123
+ year: "year";
124
+ month: "month";
125
+ day: "day";
126
+ }>>;
127
+ totalTracks: z.ZodOptional<z.ZodNumber>;
128
+ type: z.ZodLiteral<"album">;
129
+ uri: z.ZodOptional<z.ZodString>;
130
+ }, z.core.$strip>>;
131
+ artists: z.ZodArray<z.ZodObject<{
132
+ externalUrls: z.ZodOptional<z.ZodObject<{
133
+ spotify: z.ZodOptional<z.ZodURL>;
134
+ }, z.core.$strip>>;
135
+ href: z.ZodOptional<z.ZodURL>;
136
+ id: z.ZodString;
137
+ name: z.ZodString;
138
+ type: z.ZodLiteral<"artist">;
139
+ uri: z.ZodOptional<z.ZodString>;
140
+ }, z.core.$strip>>;
141
+ availableMarkets: z.ZodOptional<z.ZodArray<z.ZodString>>;
142
+ discNumber: z.ZodOptional<z.ZodNumber>;
143
+ durationMs: z.ZodNumber;
144
+ explicit: z.ZodBoolean;
145
+ externalIds: z.ZodOptional<z.ZodObject<{
146
+ isrc: z.ZodOptional<z.ZodString>;
147
+ ean: z.ZodOptional<z.ZodString>;
148
+ upc: z.ZodOptional<z.ZodString>;
149
+ }, z.core.$strip>>;
150
+ externalUrls: z.ZodOptional<z.ZodObject<{
151
+ spotify: z.ZodOptional<z.ZodURL>;
152
+ }, z.core.$strip>>;
153
+ href: z.ZodOptional<z.ZodURL>;
154
+ id: z.ZodString;
155
+ isLocal: z.ZodOptional<z.ZodBoolean>;
156
+ isPlayable: z.ZodOptional<z.ZodBoolean>;
157
+ name: z.ZodString;
158
+ popularity: z.ZodOptional<z.ZodNumber>;
159
+ previewUrl: z.ZodOptional<z.ZodUnion<readonly [z.ZodURL, z.ZodNull]>>;
160
+ restrictions: z.ZodOptional<z.ZodObject<{
161
+ reason: z.ZodString;
162
+ }, z.core.$strip>>;
163
+ trackNumber: z.ZodOptional<z.ZodNumber>;
164
+ type: z.ZodLiteral<"track">;
165
+ uri: z.ZodOptional<z.ZodString>;
166
+ }, z.core.$strip>>;
167
+ }, z.core.$strip>, readonly [_keystrokehq_core0.CredentialSet<"spotify", z.ZodObject<{
168
+ SPOTIFY_ACCESS_TOKEN: z.ZodString;
169
+ }, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
170
+ SPOTIFY_ACCESS_TOKEN: z.ZodString;
171
+ }, z.core.$strip>>[] | undefined>], undefined>;
172
+ //#endregion
173
+ export { getSeveralTracks, getTrack };
@@ -0,0 +1,37 @@
1
+ import { spotifyIdSchema, spotifyMarketSchema, spotifyTrackSchema } from "./schemas.mjs";
2
+ import { createSpotifyClient } from "./client.mjs";
3
+ import { t as spotifyOperation } from "./factory-tZba6Hij.mjs";
4
+ import { z } from "zod";
5
+
6
+ //#region src/tracks.ts
7
+ const trackIdListSchema = z.array(spotifyIdSchema).min(1).max(50);
8
+ const severalTracksResponseSchema = z.object({ tracks: z.array(spotifyTrackSchema) });
9
+ const getTrack = spotifyOperation({
10
+ id: "get_spotify_track",
11
+ name: "Get Spotify Track",
12
+ description: "Fetch a Spotify track by its ID.",
13
+ input: z.object({
14
+ id: spotifyIdSchema,
15
+ market: spotifyMarketSchema.optional()
16
+ }),
17
+ output: spotifyTrackSchema,
18
+ run: async (input, credentials) => {
19
+ return createSpotifyClient(credentials).tracks.getTrack(input.id, input.market);
20
+ }
21
+ });
22
+ const getSeveralTracks = spotifyOperation({
23
+ id: "get_spotify_several_tracks",
24
+ name: "Get Several Spotify Tracks",
25
+ description: "Fetch multiple Spotify tracks in one request.",
26
+ input: z.object({
27
+ ids: trackIdListSchema,
28
+ market: spotifyMarketSchema.optional()
29
+ }),
30
+ output: severalTracksResponseSchema,
31
+ run: async (input, credentials) => {
32
+ return createSpotifyClient(credentials).tracks.getSeveralTracks(input.ids, input.market);
33
+ }
34
+ });
35
+
36
+ //#endregion
37
+ export { getSeveralTracks, getTrack };
@@ -0,0 +1,45 @@
1
+ import { n as spotify } from "./integration-DQ5Egd4f.mjs";
2
+ import { spotifyNewDeviceAddedEventSchema, spotifyPlaylistItemsChangedEventSchema, spotifyRecentlyPlayedTrackAddedEventSchema, spotifySavedItemAddedEventSchema, spotifyUserPlaylistsChangedEventSchema } from "./events.mjs";
3
+ import { z } from "zod";
4
+ import { BoundTrigger } from "@keystrokehq/core";
5
+ import { IntegrationTriggerBindingOptions } from "@keystrokehq/integration-authoring";
6
+ import { PollingTriggerManifest } from "@keystrokehq/core/trigger";
7
+
8
+ //#region src/triggers.d.ts
9
+ type SpotifyCredentialSets = readonly [typeof spotify];
10
+ type SpotifyPollingSchedule = number | `${number}s` | `${number}m` | `${number}h` | `${number}d` | `${number}w` | `${number}y`;
11
+ type SpotifyPollingBoundTrigger<TEvent> = BoundTrigger<TEvent, SpotifyCredentialSets, PollingTriggerManifest, TEvent>;
12
+ interface SpotifyPollingBindingOptions<TEvent> extends IntegrationTriggerBindingOptions<TEvent, TEvent> {
13
+ readonly schedule?: SpotifyPollingSchedule;
14
+ }
15
+ interface PlaylistItemsChangedOptions extends SpotifyPollingBindingOptions<z.infer<typeof spotifyPlaylistItemsChangedEventSchema>> {
16
+ readonly playlistId: string;
17
+ readonly market?: string;
18
+ readonly limit?: number;
19
+ }
20
+ interface UserPlaylistsChangedOptions extends SpotifyPollingBindingOptions<z.infer<typeof spotifyUserPlaylistsChangedEventSchema>> {
21
+ readonly limit?: number;
22
+ readonly offset?: number;
23
+ }
24
+ interface RecentlyPlayedTrackAddedOptions extends SpotifyPollingBindingOptions<z.infer<typeof spotifyRecentlyPlayedTrackAddedEventSchema>> {
25
+ readonly limit?: number;
26
+ }
27
+ interface SavedItemAddedOptions extends SpotifyPollingBindingOptions<z.infer<typeof spotifySavedItemAddedEventSchema>> {
28
+ readonly itemType: 'album' | 'track' | 'show' | 'episode' | 'audiobook';
29
+ readonly limit?: number;
30
+ readonly market?: string;
31
+ }
32
+ declare function newDeviceAdded(options?: SpotifyPollingBindingOptions<z.infer<typeof spotifyNewDeviceAddedEventSchema>>): SpotifyPollingBoundTrigger<z.infer<typeof spotifyNewDeviceAddedEventSchema>>;
33
+ declare function playlistItemsChanged(options: PlaylistItemsChangedOptions): SpotifyPollingBoundTrigger<z.infer<typeof spotifyPlaylistItemsChangedEventSchema>>;
34
+ declare function userPlaylistsChanged(options?: UserPlaylistsChangedOptions): SpotifyPollingBoundTrigger<z.infer<typeof spotifyUserPlaylistsChangedEventSchema>>;
35
+ declare function recentlyPlayedTrackAdded(options?: RecentlyPlayedTrackAddedOptions): SpotifyPollingBoundTrigger<z.infer<typeof spotifyRecentlyPlayedTrackAddedEventSchema>>;
36
+ declare function savedItemAdded(options: SavedItemAddedOptions): SpotifyPollingBoundTrigger<z.infer<typeof spotifySavedItemAddedEventSchema>>;
37
+ declare const polling: Readonly<{
38
+ newDeviceAdded: typeof newDeviceAdded;
39
+ playlistItemsChanged: typeof playlistItemsChanged;
40
+ userPlaylistsChanged: typeof userPlaylistsChanged;
41
+ recentlyPlayedTrackAdded: typeof recentlyPlayedTrackAdded;
42
+ savedItemAdded: typeof savedItemAdded;
43
+ }>;
44
+ //#endregion
45
+ export { newDeviceAdded, playlistItemsChanged, polling, recentlyPlayedTrackAdded, savedItemAdded, userPlaylistsChanged };
@@ -0,0 +1,201 @@
1
+ import { t as spotify } from "./integration-ykoImsCq.mjs";
2
+ import { createSpotifyClient } from "./client.mjs";
3
+ import { spotifyNewDeviceAddedEventSchema, spotifyPlaylistItemsChangedEventSchema, spotifyRecentlyPlayedTrackAddedEventSchema, spotifySavedItemAddedEventSchema, spotifyUserPlaylistsChangedEventSchema } from "./events.mjs";
4
+ import { z } from "zod";
5
+ import { createPollingTriggerBindingFactory } from "@keystrokehq/integration-authoring";
6
+
7
+ //#region src/triggers.ts
8
+ const nullableNewDeviceEventSchema = z.union([spotifyNewDeviceAddedEventSchema, z.null()]);
9
+ const nullablePlaylistItemsChangedEventSchema = z.union([spotifyPlaylistItemsChangedEventSchema, z.null()]);
10
+ const nullableUserPlaylistsChangedEventSchema = z.union([spotifyUserPlaylistsChangedEventSchema, z.null()]);
11
+ const nullableRecentlyPlayedTrackAddedEventSchema = z.union([spotifyRecentlyPlayedTrackAddedEventSchema, z.null()]);
12
+ const nullableSavedItemAddedEventSchema = z.union([spotifySavedItemAddedEventSchema, z.null()]);
13
+ function newDeviceAdded(options) {
14
+ return createPollingTriggerBindingFactory({
15
+ defaultName: "Spotify New Device Added",
16
+ defaultDescription: "Poll available Spotify devices and emit the most recent device snapshot.",
17
+ schedule: options?.schedule ?? "5m",
18
+ credentialSets: [spotify],
19
+ response: nullableNewDeviceEventSchema,
20
+ poll: async (ctx) => {
21
+ const device = (await createSpotifyClient(ctx.credentials.spotify).player.getAvailableDevices()).devices[0];
22
+ return device ? {
23
+ eventId: `device:${device.id ?? device.name}`,
24
+ type: "device.added",
25
+ device
26
+ } : null;
27
+ },
28
+ mapPayload: (response) => response,
29
+ idempotencyKey: (response) => response?.eventId
30
+ })({
31
+ name: options?.name,
32
+ description: options?.description,
33
+ filter: options?.filter,
34
+ transform: options?.transform
35
+ });
36
+ }
37
+ function playlistItemsChanged(options) {
38
+ return createPollingTriggerBindingFactory({
39
+ defaultName: "Spotify Playlist Items Changed",
40
+ defaultDescription: "Poll playlist items and emit the most recent playlist entry.",
41
+ schedule: options.schedule ?? "5m",
42
+ credentialSets: [spotify],
43
+ response: nullablePlaylistItemsChangedEventSchema,
44
+ poll: async (ctx) => {
45
+ const item = (await createSpotifyClient(ctx.credentials.spotify).playlists.getPlaylistItems(options.playlistId, {
46
+ market: options.market,
47
+ limit: options.limit ?? 20
48
+ })).items[0];
49
+ const itemUri = item?.track?.uri ?? item?.track?.id;
50
+ return item && itemUri ? {
51
+ eventId: `${options.playlistId}:${item.addedAt ?? "unknown"}:${itemUri}:0`,
52
+ type: "playlist.item_added",
53
+ playlistId: options.playlistId,
54
+ snapshotId: item.addedAt ?? "unknown",
55
+ item
56
+ } : null;
57
+ },
58
+ mapPayload: (response) => response,
59
+ idempotencyKey: (response) => response?.eventId
60
+ })({
61
+ name: options.name,
62
+ description: options.description,
63
+ filter: options.filter,
64
+ transform: options.transform
65
+ });
66
+ }
67
+ function userPlaylistsChanged(options) {
68
+ return createPollingTriggerBindingFactory({
69
+ defaultName: "Spotify User Playlists Changed",
70
+ defaultDescription: "Poll the current user playlists and emit the most recent playlist snapshot.",
71
+ schedule: options?.schedule ?? "5m",
72
+ credentialSets: [spotify],
73
+ response: nullableUserPlaylistsChangedEventSchema,
74
+ poll: async (ctx) => {
75
+ const playlist = (await createSpotifyClient(ctx.credentials.spotify).playlists.listMyPlaylists({
76
+ limit: options?.limit ?? 20,
77
+ offset: options?.offset
78
+ })).items[0];
79
+ return playlist ? {
80
+ eventId: `${playlist.id}:${playlist.tracks?.total ?? 0}:details_changed`,
81
+ type: "playlist.details_changed",
82
+ playlist
83
+ } : null;
84
+ },
85
+ mapPayload: (response) => response,
86
+ idempotencyKey: (response) => response?.eventId
87
+ })({
88
+ name: options?.name,
89
+ description: options?.description,
90
+ filter: options?.filter,
91
+ transform: options?.transform
92
+ });
93
+ }
94
+ function recentlyPlayedTrackAdded(options) {
95
+ return createPollingTriggerBindingFactory({
96
+ defaultName: "Spotify Recently Played Track Added",
97
+ defaultDescription: "Poll recently played tracks and emit the most recent playback event.",
98
+ schedule: options?.schedule ?? "5m",
99
+ credentialSets: [spotify],
100
+ response: nullableRecentlyPlayedTrackAddedEventSchema,
101
+ poll: async (ctx) => {
102
+ const play = (await createSpotifyClient(ctx.credentials.spotify).player.getRecentlyPlayed({
103
+ limit: options?.limit ?? 1,
104
+ after: ctx.lastPolledAt ? Date.parse(ctx.lastPolledAt) : void 0
105
+ })).items[0];
106
+ return play ? {
107
+ eventId: `${play.playedAt}:${play.track.id}`,
108
+ type: "recently_played.track_added",
109
+ play
110
+ } : null;
111
+ },
112
+ mapPayload: (response) => response,
113
+ idempotencyKey: (response) => response?.eventId
114
+ })({
115
+ name: options?.name,
116
+ description: options?.description,
117
+ filter: options?.filter,
118
+ transform: options?.transform
119
+ });
120
+ }
121
+ function savedItemAdded(options) {
122
+ return createPollingTriggerBindingFactory({
123
+ defaultName: "Spotify Saved Item Added",
124
+ defaultDescription: "Poll the Spotify library and emit the most recent saved item for a resource type.",
125
+ schedule: options.schedule ?? "5m",
126
+ credentialSets: [spotify],
127
+ response: nullableSavedItemAddedEventSchema,
128
+ poll: async (ctx) => {
129
+ const client = createSpotifyClient(ctx.credentials.spotify);
130
+ if (options.itemType === "album") {
131
+ const item = (await client.library.listSavedAlbums({
132
+ limit: options.limit ?? 1,
133
+ market: options.market
134
+ })).items[0];
135
+ return item ? {
136
+ eventId: `album:${item.album.id}:${item.addedAt}`,
137
+ type: "library.saved_item_added",
138
+ itemType: "album",
139
+ item
140
+ } : null;
141
+ }
142
+ if (options.itemType === "track") {
143
+ const item = (await client.library.listSavedTracks({
144
+ limit: options.limit ?? 1,
145
+ market: options.market
146
+ })).items[0];
147
+ return item ? {
148
+ eventId: `track:${item.track.id}:${item.addedAt}`,
149
+ type: "library.saved_item_added",
150
+ itemType: "track",
151
+ item
152
+ } : null;
153
+ }
154
+ if (options.itemType === "show") {
155
+ const item = (await client.library.listSavedShows({ limit: options.limit ?? 1 })).items[0];
156
+ return item ? {
157
+ eventId: `show:${item.show.id}:${item.addedAt}`,
158
+ type: "library.saved_item_added",
159
+ itemType: "show",
160
+ item
161
+ } : null;
162
+ }
163
+ if (options.itemType === "episode") {
164
+ const item = (await client.library.listSavedEpisodes({
165
+ limit: options.limit ?? 1,
166
+ market: options.market
167
+ })).items[0];
168
+ return item ? {
169
+ eventId: `episode:${item.episode.id}:${item.addedAt}`,
170
+ type: "library.saved_item_added",
171
+ itemType: "episode",
172
+ item
173
+ } : null;
174
+ }
175
+ const item = (await client.library.listSavedAudiobooks({ limit: options.limit ?? 1 })).items[0];
176
+ return item ? {
177
+ eventId: `audiobook:${item.audiobook.id}:${item.addedAt}`,
178
+ type: "library.saved_item_added",
179
+ itemType: "audiobook",
180
+ item
181
+ } : null;
182
+ },
183
+ mapPayload: (response) => response,
184
+ idempotencyKey: (response) => response?.eventId
185
+ })({
186
+ name: options.name,
187
+ description: options.description,
188
+ filter: options.filter,
189
+ transform: options.transform
190
+ });
191
+ }
192
+ const polling = Object.freeze({
193
+ newDeviceAdded,
194
+ playlistItemsChanged,
195
+ userPlaylistsChanged,
196
+ recentlyPlayedTrackAdded,
197
+ savedItemAdded
198
+ });
199
+
200
+ //#endregion
201
+ export { newDeviceAdded, playlistItemsChanged, polling, recentlyPlayedTrackAdded, savedItemAdded, userPlaylistsChanged };
@@ -0,0 +1,35 @@
1
+ import { z } from "zod";
2
+ import * as _keystrokehq_core0 from "@keystrokehq/core";
3
+ import * as _keystrokehq_core_credential_set0 from "@keystrokehq/core/credential-set";
4
+
5
+ //#region src/users.d.ts
6
+ declare const getUser: _keystrokehq_core0.Operation<z.ZodObject<{
7
+ id: z.ZodString;
8
+ }, z.core.$strip>, z.ZodObject<{
9
+ displayName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
10
+ externalUrls: z.ZodOptional<z.ZodObject<{
11
+ spotify: z.ZodOptional<z.ZodURL>;
12
+ }, z.core.$strip>>;
13
+ followers: z.ZodOptional<z.ZodObject<{
14
+ href: z.ZodOptional<z.ZodNullable<z.ZodURL>>;
15
+ total: z.ZodNumber;
16
+ }, z.core.$strip>>;
17
+ href: z.ZodOptional<z.ZodURL>;
18
+ id: z.ZodString;
19
+ type: z.ZodLiteral<"user">;
20
+ uri: z.ZodOptional<z.ZodString>;
21
+ email: z.ZodOptional<z.ZodEmail>;
22
+ country: z.ZodOptional<z.ZodString>;
23
+ product: z.ZodOptional<z.ZodString>;
24
+ images: z.ZodOptional<z.ZodArray<z.ZodObject<{
25
+ url: z.ZodURL;
26
+ height: z.ZodNullable<z.ZodNumber>;
27
+ width: z.ZodNullable<z.ZodNumber>;
28
+ }, z.core.$strip>>>;
29
+ }, z.core.$strip>, readonly [_keystrokehq_core0.CredentialSet<"spotify", z.ZodObject<{
30
+ SPOTIFY_ACCESS_TOKEN: z.ZodString;
31
+ }, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
32
+ SPOTIFY_ACCESS_TOKEN: z.ZodString;
33
+ }, z.core.$strip>>[] | undefined>], undefined>;
34
+ //#endregion
35
+ export { getUser };
package/dist/users.mjs ADDED
@@ -0,0 +1,20 @@
1
+ import { spotifyIdSchema, spotifyUserSchema } from "./schemas.mjs";
2
+ import { createSpotifyClient } from "./client.mjs";
3
+ import { t as spotifyOperation } from "./factory-tZba6Hij.mjs";
4
+ import { z } from "zod";
5
+
6
+ //#region src/users.ts
7
+ const userLookupInputSchema = z.object({ id: spotifyIdSchema });
8
+ const getUser = spotifyOperation({
9
+ id: "get_spotify_user",
10
+ name: "Get Spotify User",
11
+ description: "Fetch a Spotify user profile by user ID.",
12
+ input: userLookupInputSchema,
13
+ output: spotifyUserSchema,
14
+ run: async (input, credentials) => {
15
+ return createSpotifyClient(credentials).users.getUser(input.id);
16
+ }
17
+ });
18
+
19
+ //#endregion
20
+ export { getUser };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ export { };