@spicemod/creator 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 (101) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +35 -0
  3. package/dist/bin.d.mts +1 -0
  4. package/dist/bin.mjs +1739 -0
  5. package/dist/client/index.d.mts +2175 -0
  6. package/dist/client/index.mjs +7 -0
  7. package/dist/templates/extension/js/react/eslint.config.js +29 -0
  8. package/dist/templates/extension/js/react/src/app.jsx +27 -0
  9. package/dist/templates/extension/js/react/src/components/Onboarding.jsx +72 -0
  10. package/dist/templates/extension/js/vanilla/components/Onboarding.js +71 -0
  11. package/dist/templates/extension/js/vanilla/eslint.config.js +16 -0
  12. package/dist/templates/extension/js/vanilla/src/app.js +12 -0
  13. package/dist/templates/extension/meta.json +4 -0
  14. package/dist/templates/extension/shared/.oxlintrc.json +36 -0
  15. package/dist/templates/extension/shared/README.template.md +53 -0
  16. package/dist/templates/extension/shared/app.css +163 -0
  17. package/dist/templates/extension/shared/biome.json +36 -0
  18. package/dist/templates/extension/shared/css.d.ts +44 -0
  19. package/dist/templates/extension/shared/jsconfig.json +32 -0
  20. package/dist/templates/extension/shared/spice.config.js +9 -0
  21. package/dist/templates/extension/shared/spice.config.ts +9 -0
  22. package/dist/templates/extension/shared/tsconfig.json +32 -0
  23. package/dist/templates/extension/ts/react/eslint.config.ts +29 -0
  24. package/dist/templates/extension/ts/react/src/app.tsx +27 -0
  25. package/dist/templates/extension/ts/react/src/components/Onboarding.tsx +83 -0
  26. package/dist/templates/extension/ts/vanilla/biome.json +36 -0
  27. package/dist/templates/extension/ts/vanilla/eslint.config.ts +16 -0
  28. package/dist/templates/extension/ts/vanilla/src/app.ts +12 -0
  29. package/dist/templates/extension/ts/vanilla/src/components/Onboarding.ts +79 -0
  30. package/dist/templates/liveReload.js +70 -0
  31. package/dist/templates/theme/js/react/eslint.config.js +29 -0
  32. package/dist/templates/theme/js/react/src/app.jsx +25 -0
  33. package/dist/templates/theme/js/react/src/components/Onboarding.jsx +72 -0
  34. package/dist/templates/theme/js/vanilla/eslint.config.js +16 -0
  35. package/dist/templates/theme/js/vanilla/src/app.js +11 -0
  36. package/dist/templates/theme/js/vanilla/src/components/Onboarding.js +71 -0
  37. package/dist/templates/theme/meta.json +4 -0
  38. package/dist/templates/theme/shared/.oxlintrc.json +36 -0
  39. package/dist/templates/theme/shared/README.template.md +53 -0
  40. package/dist/templates/theme/shared/app.css +163 -0
  41. package/dist/templates/theme/shared/biome.json +36 -0
  42. package/dist/templates/theme/shared/css.d.ts +44 -0
  43. package/dist/templates/theme/shared/jsconfig.json +31 -0
  44. package/dist/templates/theme/shared/spice.config.js +9 -0
  45. package/dist/templates/theme/shared/spice.config.ts +9 -0
  46. package/dist/templates/theme/shared/tsconfig.json +32 -0
  47. package/dist/templates/theme/ts/react/eslint.config.ts +29 -0
  48. package/dist/templates/theme/ts/react/src/app.tsx +26 -0
  49. package/dist/templates/theme/ts/react/src/components/Onboarding.tsx +83 -0
  50. package/dist/templates/theme/ts/vanilla/eslint.config.ts +16 -0
  51. package/dist/templates/theme/ts/vanilla/src/app.ts +11 -0
  52. package/dist/templates/theme/ts/vanilla/src/components/Onboarding.ts +79 -0
  53. package/dist/templates/wrapper.js +48 -0
  54. package/package.json +80 -0
  55. package/templates/extension/js/react/eslint.config.js +29 -0
  56. package/templates/extension/js/react/src/app.jsx +27 -0
  57. package/templates/extension/js/react/src/components/Onboarding.jsx +72 -0
  58. package/templates/extension/js/vanilla/components/Onboarding.js +71 -0
  59. package/templates/extension/js/vanilla/eslint.config.js +16 -0
  60. package/templates/extension/js/vanilla/src/app.js +12 -0
  61. package/templates/extension/meta.json +4 -0
  62. package/templates/extension/shared/.oxlintrc.json +36 -0
  63. package/templates/extension/shared/README.template.md +53 -0
  64. package/templates/extension/shared/app.css +163 -0
  65. package/templates/extension/shared/biome.json +36 -0
  66. package/templates/extension/shared/css.d.ts +44 -0
  67. package/templates/extension/shared/jsconfig.json +32 -0
  68. package/templates/extension/shared/spice.config.js +9 -0
  69. package/templates/extension/shared/spice.config.ts +9 -0
  70. package/templates/extension/shared/tsconfig.json +32 -0
  71. package/templates/extension/ts/react/eslint.config.ts +29 -0
  72. package/templates/extension/ts/react/src/app.tsx +27 -0
  73. package/templates/extension/ts/react/src/components/Onboarding.tsx +83 -0
  74. package/templates/extension/ts/vanilla/biome.json +36 -0
  75. package/templates/extension/ts/vanilla/eslint.config.ts +16 -0
  76. package/templates/extension/ts/vanilla/src/app.ts +12 -0
  77. package/templates/extension/ts/vanilla/src/components/Onboarding.ts +79 -0
  78. package/templates/liveReload.js +70 -0
  79. package/templates/theme/js/react/eslint.config.js +29 -0
  80. package/templates/theme/js/react/src/app.jsx +25 -0
  81. package/templates/theme/js/react/src/components/Onboarding.jsx +72 -0
  82. package/templates/theme/js/vanilla/eslint.config.js +16 -0
  83. package/templates/theme/js/vanilla/src/app.js +11 -0
  84. package/templates/theme/js/vanilla/src/components/Onboarding.js +71 -0
  85. package/templates/theme/meta.json +4 -0
  86. package/templates/theme/shared/.oxlintrc.json +36 -0
  87. package/templates/theme/shared/README.template.md +53 -0
  88. package/templates/theme/shared/app.css +163 -0
  89. package/templates/theme/shared/biome.json +36 -0
  90. package/templates/theme/shared/css.d.ts +44 -0
  91. package/templates/theme/shared/jsconfig.json +31 -0
  92. package/templates/theme/shared/spice.config.js +9 -0
  93. package/templates/theme/shared/spice.config.ts +9 -0
  94. package/templates/theme/shared/tsconfig.json +32 -0
  95. package/templates/theme/ts/react/eslint.config.ts +29 -0
  96. package/templates/theme/ts/react/src/app.tsx +26 -0
  97. package/templates/theme/ts/react/src/components/Onboarding.tsx +83 -0
  98. package/templates/theme/ts/vanilla/eslint.config.ts +16 -0
  99. package/templates/theme/ts/vanilla/src/app.ts +11 -0
  100. package/templates/theme/ts/vanilla/src/components/Onboarding.ts +79 -0
  101. package/templates/wrapper.js +48 -0
@@ -0,0 +1,2175 @@
1
+ import * as v from "valibot";
2
+ import { BuildOptions } from "esbuild";
3
+
4
+ //#region src/utils/package-manager.d.ts
5
+ type PackageManagerType = "npm" | "pnpm" | "yarn" | "bun";
6
+ //#endregion
7
+ //#region src/config/schema.d.ts
8
+ type EsBuildOmited = "bundle" | "entryPoints";
9
+ type ESBuildOptions = Omit<BuildOptions, EsBuildOmited>;
10
+ declare const FileOptionsSchema: v.IntersectSchema<[Omit<v.ObjectSchema<{
11
+ readonly name: v.StringSchema<undefined>;
12
+ readonly outDir: v.StringSchema<undefined>;
13
+ readonly linter: v.PicklistSchema<readonly ["biome", "eslint", "oxlint", "none"], undefined>;
14
+ readonly framework: v.PicklistSchema<readonly ["react", "vanilla"], undefined>;
15
+ readonly packageManager: v.PicklistSchema<PackageManagerType[], undefined>;
16
+ readonly esbuildOptions: v.GenericSchema<ESBuildOptions>;
17
+ readonly serverConfig: Omit<v.ObjectSchema<{
18
+ readonly port: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
19
+ readonly serveDir: v.StringSchema<undefined>;
20
+ readonly hmrPath: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
21
+ }, undefined>, "~types" | "~run" | "~standard" | "entries"> & {
22
+ readonly entries: {
23
+ readonly port: v.OptionalSchema<v.OptionalSchema<v.NumberSchema<undefined>, undefined>, undefined>;
24
+ readonly serveDir: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
25
+ readonly hmrPath: v.OptionalSchema<v.OptionalSchema<v.StringSchema<undefined>, undefined>, undefined>;
26
+ };
27
+ readonly "~standard": v.StandardProps<{
28
+ port?: number | undefined;
29
+ serveDir?: string | undefined;
30
+ hmrPath?: string | undefined;
31
+ }, {
32
+ port?: number | undefined;
33
+ serveDir?: string | undefined;
34
+ hmrPath?: string | undefined;
35
+ }>;
36
+ readonly "~run": (dataset: v.UnknownDataset, config: v.Config<v.BaseIssue<unknown>>) => v.OutputDataset<{
37
+ port?: number | undefined;
38
+ serveDir?: string | undefined;
39
+ hmrPath?: string | undefined;
40
+ }, v.NumberIssue | v.StringIssue | v.ObjectIssue>;
41
+ readonly "~types"?: {
42
+ readonly input: {
43
+ port?: number | undefined;
44
+ serveDir?: string | undefined;
45
+ hmrPath?: string | undefined;
46
+ };
47
+ readonly output: {
48
+ port?: number | undefined;
49
+ serveDir?: string | undefined;
50
+ hmrPath?: string | undefined;
51
+ };
52
+ readonly issue: v.NumberIssue | v.StringIssue | v.ObjectIssue;
53
+ } | undefined;
54
+ };
55
+ readonly version: v.StringSchema<undefined>;
56
+ }, undefined>, "~types" | "~run" | "~standard" | "entries"> & {
57
+ readonly entries: {
58
+ readonly name: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
59
+ readonly outDir: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
60
+ readonly linter: v.OptionalSchema<v.PicklistSchema<readonly ["biome", "eslint", "oxlint", "none"], undefined>, undefined>;
61
+ readonly framework: v.OptionalSchema<v.PicklistSchema<readonly ["react", "vanilla"], undefined>, undefined>;
62
+ readonly packageManager: v.OptionalSchema<v.PicklistSchema<PackageManagerType[], undefined>, undefined>;
63
+ readonly esbuildOptions: v.OptionalSchema<v.GenericSchema<ESBuildOptions>, undefined>;
64
+ readonly serverConfig: v.OptionalSchema<Omit<v.ObjectSchema<{
65
+ readonly port: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
66
+ readonly serveDir: v.StringSchema<undefined>;
67
+ readonly hmrPath: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
68
+ }, undefined>, "~types" | "~run" | "~standard" | "entries"> & {
69
+ readonly entries: {
70
+ readonly port: v.OptionalSchema<v.OptionalSchema<v.NumberSchema<undefined>, undefined>, undefined>;
71
+ readonly serveDir: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
72
+ readonly hmrPath: v.OptionalSchema<v.OptionalSchema<v.StringSchema<undefined>, undefined>, undefined>;
73
+ };
74
+ readonly "~standard": v.StandardProps<{
75
+ port?: number | undefined;
76
+ serveDir?: string | undefined;
77
+ hmrPath?: string | undefined;
78
+ }, {
79
+ port?: number | undefined;
80
+ serveDir?: string | undefined;
81
+ hmrPath?: string | undefined;
82
+ }>;
83
+ readonly "~run": (dataset: v.UnknownDataset, config: v.Config<v.BaseIssue<unknown>>) => v.OutputDataset<{
84
+ port?: number | undefined;
85
+ serveDir?: string | undefined;
86
+ hmrPath?: string | undefined;
87
+ }, v.NumberIssue | v.StringIssue | v.ObjectIssue>;
88
+ readonly "~types"?: {
89
+ readonly input: {
90
+ port?: number | undefined;
91
+ serveDir?: string | undefined;
92
+ hmrPath?: string | undefined;
93
+ };
94
+ readonly output: {
95
+ port?: number | undefined;
96
+ serveDir?: string | undefined;
97
+ hmrPath?: string | undefined;
98
+ };
99
+ readonly issue: v.NumberIssue | v.StringIssue | v.ObjectIssue;
100
+ } | undefined;
101
+ }, undefined>;
102
+ readonly version: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
103
+ };
104
+ readonly "~standard": v.StandardProps<{
105
+ name?: string | undefined;
106
+ outDir?: string | undefined;
107
+ linter?: "biome" | "eslint" | "oxlint" | "none" | undefined;
108
+ framework?: "react" | "vanilla" | undefined;
109
+ packageManager?: PackageManagerType | undefined;
110
+ esbuildOptions?: ESBuildOptions | undefined;
111
+ serverConfig?: {
112
+ port?: number | undefined;
113
+ serveDir?: string | undefined;
114
+ hmrPath?: string | undefined;
115
+ } | undefined;
116
+ version?: string | undefined;
117
+ }, {
118
+ name?: string | undefined;
119
+ outDir?: string | undefined;
120
+ linter?: "biome" | "eslint" | "oxlint" | "none" | undefined;
121
+ framework?: "react" | "vanilla" | undefined;
122
+ packageManager?: PackageManagerType | undefined;
123
+ esbuildOptions?: ESBuildOptions | undefined;
124
+ serverConfig?: {
125
+ port?: number | undefined;
126
+ serveDir?: string | undefined;
127
+ hmrPath?: string | undefined;
128
+ } | undefined;
129
+ version?: string | undefined;
130
+ }>;
131
+ readonly "~run": (dataset: v.UnknownDataset, config: v.Config<v.BaseIssue<unknown>>) => v.OutputDataset<{
132
+ name?: string | undefined;
133
+ outDir?: string | undefined;
134
+ linter?: "biome" | "eslint" | "oxlint" | "none" | undefined;
135
+ framework?: "react" | "vanilla" | undefined;
136
+ packageManager?: PackageManagerType | undefined;
137
+ esbuildOptions?: ESBuildOptions | undefined;
138
+ serverConfig?: {
139
+ port?: number | undefined;
140
+ serveDir?: string | undefined;
141
+ hmrPath?: string | undefined;
142
+ } | undefined;
143
+ version?: string | undefined;
144
+ }, v.BaseIssue<unknown> | v.NumberIssue | v.StringIssue | v.ObjectIssue | v.PicklistIssue>;
145
+ readonly "~types"?: {
146
+ readonly input: {
147
+ name?: string | undefined;
148
+ outDir?: string | undefined;
149
+ linter?: "biome" | "eslint" | "oxlint" | "none" | undefined;
150
+ framework?: "react" | "vanilla" | undefined;
151
+ packageManager?: PackageManagerType | undefined;
152
+ esbuildOptions?: ESBuildOptions | undefined;
153
+ serverConfig?: {
154
+ port?: number | undefined;
155
+ serveDir?: string | undefined;
156
+ hmrPath?: string | undefined;
157
+ } | undefined;
158
+ version?: string | undefined;
159
+ };
160
+ readonly output: {
161
+ name?: string | undefined;
162
+ outDir?: string | undefined;
163
+ linter?: "biome" | "eslint" | "oxlint" | "none" | undefined;
164
+ framework?: "react" | "vanilla" | undefined;
165
+ packageManager?: PackageManagerType | undefined;
166
+ esbuildOptions?: ESBuildOptions | undefined;
167
+ serverConfig?: {
168
+ port?: number | undefined;
169
+ serveDir?: string | undefined;
170
+ hmrPath?: string | undefined;
171
+ } | undefined;
172
+ version?: string | undefined;
173
+ };
174
+ readonly issue: v.BaseIssue<unknown> | v.NumberIssue | v.StringIssue | v.ObjectIssue | v.PicklistIssue;
175
+ } | undefined;
176
+ }, v.VariantSchema<"template", [Omit<v.ObjectSchema<{
177
+ readonly template: v.LiteralSchema<"extension", undefined>;
178
+ readonly entry: v.StringSchema<undefined>;
179
+ }, undefined>, "~types" | "~run" | "~standard" | "entries"> & {
180
+ readonly entries: {
181
+ readonly template: v.OptionalSchema<v.LiteralSchema<"extension", undefined>, undefined>;
182
+ readonly entry: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
183
+ };
184
+ readonly "~standard": v.StandardProps<{
185
+ template?: "extension" | undefined;
186
+ entry?: string | undefined;
187
+ }, {
188
+ template?: "extension" | undefined;
189
+ entry?: string | undefined;
190
+ }>;
191
+ readonly "~run": (dataset: v.UnknownDataset, config: v.Config<v.BaseIssue<unknown>>) => v.OutputDataset<{
192
+ template?: "extension" | undefined;
193
+ entry?: string | undefined;
194
+ }, v.StringIssue | v.ObjectIssue | v.LiteralIssue>;
195
+ readonly "~types"?: {
196
+ readonly input: {
197
+ template?: "extension" | undefined;
198
+ entry?: string | undefined;
199
+ };
200
+ readonly output: {
201
+ template?: "extension" | undefined;
202
+ entry?: string | undefined;
203
+ };
204
+ readonly issue: v.StringIssue | v.ObjectIssue | v.LiteralIssue;
205
+ } | undefined;
206
+ }, Omit<v.ObjectSchema<{
207
+ readonly template: v.LiteralSchema<"theme", undefined>;
208
+ readonly entry: v.ObjectSchema<{
209
+ readonly js: v.StringSchema<undefined>;
210
+ readonly css: v.StringSchema<undefined>;
211
+ }, undefined>;
212
+ }, undefined>, "~types" | "~run" | "~standard" | "entries"> & {
213
+ readonly entries: {
214
+ readonly template: v.OptionalSchema<v.LiteralSchema<"theme", undefined>, undefined>;
215
+ readonly entry: v.OptionalSchema<v.ObjectSchema<{
216
+ readonly js: v.StringSchema<undefined>;
217
+ readonly css: v.StringSchema<undefined>;
218
+ }, undefined>, undefined>;
219
+ };
220
+ readonly "~standard": v.StandardProps<{
221
+ template?: "theme" | undefined;
222
+ entry?: {
223
+ js: string;
224
+ css: string;
225
+ } | undefined;
226
+ }, {
227
+ template?: "theme" | undefined;
228
+ entry?: {
229
+ js: string;
230
+ css: string;
231
+ } | undefined;
232
+ }>;
233
+ readonly "~run": (dataset: v.UnknownDataset, config: v.Config<v.BaseIssue<unknown>>) => v.OutputDataset<{
234
+ template?: "theme" | undefined;
235
+ entry?: {
236
+ js: string;
237
+ css: string;
238
+ } | undefined;
239
+ }, v.StringIssue | v.ObjectIssue | v.LiteralIssue>;
240
+ readonly "~types"?: {
241
+ readonly input: {
242
+ template?: "theme" | undefined;
243
+ entry?: {
244
+ js: string;
245
+ css: string;
246
+ } | undefined;
247
+ };
248
+ readonly output: {
249
+ template?: "theme" | undefined;
250
+ entry?: {
251
+ js: string;
252
+ css: string;
253
+ } | undefined;
254
+ };
255
+ readonly issue: v.StringIssue | v.ObjectIssue | v.LiteralIssue;
256
+ } | undefined;
257
+ }], undefined>], undefined>;
258
+ type FileConfig = v.InferOutput<typeof FileOptionsSchema>;
259
+ //#endregion
260
+ //#region src/client/types/spicetify.d.ts
261
+ declare namespace _Spicetify {
262
+ type Icon = "album" | "artist" | "block" | "brightness" | "car" | "chart-down" | "chart-up" | "check" | "check-alt-fill" | "chevron-left" | "chevron-right" | "chromecast-disconnected" | "clock" | "collaborative" | "computer" | "copy" | "download" | "downloaded" | "edit" | "enhance" | "exclamation-circle" | "external-link" | "facebook" | "follow" | "fullscreen" | "gamepad" | "grid-view" | "heart" | "heart-active" | "instagram" | "laptop" | "library" | "list-view" | "location" | "locked" | "locked-active" | "lyrics" | "menu" | "minimize" | "minus" | "more" | "new-spotify-connect" | "offline" | "pause" | "phone" | "play" | "playlist" | "playlist-folder" | "plus-alt" | "plus2px" | "podcasts" | "projector" | "queue" | "repeat" | "repeat-once" | "search" | "search-active" | "shuffle" | "skip-back" | "skip-back15" | "skip-forward" | "skip-forward15" | "soundbetter" | "speaker" | "spotify" | "subtitles" | "tablet" | "ticket" | "twitter" | "visualizer" | "voice" | "volume" | "volume-off" | "volume-one-wave" | "volume-two-wave" | "watch" | "x";
263
+ type Variant = "bass" | "forte" | "brio" | "altoBrio" | "alto" | "canon" | "celloCanon" | "cello" | "ballad" | "balladBold" | "viola" | "violaBold" | "mesto" | "mestoBold" | "metronome" | "finale" | "finaleBold" | "minuet" | "minuetBold";
264
+ type SemanticColor = "textBase" | "textSubdued" | "textBrightAccent" | "textNegative" | "textWarning" | "textPositive" | "textAnnouncement" | "essentialBase" | "essentialSubdued" | "essentialBrightAccent" | "essentialNegative" | "essentialWarning" | "essentialPositive" | "essentialAnnouncement" | "decorativeBase" | "decorativeSubdued" | "backgroundBase" | "backgroundHighlight" | "backgroundPress" | "backgroundElevatedBase" | "backgroundElevatedHighlight" | "backgroundElevatedPress" | "backgroundTintedBase" | "backgroundTintedHighlight" | "backgroundTintedPress" | "backgroundUnsafeForSmallTextBase" | "backgroundUnsafeForSmallTextHighlight" | "backgroundUnsafeForSmallTextPress";
265
+ type ColorSet = "base" | "brightAccent" | "negative" | "warning" | "positive" | "announcement" | "invertedDark" | "invertedLight" | "mutedAccent" | "overMedia";
266
+ type ColorSetBackgroundColors = {
267
+ base: string;
268
+ highlight: string;
269
+ press: string;
270
+ };
271
+ type ColorSetNamespaceColors = {
272
+ announcement: string;
273
+ base: string;
274
+ brightAccent: string;
275
+ negative: string;
276
+ positive: string;
277
+ subdued: string;
278
+ warning: string;
279
+ };
280
+ type ColorSetBody = {
281
+ background: ColorSetBackgroundColors & {
282
+ elevated: ColorSetBackgroundColors;
283
+ tinted: ColorSetBackgroundColors;
284
+ unsafeForSmallText: ColorSetBackgroundColors;
285
+ };
286
+ decorative: {
287
+ base: string;
288
+ subdued: string;
289
+ };
290
+ essential: ColorSetNamespaceColors;
291
+ text: ColorSetNamespaceColors;
292
+ };
293
+ type Metadata = Partial<Record<string, string>>;
294
+ type ContextTrack = {
295
+ uri: string;
296
+ uid?: string;
297
+ metadata?: Metadata;
298
+ };
299
+ type PlayerState = {
300
+ timestamp: number;
301
+ context: PlayerContext;
302
+ index: PlayerIndex;
303
+ item: PlayerTrack;
304
+ shuffle: boolean;
305
+ repeat: number;
306
+ speed: number;
307
+ positionAsOfTimestamp: number;
308
+ duration: number;
309
+ hasContext: boolean;
310
+ isPaused: boolean;
311
+ isBuffering: boolean;
312
+ restrictions: Restrictions;
313
+ previousItems?: PlayerTrack[];
314
+ nextItems?: PlayerTrack[];
315
+ playbackQuality: PlaybackQuality;
316
+ playbackId: string;
317
+ sessionId: string;
318
+ signals?: any[];
319
+ };
320
+ type PlayerContext = {
321
+ uri: string;
322
+ url: string;
323
+ metadata: {
324
+ "player.arch": string;
325
+ };
326
+ };
327
+ type PlayerIndex = {
328
+ pageURI?: string | null;
329
+ pageIndex: number;
330
+ itemIndex: number;
331
+ };
332
+ type PlayerTrack = {
333
+ type: string;
334
+ uri: string;
335
+ uid: string;
336
+ name: string;
337
+ mediaType: string;
338
+ duration: {
339
+ milliseconds: number;
340
+ };
341
+ album: Album;
342
+ artists?: ArtistsEntity[];
343
+ isLocal: boolean;
344
+ isExplicit: boolean;
345
+ is19PlusOnly: boolean;
346
+ provider: string;
347
+ metadata: TrackMetadata;
348
+ images?: ImagesEntity[];
349
+ };
350
+ type TrackMetadata = {
351
+ artist_uri: string;
352
+ entity_uri: string;
353
+ iteration: string;
354
+ title: string;
355
+ "collection.is_banned": string;
356
+ "artist_uri:1": string;
357
+ "collection.in_collection": string;
358
+ image_small_url: string;
359
+ "collection.can_ban": string;
360
+ is_explicit: string;
361
+ album_disc_number: string;
362
+ album_disc_count: string;
363
+ track_player: string;
364
+ album_title: string;
365
+ "collection.can_add": string;
366
+ image_large_url: string;
367
+ "actions.skipping_prev_past_track": string;
368
+ page_instance_id: string;
369
+ image_xlarge_url: string;
370
+ marked_for_download: string;
371
+ "actions.skipping_next_past_track": string;
372
+ context_uri: string;
373
+ "artist_name:1": string;
374
+ has_lyrics: string;
375
+ interaction_id: string;
376
+ image_url: string;
377
+ album_uri: string;
378
+ album_artist_name: string;
379
+ album_track_number: string;
380
+ artist_name: string;
381
+ duration: string;
382
+ album_track_count: string;
383
+ popularity: string;
384
+ };
385
+ type Album = {
386
+ type: string;
387
+ uri: string;
388
+ name: string;
389
+ images?: ImagesEntity[];
390
+ };
391
+ type ImagesEntity = {
392
+ url: string;
393
+ label: string;
394
+ };
395
+ type ArtistsEntity = {
396
+ type: string;
397
+ uri: string;
398
+ name: string;
399
+ };
400
+ type Restrictions = {
401
+ canPause: boolean;
402
+ canResume: boolean;
403
+ canSeek: boolean;
404
+ canSkipPrevious: boolean;
405
+ canSkipNext: boolean;
406
+ canToggleRepeatContext: boolean;
407
+ canToggleRepeatTrack: boolean;
408
+ canToggleShuffle: boolean;
409
+ disallowPausingReasons?: string[];
410
+ disallowResumingReasons?: string[];
411
+ disallowSeekingReasons?: string[];
412
+ disallowSkippingPreviousReasons?: string[];
413
+ disallowSkippingNextReasons?: string[];
414
+ disallowTogglingRepeatContextReasons?: string[];
415
+ disallowTogglingRepeatTrackReasons?: string[];
416
+ disallowTogglingShuffleReasons?: string[];
417
+ disallowTransferringPlaybackReasons?: string[];
418
+ };
419
+ type PlaybackQuality = {
420
+ bitrateLevel: number;
421
+ strategy: number;
422
+ targetBitrateLevel: number;
423
+ targetBitrateAvailable: boolean;
424
+ hifiStatus: number;
425
+ };
426
+ namespace Player {
427
+ /**
428
+ * Register a listener `type` on Spicetify.Player.
429
+ *
430
+ * On default, `Spicetify.Player` always dispatch:
431
+ * - `songchange` type when player changes track.
432
+ * - `onplaypause` type when player plays or pauses.
433
+ * - `onprogress` type when track progress changes.
434
+ * - `appchange` type when user changes page.
435
+ */
436
+ function addEventListener(type: string, callback: (event?: Event) => void): void;
437
+ function addEventListener(type: "songchange", callback: (event?: Event & {
438
+ data: PlayerState;
439
+ }) => void): void;
440
+ function addEventListener(type: "onplaypause", callback: (event?: Event & {
441
+ data: PlayerState;
442
+ }) => void): void;
443
+ function addEventListener(type: "onprogress", callback: (event?: Event & {
444
+ data: number;
445
+ }) => void): void;
446
+ function addEventListener(type: "appchange", callback: (event?: Event & {
447
+ data: {
448
+ /**
449
+ * App href path
450
+ */
451
+ path: string;
452
+ /**
453
+ * App container
454
+ */
455
+ container: HTMLElement;
456
+ };
457
+ }) => void): void;
458
+ /**
459
+ * Skip to previous track.
460
+ */
461
+ function back(): void;
462
+ /**
463
+ * An object contains all information about current track and player.
464
+ */
465
+ const data: PlayerState;
466
+ /**
467
+ * Decrease a small amount of volume.
468
+ */
469
+ function decreaseVolume(): void;
470
+ /**
471
+ * Dispatches an event at `Spicetify.Player`.
472
+ *
473
+ * On default, `Spicetify.Player` always dispatch
474
+ * - `songchange` type when player changes track.
475
+ * - `onplaypause` type when player plays or pauses.
476
+ * - `onprogress` type when track progress changes.
477
+ * - `appchange` type when user changes page.
478
+ */
479
+ function dispatchEvent(event: Event): void;
480
+ const eventListeners: {
481
+ [key: string]: Array<(event?: Event) => void>;
482
+ };
483
+ /**
484
+ * Convert milisecond to `mm:ss` format
485
+ * @param milisecond
486
+ */
487
+ function formatTime(milisecond: number): string;
488
+ /**
489
+ * Return song total duration in milisecond.
490
+ */
491
+ function getDuration(): number;
492
+ /**
493
+ * Return mute state
494
+ */
495
+ function getMute(): boolean;
496
+ /**
497
+ * Return elapsed duration in milisecond.
498
+ */
499
+ function getProgress(): number;
500
+ /**
501
+ * Return elapsed duration in percentage (0 to 1).
502
+ */
503
+ function getProgressPercent(): number;
504
+ /**
505
+ * Return current Repeat state (No repeat = 0/Repeat all = 1/Repeat one = 2).
506
+ */
507
+ function getRepeat(): number;
508
+ /**
509
+ * Return current shuffle state.
510
+ */
511
+ function getShuffle(): boolean;
512
+ /**
513
+ * Return track heart state.
514
+ */
515
+ function getHeart(): boolean;
516
+ /**
517
+ * Return current volume level (0 to 1).
518
+ */
519
+ function getVolume(): number;
520
+ /**
521
+ * Increase a small amount of volume.
522
+ */
523
+ function increaseVolume(): void;
524
+ /**
525
+ * Return a boolean whether player is playing.
526
+ */
527
+ function isPlaying(): boolean;
528
+ /**
529
+ * Skip to next track.
530
+ */
531
+ function next(): void;
532
+ /**
533
+ * Pause track.
534
+ */
535
+ function pause(): void;
536
+ /**
537
+ * Resume track.
538
+ */
539
+ function play(): void;
540
+ /**
541
+ * Play a track, playlist, album, etc. immediately
542
+ * @param uri Spotify URI
543
+ * @param context
544
+ * @param options
545
+ */
546
+ function playUri(uri: string, context?: any, options?: any): Promise<void>;
547
+ /**
548
+ * Unregister added event listener `type`.
549
+ * @param type
550
+ * @param callback
551
+ */
552
+ function removeEventListener(type: string, callback: (event?: Event) => void): void;
553
+ /**
554
+ * Seek track to position.
555
+ * @param position can be in percentage (0 to 1) or in milisecond.
556
+ */
557
+ function seek(position: number): void;
558
+ /**
559
+ * Turn mute on/off
560
+ * @param state
561
+ */
562
+ function setMute(state: boolean): void;
563
+ /**
564
+ * Change Repeat mode
565
+ * @param mode `0` No repeat. `1` Repeat all. `2` Repeat one track.
566
+ */
567
+ function setRepeat(mode: number): void;
568
+ /**
569
+ * Turn shuffle on/off.
570
+ * @param state
571
+ */
572
+ function setShuffle(state: boolean): void;
573
+ /**
574
+ * Set volume level
575
+ * @param level 0 to 1
576
+ */
577
+ function setVolume(level: number): void;
578
+ /**
579
+ * Seek to previous `amount` of milisecond
580
+ * @param amount in milisecond. Default: 15000.
581
+ */
582
+ function skipBack(amount?: number): void;
583
+ /**
584
+ * Seek to next `amount` of milisecond
585
+ * @param amount in milisecond. Default: 15000.
586
+ */
587
+ function skipForward(amount?: number): void;
588
+ /**
589
+ * Set Heart on/off (Favourite) track state.
590
+ * @param state
591
+ */
592
+ function setHeart(state: boolean): void;
593
+ /**
594
+ * Toggle Heart (Favourite) track state.
595
+ */
596
+ function toggleHeart(): void;
597
+ /**
598
+ * Toggle Mute/No mute.
599
+ */
600
+ function toggleMute(): void;
601
+ /**
602
+ * Toggle Play/Pause.
603
+ */
604
+ function togglePlay(): void;
605
+ /**
606
+ * Toggle No repeat/Repeat all/Repeat one.
607
+ */
608
+ function toggleRepeat(): void;
609
+ /**
610
+ * Toggle Shuffle/No shuffle.
611
+ */
612
+ function toggleShuffle(): void;
613
+ /**
614
+ * Internal player state variables.
615
+ */
616
+ const origin: any;
617
+ }
618
+ /**
619
+ * Adds a track or array of tracks to prioritized queue.
620
+ */
621
+ function addToQueue(uri: ContextTrack[]): Promise<void>;
622
+ /**
623
+ * @deprecated
624
+ */
625
+ const BridgeAPI: any;
626
+ /**
627
+ * @deprecated
628
+ */
629
+ const CosmosAPI: any;
630
+ /**
631
+ * Async wrappers of CosmosAPI
632
+ */
633
+ namespace CosmosAsync {
634
+ type Method = "DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT" | "SUB";
635
+ interface Error {
636
+ code: number;
637
+ error: string;
638
+ message: string;
639
+ stack?: string;
640
+ }
641
+ type Headers = Record<string, string>;
642
+ type Body = Record<string, any>;
643
+ interface Response {
644
+ body: any;
645
+ headers: Headers;
646
+ status: number;
647
+ uri?: string;
648
+ }
649
+ function head(url: string, headers?: Headers): Promise<Headers>;
650
+ function get(url: string, body?: Body, headers?: Headers): Promise<Response["body"]>;
651
+ function post(url: string, body?: Body, headers?: Headers): Promise<Response["body"]>;
652
+ function put(url: string, body?: Body, headers?: Headers): Promise<Response["body"]>;
653
+ function del(url: string, body?: Body, headers?: Headers): Promise<Response["body"]>;
654
+ function patch(url: string, body?: Body, headers?: Headers): Promise<Response["body"]>;
655
+ function sub(url: string, callback: (b: Response["body"]) => void, onError?: (e: Error) => void, body?: Body, headers?: Headers): Promise<Response["body"]>;
656
+ function postSub(url: string, body: Body | null, callback: (b: Response["body"]) => void, onError?: (e: Error) => void): Promise<Response["body"]>;
657
+ function request(method: Method, url: string, body?: Body, headers?: Headers): Promise<Response>;
658
+ function resolve(method: Method, url: string, body?: Body, headers?: Headers): Promise<Response>;
659
+ }
660
+ /**
661
+ * Fetch interesting colors from URI.
662
+ * @param uri Any type of URI that has artwork (playlist, track, album, artist, show, ...)
663
+ */
664
+ function colorExtractor(uri: string): Promise<{
665
+ DARK_VIBRANT: string;
666
+ DESATURATED: string;
667
+ LIGHT_VIBRANT: string;
668
+ PROMINENT: string;
669
+ VIBRANT: string;
670
+ VIBRANT_NON_ALARMING: string;
671
+ }>;
672
+ /**
673
+ * @deprecated
674
+ */
675
+ function getAblumArtColors(): any;
676
+ /**
677
+ * Fetch track analyzed audio data.
678
+ * Beware, not all tracks have audio data.
679
+ * @param uri is optional. Leave it blank to get current track
680
+ * or specify another track uri.
681
+ */
682
+ function getAudioData(uri?: string): Promise<any>;
683
+ /**
684
+ * Set of APIs method to register, deregister hotkeys/shortcuts
685
+ */
686
+ namespace Keyboard {
687
+ type ValidKey = "BACKSPACE" | "TAB" | "ENTER" | "SHIFT" | "CTRL" | "ALT" | "CAPS" | "ESCAPE" | "SPACE" | "PAGE_UP" | "PAGE_DOWN" | "END" | "HOME" | "ARROW_LEFT" | "ARROW_UP" | "ARROW_RIGHT" | "ARROW_DOWN" | "INSERT" | "DELETE" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "WINDOW_LEFT" | "WINDOW_RIGHT" | "SELECT" | "NUMPAD_0" | "NUMPAD_1" | "NUMPAD_2" | "NUMPAD_3" | "NUMPAD_4" | "NUMPAD_5" | "NUMPAD_6" | "NUMPAD_7" | "NUMPAD_8" | "NUMPAD_9" | "MULTIPLY" | "ADD" | "SUBTRACT" | "DECIMAL_POINT" | "DIVIDE" | "F1" | "F2" | "F3" | "F4" | "F5" | "F6" | "F7" | "F8" | "F9" | "F10" | "F11" | "F12" | ";" | "=" | " | " | "-" | "." | "/" | "`" | "[" | "\\" | "]" | '"' | "~" | "!" | "@" | "#" | "$" | "%" | "^" | "&" | "*" | "(" | ")" | "_" | "+" | ":" | "<" | ">" | "?" | "|";
688
+ type KeysDefine = string | {
689
+ key: string;
690
+ ctrl?: boolean;
691
+ shift?: boolean;
692
+ alt?: boolean;
693
+ meta?: boolean;
694
+ };
695
+ const KEYS: Record<ValidKey, string>;
696
+ function registerShortcut(keys: KeysDefine, callback: (event: KeyboardEvent) => void): void;
697
+ function registerIsolatedShortcut(keys: KeysDefine, callback: (event: KeyboardEvent) => void): void;
698
+ function registerImportantShortcut(keys: KeysDefine, callback: (event: KeyboardEvent) => void): void;
699
+ function _deregisterShortcut(keys: KeysDefine): void;
700
+ function deregisterImportantShortcut(keys: KeysDefine): void;
701
+ function changeShortcut(keys: KeysDefine, newKeys: KeysDefine): void;
702
+ }
703
+ /**
704
+ * @deprecated
705
+ */
706
+ const LiveAPI: any;
707
+ namespace LocalStorage {
708
+ /**
709
+ * Empties the list associated with the object of all key/value pairs, if there are any.
710
+ */
711
+ function clear(): void;
712
+ /**
713
+ * Get key value
714
+ */
715
+ function get(key: string): string | null;
716
+ /**
717
+ * Delete key
718
+ */
719
+ function remove(key: string): void;
720
+ /**
721
+ * Set new value for key
722
+ */
723
+ function set(key: string, value: string): void;
724
+ }
725
+ /**
726
+ * To create and prepend custom menu item in profile menu.
727
+ */
728
+ namespace Menu {
729
+ /**
730
+ * Create a single toggle.
731
+ */
732
+ class Item {
733
+ constructor(name: string, isEnabled: boolean, onClick: (self: Item) => void, icon?: Icon | string);
734
+ name: string;
735
+ isEnabled: boolean;
736
+ /**
737
+ * Change item name
738
+ */
739
+ setName(name: string): void;
740
+ /**
741
+ * Change item enabled state.
742
+ * Visually, item would has a tick next to it if its state is enabled.
743
+ */
744
+ setState(isEnabled: boolean): void;
745
+ /**
746
+ * Change icon
747
+ */
748
+ setIcon(icon: Icon | string): void;
749
+ /**
750
+ * Item is only available in Profile menu when method "register" is called.
751
+ */
752
+ register(): void;
753
+ /**
754
+ * Stop item to be prepended into Profile menu.
755
+ */
756
+ deregister(): void;
757
+ }
758
+ /**
759
+ * Create a sub menu to contain Item toggles.
760
+ * `Item`s in `subItems` array shouldn't be registered.
761
+ */
762
+ class SubMenu {
763
+ constructor(name: string, subItems: Item[]);
764
+ name: string;
765
+ /**
766
+ * Change SubMenu name
767
+ */
768
+ setName(name: string): void;
769
+ /**
770
+ * Add an item to sub items list
771
+ */
772
+ addItem(item: Item): void;
773
+ /**
774
+ * Remove an item from sub items list
775
+ */
776
+ removeItem(item: Item): void;
777
+ /**
778
+ * SubMenu is only available in Profile menu when method "register" is called.
779
+ */
780
+ register(): void;
781
+ /**
782
+ * Stop SubMenu to be prepended into Profile menu.
783
+ */
784
+ deregister(): void;
785
+ }
786
+ }
787
+ /**
788
+ * Keyboard shortcut library
789
+ *
790
+ * Documentation: https://craig.is/killing/mice v1.6.5
791
+ *
792
+ * Spicetify.Keyboard is wrapper of this library to be compatible with legacy Spotify,
793
+ * so new extension should use this library instead.
794
+ */
795
+ function Mousetrap(element?: any): void;
796
+ /**
797
+ * Contains vast array of internal APIs.
798
+ * Please explore in Devtool Console.
799
+ */
800
+ const Platform: any;
801
+ /**
802
+ * Queue object contains list of queuing tracks,
803
+ * history of played tracks and current track metadata.
804
+ */
805
+ const Queue: {
806
+ nextTracks: any[];
807
+ prevTracks: any[];
808
+ queueRevision: string;
809
+ track: any;
810
+ };
811
+ /**
812
+ * Remove a track or array of tracks from current queue.
813
+ */
814
+ function removeFromQueue(uri: ContextTrack[]): Promise<void>;
815
+ /**
816
+ * Display a bubble of notification. Useful for a visual feedback.
817
+ * @param message Message to display. Can use inline HTML for styling.
818
+ * @param isError If true, bubble will be red. Defaults to false.
819
+ * @param msTimeout Time in milliseconds to display the bubble. Defaults to Spotify's value.
820
+ */
821
+ function showNotification(message: React.ReactNode, isError?: boolean, msTimeout?: number): void;
822
+ /**
823
+ * Set of APIs method to parse and validate URIs.
824
+ */
825
+ class URI {
826
+ constructor(type: string, props: any);
827
+ type: string;
828
+ hasBase62Id: boolean;
829
+ id?: string;
830
+ disc?: any;
831
+ args?: any;
832
+ category?: string;
833
+ username?: string;
834
+ track?: string;
835
+ artist?: string;
836
+ album?: string;
837
+ duration?: number;
838
+ query?: string;
839
+ country?: string;
840
+ global?: boolean;
841
+ context?: string | typeof URI | null;
842
+ anchor?: string;
843
+ play?: any;
844
+ toplist?: any;
845
+ /**
846
+ *
847
+ * @return The URI representation of this uri.
848
+ */
849
+ toURI(): string;
850
+ /**
851
+ *
852
+ * @return The URI representation of this uri.
853
+ */
854
+ toString(): string;
855
+ /**
856
+ * Get the URL path of this uri.
857
+ *
858
+ * @param opt_leadingSlash True if a leading slash should be prepended.
859
+ * @return The path of this uri.
860
+ */
861
+ toURLPath(opt_leadingSlash: boolean): string;
862
+ /**
863
+ *
864
+ * @param origin The origin to use for the URL.
865
+ * @return The URL string for the uri.
866
+ */
867
+ toURL(origin?: string): string;
868
+ /**
869
+ * Clones a given SpotifyURI instance.
870
+ *
871
+ * @return An instance of URI.
872
+ */
873
+ clone(): URI | null;
874
+ /**
875
+ * Gets the path of the URI object by removing all hash and query parameters.
876
+ *
877
+ * @return The path of the URI object.
878
+ */
879
+ getPath(): string;
880
+ /**
881
+ * The various URI Types.
882
+ *
883
+ * Note that some of the types in this enum are not real URI types, but are
884
+ * actually URI particles. They are marked so.
885
+ *
886
+ */
887
+ static Type: {
888
+ AD: string;
889
+ ALBUM: string;
890
+ GENRE: string;
891
+ QUEUE: string;
892
+ APPLICATION: string;
893
+ ARTIST: string;
894
+ ARTIST_TOPLIST: string;
895
+ ARTIST_CONCERTS: string;
896
+ AUDIO_FILE: string;
897
+ COLLECTION: string;
898
+ COLLECTION_ALBUM: string;
899
+ COLLECTION_ARTIST: string;
900
+ COLLECTION_MISSING_ALBUM: string;
901
+ COLLECTION_TRACK_LIST: string;
902
+ CONCERT: string;
903
+ CONTEXT_GROUP: string;
904
+ DAILY_MIX: string;
905
+ EMPTY: string;
906
+ EPISODE: string; /** URI particle; not an actual URI. */
907
+ FACEBOOK: string;
908
+ FOLDER: string;
909
+ FOLLOWERS: string;
910
+ FOLLOWING: string;
911
+ IMAGE: string;
912
+ INBOX: string;
913
+ INTERRUPTION: string;
914
+ LIBRARY: string;
915
+ LIVE: string;
916
+ ROOM: string;
917
+ EXPRESSION: string;
918
+ LOCAL: string;
919
+ LOCAL_TRACK: string;
920
+ LOCAL_ALBUM: string;
921
+ LOCAL_ARTIST: string;
922
+ MERCH: string;
923
+ MOSAIC: string;
924
+ PLAYLIST: string;
925
+ PLAYLIST_V2: string;
926
+ PRERELEASE: string;
927
+ PROFILE: string;
928
+ PUBLISHED_ROOTLIST: string;
929
+ RADIO: string;
930
+ ROOTLIST: string;
931
+ SEARCH: string;
932
+ SHOW: string;
933
+ SOCIAL_SESSION: string;
934
+ SPECIAL: string;
935
+ STARRED: string;
936
+ STATION: string;
937
+ TEMP_PLAYLIST: string;
938
+ TOPLIST: string;
939
+ TRACK: string;
940
+ TRACKSET: string;
941
+ USER_TOPLIST: string;
942
+ USER_TOP_TRACKS: string;
943
+ UNKNOWN: string;
944
+ MEDIA: string;
945
+ QUESTION: string;
946
+ POLL: string;
947
+ };
948
+ /**
949
+ * Creates a new URI object from a parsed string argument.
950
+ *
951
+ * @param str The string that will be parsed into a URI object.
952
+ * @throws TypeError If the string argument is not a valid URI, a TypeError will
953
+ * be thrown.
954
+ * @return The parsed URI object.
955
+ */
956
+ static fromString(str: string): URI;
957
+ /**
958
+ * Parses a given object into a URI instance.
959
+ *
960
+ * Unlike URI.fromString, this function could receive any kind of value. If
961
+ * the value is already a URI instance, it is simply returned.
962
+ * Otherwise the value will be stringified before parsing.
963
+ *
964
+ * This function also does not throw an error like URI.fromString, but
965
+ * instead simply returns null if it can't parse the value.
966
+ *
967
+ * @param value The value to parse.
968
+ * @return The corresponding URI instance, or null if the
969
+ * passed value is not a valid value.
970
+ */
971
+ static from(value: any): URI | null;
972
+ /**
973
+ * Checks whether two URI:s refer to the same thing even though they might
974
+ * not necessarily be equal.
975
+ *
976
+ * These two Playlist URIs, for example, refer to the same playlist:
977
+ *
978
+ * spotify:user:napstersean:playlist:3vxotOnOGDlZXyzJPLFnm2
979
+ * spotify:playlist:3vxotOnOGDlZXyzJPLFnm2
980
+ *
981
+ * @param baseUri The first URI to compare.
982
+ * @param refUri The second URI to compare.
983
+ * @return Whether they shared idenitity
984
+ */
985
+ static isSameIdentity(baseUri: URI | string, refUri: URI | string): boolean;
986
+ /**
987
+ * Returns the hex representation of a Base62 encoded id.
988
+ *
989
+ * @param id The base62 encoded id.
990
+ * @return The hex representation of the base62 id.
991
+ */
992
+ static idToHex(id: string): string;
993
+ /**
994
+ * Returns the base62 representation of a hex encoded id.
995
+ *
996
+ * @param hex The hex encoded id.
997
+ * @return The base62 representation of the id.
998
+ */
999
+ static hexToId(hex: string): string;
1000
+ /**
1001
+ * Creates a new 'album' type URI.
1002
+ *
1003
+ * @param id The id of the album.
1004
+ * @param disc The disc number of the album.
1005
+ * @return The album URI.
1006
+ */
1007
+ static albumURI(id: string, disc: number): URI;
1008
+ /**
1009
+ * Creates a new 'application' type URI.
1010
+ *
1011
+ * @param id The id of the application.
1012
+ * @param args An array containing the arguments to the app.
1013
+ * @return The application URI.
1014
+ */
1015
+ static applicationURI(id: string, args: string[]): URI;
1016
+ /**
1017
+ * Creates a new 'artist' type URI.
1018
+ *
1019
+ * @param id The id of the artist.
1020
+ * @return The artist URI.
1021
+ */
1022
+ static artistURI(id: string): URI;
1023
+ /**
1024
+ * Creates a new 'collection' type URI.
1025
+ *
1026
+ * @param username The non-canonical username of the rootlist owner.
1027
+ * @param category The category of the collection.
1028
+ * @return The collection URI.
1029
+ */
1030
+ static collectionURI(username: string, category: string): URI;
1031
+ /**
1032
+ * Creates a new 'collection-album' type URI.
1033
+ *
1034
+ * @param username The non-canonical username of the rootlist owner.
1035
+ * @param id The id of the album.
1036
+ * @return The collection album URI.
1037
+ */
1038
+ static collectionAlbumURI(username: string, id: string): URI;
1039
+ /**
1040
+ * Creates a new 'collection-artist' type URI.
1041
+ *
1042
+ * @param username The non-canonical username of the rootlist owner.
1043
+ * @param id The id of the artist.
1044
+ * @return The collection artist URI.
1045
+ */
1046
+ static collectionAlbumURI(username: string, id: string): URI;
1047
+ /**
1048
+ * Creates a new 'concert' type URI.
1049
+ *
1050
+ * @param id The id of the concert.
1051
+ * @return The concert URI.
1052
+ */
1053
+ static concertURI(id: string): URI;
1054
+ /**
1055
+ * Creates a new 'episode' type URI.
1056
+ *
1057
+ * @param id The id of the episode.
1058
+ * @return The episode URI.
1059
+ */
1060
+ static episodeURI(id: string): URI;
1061
+ /**
1062
+ * Creates a new 'folder' type URI.
1063
+ *
1064
+ * @param id The id of the folder.
1065
+ * @return The folder URI.
1066
+ */
1067
+ static folderURI(id: string): URI;
1068
+ /**
1069
+ * Creates a new 'local-album' type URI.
1070
+ *
1071
+ * @param artist The artist of the album.
1072
+ * @param album The name of the album.
1073
+ * @return The local album URI.
1074
+ */
1075
+ static localAlbumURI(artist: string, album: string): URI;
1076
+ /**
1077
+ * Creates a new 'local-artist' type URI.
1078
+ *
1079
+ * @param artist The name of the artist.
1080
+ * @return The local artist URI.
1081
+ */
1082
+ static localArtistURI(artist: string): URI;
1083
+ /**
1084
+ * Creates a new 'playlist-v2' type URI.
1085
+ *
1086
+ * @param id The id of the playlist.
1087
+ * @return The playlist URI.
1088
+ */
1089
+ static playlistV2URI(id: string): URI;
1090
+ /**
1091
+ * Creates a new 'prerelease' type URI.
1092
+ *
1093
+ * @param id The id of the prerelease.
1094
+ * @return The prerelease URI.
1095
+ */
1096
+ static prereleaseURI(id: string): URI;
1097
+ /**
1098
+ * Creates a new 'profile' type URI.
1099
+ *
1100
+ * @param username The non-canonical username of the rootlist owner.
1101
+ * @param args A list of arguments.
1102
+ * @return The profile URI.
1103
+ */
1104
+ static profileURI(username: string, args: string[]): URI;
1105
+ /**
1106
+ * Creates a new 'search' type URI.
1107
+ *
1108
+ * @param query The unencoded search query.
1109
+ * @return The search URI
1110
+ */
1111
+ static searchURI(query: string): URI;
1112
+ /**
1113
+ * Creates a new 'show' type URI.
1114
+ *
1115
+ * @param id The id of the show.
1116
+ * @return The show URI.
1117
+ */
1118
+ static showURI(id: string): URI;
1119
+ /**
1120
+ * Creates a new 'station' type URI.
1121
+ *
1122
+ * @param args An array of arguments for the station.
1123
+ * @return The station URI.
1124
+ */
1125
+ static stationURI(args: string[]): URI;
1126
+ /**
1127
+ * Creates a new 'track' type URI.
1128
+ *
1129
+ * @param id The id of the track.
1130
+ * @param anchor The point in the track formatted as mm:ss
1131
+ * @param context An optional context URI
1132
+ * @param play Toggles autoplay
1133
+ * @return The track URI.
1134
+ */
1135
+ static trackURI(id: string, anchor: string, context?: string, play?: boolean): URI;
1136
+ /**
1137
+ * Creates a new 'user-toplist' type URI.
1138
+ *
1139
+ * @param username The non-canonical username of the toplist owner.
1140
+ * @param toplist The toplist type.
1141
+ * @return The user-toplist URI.
1142
+ */
1143
+ static userToplistURI(username: string, toplist: string): URI;
1144
+ static isAd(uri: URI | string): boolean;
1145
+ static isAlbum(uri: URI | string): boolean;
1146
+ static isGenre(uri: URI | string): boolean;
1147
+ static isQueue(uri: URI | string): boolean;
1148
+ static isApplication(uri: URI | string): boolean;
1149
+ static isArtist(uri: URI | string): boolean;
1150
+ static isArtistToplist(uri: URI | string): boolean;
1151
+ static isArtistConcerts(uri: URI | string): boolean;
1152
+ static isAudioFile(uri: URI | string): boolean;
1153
+ static isCollection(uri: URI | string): boolean;
1154
+ static isCollectionAlbum(uri: URI | string): boolean;
1155
+ static isCollectionArtist(uri: URI | string): boolean;
1156
+ static isCollectionMissingAlbum(uri: URI | string): boolean;
1157
+ static isCollectionTrackList(uri: URI | string): boolean;
1158
+ static isConcert(uri: URI | string): boolean;
1159
+ static isContextGroup(uri: URI | string): boolean;
1160
+ static isDailyMix(uri: URI | string): boolean;
1161
+ static isEmpty(uri: URI | string): boolean;
1162
+ static isEpisode(uri: URI | string): boolean;
1163
+ static isFacebook(uri: URI | string): boolean;
1164
+ static isFolder(uri: URI | string): boolean;
1165
+ static isFollowers(uri: URI | string): boolean;
1166
+ static isFollowing(uri: URI | string): boolean;
1167
+ static isImage(uri: URI | string): boolean;
1168
+ static isInbox(uri: URI | string): boolean;
1169
+ static isInterruption(uri: URI | string): boolean;
1170
+ static isLibrary(uri: URI | string): boolean;
1171
+ static isLive(uri: URI | string): boolean;
1172
+ static isRoom(uri: URI | string): boolean;
1173
+ static isExpression(uri: URI | string): boolean;
1174
+ static isLocal(uri: URI | string): boolean;
1175
+ static isLocalTrack(uri: URI | string): boolean;
1176
+ static isLocalAlbum(uri: URI | string): boolean;
1177
+ static isLocalArtist(uri: URI | string): boolean;
1178
+ static isMerch(uri: URI | string): boolean;
1179
+ static isMosaic(uri: URI | string): boolean;
1180
+ static isPlaylist(uri: URI | string): boolean;
1181
+ static isPlaylistV2(uri: URI | string): boolean;
1182
+ static isPrerelease(uri: URI | string): boolean;
1183
+ static isProfile(uri: URI | string): boolean;
1184
+ static isPublishedRootlist(uri: URI | string): boolean;
1185
+ static isRadio(uri: URI | string): boolean;
1186
+ static isRootlist(uri: URI | string): boolean;
1187
+ static isSearch(uri: URI | string): boolean;
1188
+ static isShow(uri: URI | string): boolean;
1189
+ static isSocialSession(uri: URI | string): boolean;
1190
+ static isSpecial(uri: URI | string): boolean;
1191
+ static isStarred(uri: URI | string): boolean;
1192
+ static isStation(uri: URI | string): boolean;
1193
+ static isTempPlaylist(uri: URI | string): boolean;
1194
+ static isToplist(uri: URI | string): boolean;
1195
+ static isTrack(uri: URI | string): boolean;
1196
+ static isTrackset(uri: URI | string): boolean;
1197
+ static isUserToplist(uri: URI | string): boolean;
1198
+ static isUserTopTracks(uri: URI | string): boolean;
1199
+ static isUnknown(uri: URI | string): boolean;
1200
+ static isMedia(uri: URI | string): boolean;
1201
+ static isQuestion(uri: URI | string): boolean;
1202
+ static isPoll(uri: URI | string): boolean;
1203
+ static isPlaylistV1OrV2(uri: URI | string): boolean;
1204
+ }
1205
+ /**
1206
+ * Create custom menu item and prepend to right click context menu
1207
+ */
1208
+ namespace ContextMenu {
1209
+ type OnClickCallback = (uris: string[], uids?: string[], contextUri?: string) => void;
1210
+ type ShouldAddCallback = (uris: string[], uids?: string[], contextUri?: string) => boolean;
1211
+ class Item {
1212
+ /**
1213
+ * List of valid icons to use.
1214
+ */
1215
+ static readonly iconList: Icon[];
1216
+ constructor(name: string, onClick: OnClickCallback, shouldAdd?: ShouldAddCallback, icon?: Icon, disabled?: boolean);
1217
+ name: string;
1218
+ icon: Icon | string;
1219
+ disabled: boolean;
1220
+ /**
1221
+ * A function returning boolean determines whether item should be prepended.
1222
+ */
1223
+ shouldAdd: ShouldAddCallback;
1224
+ /**
1225
+ * A function to call when item is clicked
1226
+ */
1227
+ onClick: OnClickCallback;
1228
+ /**
1229
+ * Item is only available in Context Menu when method "register" is called.
1230
+ */
1231
+ register: () => void;
1232
+ /**
1233
+ * Stop Item to be prepended into Context Menu.
1234
+ */
1235
+ deregister: () => void;
1236
+ }
1237
+ /**
1238
+ * Create a sub menu to contain `Item`s.
1239
+ * `Item`s in `subItems` array shouldn't be registered.
1240
+ */
1241
+ class SubMenu {
1242
+ constructor(name: string, subItems: Iterable<Item>, shouldAdd?: ShouldAddCallback, disabled?: boolean);
1243
+ name: string;
1244
+ disabled: boolean;
1245
+ /**
1246
+ * A function returning boolean determines whether item should be prepended.
1247
+ */
1248
+ shouldAdd: ShouldAddCallback;
1249
+ addItem: (item: Item) => void;
1250
+ removeItem: (item: Item) => void;
1251
+ /**
1252
+ * SubMenu is only available in Context Menu when method "register" is called.
1253
+ */
1254
+ register: () => void;
1255
+ /**
1256
+ * Stop SubMenu to be prepended into Context Menu.
1257
+ */
1258
+ deregister: () => void;
1259
+ }
1260
+ }
1261
+ /**
1262
+ * Popup Modal
1263
+ */
1264
+ namespace PopupModal {
1265
+ interface Content {
1266
+ title: string;
1267
+ /**
1268
+ * You can specify a string for simple text display
1269
+ * or a HTML element for interactive config/setting menu
1270
+ */
1271
+ content: string | Element;
1272
+ /**
1273
+ * Bigger window
1274
+ */
1275
+ isLarge?: boolean;
1276
+ }
1277
+ function display(e: Content): void;
1278
+ function hide(): void;
1279
+ }
1280
+ /** React instance to create components */
1281
+ const React: any;
1282
+ /** React DOM instance to render and mount components */
1283
+ const ReactDOM: any;
1284
+ /** React DOM Server instance to render components to string */
1285
+ const ReactDOMServer: any;
1286
+ /** Stock React components exposed from Spotify library */
1287
+ namespace ReactComponent {
1288
+ type ContextMenuProps = {
1289
+ /**
1290
+ * Decide whether to use the global singleton context menu (rendered in <body>)
1291
+ * or a new inline context menu (rendered in a sibling
1292
+ * element to `children`)
1293
+ */
1294
+ renderInline?: boolean;
1295
+ /**
1296
+ * Determins what will trigger the context menu. For example, a click, or a right-click
1297
+ */
1298
+ trigger?: "click" | "right-click";
1299
+ /**
1300
+ * Determins is the context menu should open or toggle when triggered
1301
+ */
1302
+ action?: "toggle" | "open";
1303
+ /**
1304
+ * The preferred placement of the context menu when it opens.
1305
+ * Relative to trigger element.
1306
+ */
1307
+ placement?: "top" | "top-start" | "top-end" | "right" | "right-start" | "right-end" | "bottom" | "bottom-start" | "bottom-end" | "left" | "left-start" | "left-end";
1308
+ /**
1309
+ * The x and y offset distances at which the context menu should open.
1310
+ * Relative to trigger element and `position`.
1311
+ */
1312
+ offset?: [number, number];
1313
+ /**
1314
+ * Will stop the client from scrolling while the context menu is open
1315
+ */
1316
+ preventScrollingWhileOpen?: boolean;
1317
+ /**
1318
+ * The menu UI to render inside of the context menu.
1319
+ */
1320
+ menu: typeof Spicetify.ReactComponent.Menu | typeof Spicetify.ReactComponent.AlbumMenu | typeof Spicetify.ReactComponent.PodcastShowMenu | typeof Spicetify.ReactComponent.ArtistMenu | typeof Spicetify.ReactComponent.PlaylistMenu;
1321
+ /**
1322
+ * A child of the context menu. Should be `<button>`, `<a>`,
1323
+ * a custom react component that forwards a ref to a `<button>` or `<a>`,
1324
+ * or a function. If a function is passed it will be called with
1325
+ * (`isOpen`, `handleContextMenu`, `ref`) as arguments.
1326
+ */
1327
+ children: Element | ((isOpen?: boolean, handleContextMenu?: (e: MouseEvent) => void, ref?: (e: Element) => void) => Element);
1328
+ };
1329
+ type MenuProps = {
1330
+ /**
1331
+ * Function that is called when the menu is closed
1332
+ */
1333
+ onClose?: () => void;
1334
+ /**
1335
+ * Function that provides the element that focus should jump to when the menu
1336
+ * is opened
1337
+ */
1338
+ getInitialFocusElement?: (el: HTMLElement | null) => HTMLElement | undefined | null;
1339
+ };
1340
+ type MenuItemProps = {
1341
+ /**
1342
+ * Function that runs when `MenuItem` is clicked
1343
+ */
1344
+ onClick?: React.MouseEventHandler<HTMLButtonElement>;
1345
+ /**
1346
+ * Indicates if `MenuItem` is disabled. Disabled items will not cause
1347
+ * the `Menu` to close when clicked.
1348
+ */
1349
+ disabled?: boolean;
1350
+ /**
1351
+ * Indicate that a divider line should be added `before` or `after` this `MenuItem`
1352
+ */
1353
+ divider?: "before" | "after" | "both";
1354
+ /**
1355
+ * React component icon that will be rendered at the end of the `MenuItem`
1356
+ * @deprecated Since Spotify `1.2.8`. Use `leadingIcon` or `trailingIcon` instead
1357
+ */
1358
+ icon?: React.ReactNode;
1359
+ /**
1360
+ * React component icon that will be rendered at the start of the `MenuItem`
1361
+ * @since Spotify `1.2.8`
1362
+ */
1363
+ leadingIcon?: React.ReactNode;
1364
+ /**
1365
+ * React component icon that will be rendered at the end of the `MenuItem`
1366
+ * @since Spotify `1.2.8`
1367
+ */
1368
+ trailingIcon?: React.ReactNode;
1369
+ };
1370
+ type TooltipProps = {
1371
+ /**
1372
+ * Label to display in the tooltip
1373
+ */
1374
+ label: string | React.ReactNode;
1375
+ /**
1376
+ * The child element that the tooltip will be attached to
1377
+ * and will display when hovered over
1378
+ */
1379
+ children: React.ReactNode;
1380
+ /**
1381
+ * Decide whether to use the global singleton tooltip (rendered in `<body>`)
1382
+ * or a new inline tooltip (rendered in a sibling
1383
+ * element to `children`)
1384
+ */
1385
+ renderInline?: boolean;
1386
+ /**
1387
+ * Delay in milliseconds before the tooltip is displayed
1388
+ * after the user hovers over the child element
1389
+ */
1390
+ showDelay?: number;
1391
+ /**
1392
+ * Determine whether the tooltip should be displayed
1393
+ */
1394
+ disabled?: boolean;
1395
+ /**
1396
+ * The preferred placement of the context menu when it opens.
1397
+ * Relative to trigger element.
1398
+ * @default 'top'
1399
+ */
1400
+ placement?: "top" | "top-start" | "top-end" | "right" | "right-start" | "right-end" | "bottom" | "bottom-start" | "bottom-end" | "left" | "left-start" | "left-end";
1401
+ /**
1402
+ * Class name to apply to the tooltip
1403
+ */
1404
+ labelClassName?: string;
1405
+ };
1406
+ type IconComponentProps = {
1407
+ /**
1408
+ * Icon size
1409
+ * @default 24
1410
+ */
1411
+ iconSize?: number;
1412
+ /**
1413
+ * Icon color
1414
+ * Might not be used by component
1415
+ * @default 'currentColor'
1416
+ */
1417
+ color?: string;
1418
+ /**
1419
+ * Semantic color name
1420
+ * Matches color variables used in xpui
1421
+ * @default Inherit from parent
1422
+ */
1423
+ semanticColor?: SemanticColor;
1424
+ /**
1425
+ * Icon title
1426
+ * @default ''
1427
+ */
1428
+ title?: string;
1429
+ /**
1430
+ * Title ID (internal)
1431
+ */
1432
+ titleId?: string;
1433
+ /**
1434
+ * Icon description
1435
+ */
1436
+ desc?: string;
1437
+ /**
1438
+ * Description ID (internal)
1439
+ */
1440
+ descId?: string;
1441
+ /**
1442
+ * Auto mirror icon
1443
+ * @default false
1444
+ */
1445
+ autoMirror?: boolean;
1446
+ };
1447
+ type TextComponentProps = {
1448
+ /**
1449
+ * Text color
1450
+ * Might not be used by component
1451
+ * @default 'currentColor'
1452
+ */
1453
+ color?: string;
1454
+ /**
1455
+ * Semantic color name
1456
+ * Matches color variables used in xpui
1457
+ * @default Inherit from parent
1458
+ */
1459
+ semanticColor?: SemanticColor;
1460
+ /**
1461
+ * Text style variant
1462
+ * @default 'viola'
1463
+ */
1464
+ variant?: Variant;
1465
+ /**
1466
+ * Bottom padding size
1467
+ */
1468
+ paddingBottom?: string;
1469
+ /**
1470
+ * Font weight
1471
+ */
1472
+ weight?: "book" | "bold" | "black";
1473
+ };
1474
+ type ConfirmDialogProps = {
1475
+ /**
1476
+ * Boolean to determine if the dialog should be opened
1477
+ * @default true
1478
+ */
1479
+ isOpen?: boolean;
1480
+ /**
1481
+ * Whether to allow inline HTML in component text
1482
+ * @default false
1483
+ */
1484
+ allowHTML?: boolean;
1485
+ /**
1486
+ * Dialog title. Can be inline HTML if `allowHTML` is true
1487
+ */
1488
+ titleText: string;
1489
+ /**
1490
+ * Dialog description. Can be inline HTML if `allowHTML` is true
1491
+ */
1492
+ descriptionText?: string;
1493
+ /**
1494
+ * Confirm button text
1495
+ */
1496
+ confirmText?: string;
1497
+ /**
1498
+ * Cancel button text
1499
+ */
1500
+ cancelText?: string;
1501
+ /**
1502
+ * Confirm button aria-label
1503
+ */
1504
+ confirmLabel?: string;
1505
+ /**
1506
+ * Function to run when confirm button is clicked
1507
+ * The dialog does not close automatically, a handler must be included.
1508
+ * @param {React.MouseEvent<HTMLButtonElement>} event
1509
+ */
1510
+ onConfirm?: (event: React.MouseEvent<HTMLButtonElement>) => void;
1511
+ /**
1512
+ * Function to run when cancel button is clicked.
1513
+ * The dialog does not close automatically, a handler must be included.
1514
+ * @param {React.MouseEvent<HTMLButtonElement>} event
1515
+ */
1516
+ onClose?: (event: React.MouseEvent<HTMLButtonElement>) => void;
1517
+ /**
1518
+ * Function to run when dialog is clicked outside of.
1519
+ * By default, this will run `onClose`.
1520
+ * A handler must be included to close the dialog.
1521
+ * @param {React.MouseEvent<HTMLButtonElement>} event
1522
+ */
1523
+ onOutside?: (event: React.MouseEvent<HTMLButtonElement>) => void;
1524
+ };
1525
+ type SliderProps = {
1526
+ /**
1527
+ * Label for the slider.
1528
+ */
1529
+ labelText?: string;
1530
+ /**
1531
+ * The current value of the slider.
1532
+ */
1533
+ value: number;
1534
+ /**
1535
+ * The minimum value of the slider.
1536
+ */
1537
+ min: number;
1538
+ /**
1539
+ * The maximum value of the slider.
1540
+ */
1541
+ max: number;
1542
+ /**
1543
+ * The step value of the slider.
1544
+ */
1545
+ step: number;
1546
+ /**
1547
+ * Whether or not the slider is disabled/can be interacted with.
1548
+ * @default true
1549
+ */
1550
+ isInteractive?: boolean;
1551
+ /**
1552
+ * Whether or not the active style of the slider should be shown.
1553
+ * This is equivalent to the slider being focused/hovered.
1554
+ * @default false
1555
+ */
1556
+ forceActiveStyles?: boolean;
1557
+ /**
1558
+ * Callback function that is called when the slider starts being dragged.
1559
+ *
1560
+ * @param {number} value The current value of the slider in percent.
1561
+ */
1562
+ onDragStart: (value: number) => void;
1563
+ /**
1564
+ * Callback function that is called when the slider is being dragged.
1565
+ *
1566
+ * @param {number} value The current value of the slider in percent.
1567
+ */
1568
+ onDragMove: (value: number) => void;
1569
+ /**
1570
+ * Callback function that is called when the slider stops being dragged.
1571
+ *
1572
+ * @param {number} value The current value of the slider in percent.
1573
+ */
1574
+ onDragEnd: (value: number) => void;
1575
+ /**
1576
+ * Callback function that is called when the slider incremented a step.
1577
+ *
1578
+ * @deprecated Use `onDrag` props instead.
1579
+ */
1580
+ onStepForward?: () => void;
1581
+ /**
1582
+ * Callback function that is called when the slider decremented a step.
1583
+ *
1584
+ * @deprecated Use `onDrag` props instead.
1585
+ */
1586
+ onStepBackward?: () => void;
1587
+ };
1588
+ type ButtonProps = {
1589
+ component: any;
1590
+ /**
1591
+ * Color set for the button.
1592
+ * @default "brightAccent"
1593
+ */
1594
+ colorSet?: ColorSet;
1595
+ /**
1596
+ * Size for the button.
1597
+ * @default "md"
1598
+ */
1599
+ buttonSize?: "sm" | "md" | "lg";
1600
+ /**
1601
+ * Size for the button.
1602
+ * @deprecated Use `buttonSize` prop instead, as it will take precedence.
1603
+ * @default "medium"
1604
+ */
1605
+ size?: "small" | "medium" | "large";
1606
+ /**
1607
+ * Unused by Spotify. Usage unknown.
1608
+ */
1609
+ fullWidth?: any;
1610
+ /**
1611
+ * React component to render for an icon placed before children. Component, not element!
1612
+ */
1613
+ iconLeading?: (props: any) => any | string;
1614
+ /**
1615
+ * React component to render for an icon placed after children. Component, not element!
1616
+ */
1617
+ iconTrailing?: (props: any) => any | string;
1618
+ /**
1619
+ * React component to render for an icon used as button body. Component, not element!
1620
+ */
1621
+ iconOnly?: (props: any) => any | string;
1622
+ /**
1623
+ * Additional class name to apply to the button.
1624
+ */
1625
+ className?: string;
1626
+ /**
1627
+ * Label of the element for screen readers.
1628
+ */
1629
+ "aria-label"?: string;
1630
+ /**
1631
+ * ID of an element that describes the button for screen readers.
1632
+ */
1633
+ "aria-labelledby"?: string;
1634
+ /**
1635
+ * Unsafely set the color set for the button.
1636
+ * Values from the colorSet will be pasted into the CSS.
1637
+ */
1638
+ UNSAFE_colorSet?: ColorSetBody;
1639
+ onClick?: (event: MouseEvent<HTMLButtonElement>) => void;
1640
+ onMouseEnter?: (event: MouseEvent<HTMLButtonElement>) => void;
1641
+ onMouseLeave?: (event: MouseEvent<HTMLButtonElement>) => void;
1642
+ onMouseDown?: (event: MouseEvent<HTMLButtonElement>) => void;
1643
+ onMouseUp?: (event: MouseEvent<HTMLButtonElement>) => void;
1644
+ onFocus?: (event: FocusEvent<HTMLButtonElement>) => void;
1645
+ onBlur?: (event: FocusEvent<HTMLButtonElement>) => void;
1646
+ };
1647
+ /**
1648
+ * Generic context menu provider
1649
+ *
1650
+ * Props:
1651
+ * @see Spicetify.ReactComponent.ContextMenuProps
1652
+ */
1653
+ const ContextMenu: any;
1654
+ /**
1655
+ * Wrapper of ReactComponent.ContextMenu with props: action = 'toggle' and trigger = 'right-click'
1656
+ *
1657
+ * Props:
1658
+ * @see Spicetify.ReactComponent.ContextMenuProps
1659
+ */
1660
+ const RightClickMenu: any;
1661
+ /**
1662
+ * Outer layer contain ReactComponent.MenuItem(s)
1663
+ *
1664
+ * Props:
1665
+ * @see Spicetify.ReactComponent.MenuProps
1666
+ */
1667
+ const Menu: any;
1668
+ /**
1669
+ * Component to construct menu item
1670
+ * Used as ReactComponent.Menu children
1671
+ *
1672
+ * Props:
1673
+ * @see Spicetify.ReactComponent.MenuItemProps
1674
+ */
1675
+ const MenuItem: any;
1676
+ /**
1677
+ * Tailored ReactComponent.Menu for specific type of object
1678
+ *
1679
+ * Props: {
1680
+ * uri: string;
1681
+ * onRemoveCallback?: (uri: string) => void;
1682
+ * }
1683
+ */
1684
+ const AlbumMenu: any;
1685
+ const PodcastShowMenu: any;
1686
+ const ArtistMenu: any;
1687
+ const PlaylistMenu: any;
1688
+ const TrackMenu: any;
1689
+ /**
1690
+ * Component to display tooltip when hovering over element
1691
+ * Useful for accessibility
1692
+ *
1693
+ * Props:
1694
+ * @see Spicetify.ReactComponent.TooltipProps
1695
+ */
1696
+ const TooltipWrapper: any;
1697
+ /**
1698
+ * Component to render Spotify-style icon
1699
+ * @since Spotify `1.1.95`
1700
+ *
1701
+ * Props:
1702
+ * @see Spicetify.ReactComponent.IconComponentProps
1703
+ */
1704
+ const IconComponent: any;
1705
+ /**
1706
+ * Component to render Spotify-style text
1707
+ * @since Spotify `1.1.95`
1708
+ *
1709
+ * Props:
1710
+ * @see Spicetify.ReactComponent.TextComponentProps
1711
+ */
1712
+ const TextComponent: any;
1713
+ /**
1714
+ * Component to render Spotify-style confirm dialog
1715
+ *
1716
+ * Props:
1717
+ * @see Spicetify.ReactComponent.ConfirmDialogProps
1718
+ */
1719
+ const ConfirmDialog: any;
1720
+ /**
1721
+ * Component to render Spotify slider
1722
+ *
1723
+ * Used in progress bar, volume slider, crossfade settings, etc.
1724
+ *
1725
+ * Props:
1726
+ * @see Spicetify.ReactComponent.SliderProps
1727
+ */
1728
+ const Slider: any;
1729
+ /**
1730
+ * Component to render Spotify primary button
1731
+ *
1732
+ * Props:
1733
+ * @see Spicetify.ReactComponent.ButtonProps
1734
+ */
1735
+ const ButtonPrimary: any;
1736
+ /**
1737
+ * Component to render Spotify secondary button
1738
+ *
1739
+ * Props:
1740
+ * @see Spicetify.ReactComponent.ButtonProps
1741
+ */
1742
+ const ButtonSecondary: any;
1743
+ /**
1744
+ * Component to render Spotify tertiary button
1745
+ *
1746
+ * Props:
1747
+ * @see Spicetify.ReactComponent.ButtonProps
1748
+ */
1749
+ const ButtonTertiary: any;
1750
+ }
1751
+ /**
1752
+ * Add button in top bar next to navigation buttons
1753
+ */
1754
+ namespace Topbar {
1755
+ class Button {
1756
+ constructor(label: string, icon: Icon | string, onClick: (self: Button) => void, disabled?: boolean, isRight?: boolean);
1757
+ label: string;
1758
+ icon: string;
1759
+ onClick: (self: Button) => void;
1760
+ disabled: boolean;
1761
+ isRight: boolean;
1762
+ element: HTMLButtonElement;
1763
+ tippy: any;
1764
+ }
1765
+ }
1766
+ /**
1767
+ * Add button in player controls
1768
+ */
1769
+ namespace Playbar {
1770
+ /**
1771
+ * Create a button on the right side of the playbar
1772
+ */
1773
+ class Button {
1774
+ constructor(label: string, icon: Icon | string, onClick?: (self: Button) => void, disabled?: boolean, active?: boolean, registerOnCreate?: boolean);
1775
+ label: string;
1776
+ icon: string;
1777
+ onClick: (self: Button) => void;
1778
+ disabled: boolean;
1779
+ active: boolean;
1780
+ element: HTMLButtonElement;
1781
+ tippy: any;
1782
+ register: () => void;
1783
+ deregister: () => void;
1784
+ }
1785
+ /**
1786
+ * Create a widget next to track info
1787
+ */
1788
+ class Widget {
1789
+ constructor(label: string, icon: Icon | string, onClick?: (self: Widget) => void, disabled?: boolean, active?: boolean, registerOnCreate?: boolean);
1790
+ label: string;
1791
+ icon: string;
1792
+ onClick: (self: Widget) => void;
1793
+ disabled: boolean;
1794
+ active: boolean;
1795
+ element: HTMLButtonElement;
1796
+ tippy: any;
1797
+ register: () => void;
1798
+ deregister: () => void;
1799
+ }
1800
+ }
1801
+ /**
1802
+ * SVG icons
1803
+ */
1804
+ const SVGIcons: Record<Icon, string>;
1805
+ /**
1806
+ * A filtered copy of user's `config-xpui` file.
1807
+ */
1808
+ namespace Config {
1809
+ const version: string;
1810
+ const current_theme: string;
1811
+ const color_scheme: string;
1812
+ const extensions: string[];
1813
+ const custom_apps: string[];
1814
+ }
1815
+ /**
1816
+ * Tippy.js instance used by Spotify
1817
+ */
1818
+ const Tippy: any;
1819
+ /**
1820
+ * Spicetify's predefined props for Tippy.js
1821
+ * Used to mimic Spotify's tooltip behavior
1822
+ */
1823
+ const TippyProps: any;
1824
+ /**
1825
+ * Interface for interacting with Spotify client's app title
1826
+ */
1827
+ namespace AppTitle {
1828
+ /**
1829
+ * Set default app title. This has no effect if the player is running.
1830
+ * Will override any previous forced title.
1831
+ * @param title Title to set
1832
+ * @return Promise that resolves to a function to cancel forced title. This doesn't reset the title.
1833
+ */
1834
+ function set(title: string): Promise<{
1835
+ clear: () => void;
1836
+ }>;
1837
+ /**
1838
+ * Reset app title to default
1839
+ */
1840
+ function reset(): Promise<void>;
1841
+ /**
1842
+ * Get current default app title
1843
+ * @return Current default app title
1844
+ */
1845
+ function get(): Promise<string>;
1846
+ /**
1847
+ * Subscribe to title changes.
1848
+ * This event is not fired when the player changes app title.
1849
+ * @param callback Callback to call when title changes
1850
+ * @return Object with method to unsubscribe
1851
+ */
1852
+ function sub(callback: (title: string) => void): {
1853
+ clear: () => void;
1854
+ };
1855
+ }
1856
+ /**
1857
+ * Spicetify's QraphQL wrapper for Spotify's GraphQL API endpoints
1858
+ */
1859
+ namespace GraphQL {
1860
+ /**
1861
+ * Possible types of entities.
1862
+ *
1863
+ * This list is dynamic and may change in the future.
1864
+ */
1865
+ type Query = "decorateItemsForEnhance" | "imageURLAndSize" | "imageSources" | "audioItems" | "creator" | "extractedColors" | "extractedColorsAndImageSources" | "fetchExtractedColorAndImageForAlbumEntity" | "fetchExtractedColorAndImageForArtistEntity" | "fetchExtractedColorAndImageForEpisodeEntity" | "fetchExtractedColorAndImageForPlaylistEntity" | "fetchExtractedColorAndImageForPodcastEntity" | "fetchExtractedColorAndImageForTrackEntity" | "fetchExtractedColorForAlbumEntity" | "fetchExtractedColorForArtistEntity" | "fetchExtractedColorForEpisodeEntity" | "fetchExtractedColorForPlaylistEntity" | "fetchExtractedColorForPodcastEntity" | "fetchExtractedColorForTrackEntity" | "getAlbumNameAndTracks" | "getEpisodeName" | "getTrackName" | "queryAlbumTrackUris" | "queryTrackArtists" | "decorateContextEpisodesOrChapters" | "decorateContextTracks" | "fetchTracksForRadioStation" | "decoratePlaylists" | "playlistUser" | "FetchPlaylistMetadata" | "playlistContentsItemTrackArtist" | "playlistContentsItemTrackAlbum" | "playlistContentsItemTrack" | "playlistContentsItemLocalTrack" | "playlistContentsItemEpisodeShow" | "playlistContentsItemEpisode" | "playlistContentsItemResponse" | "playlistContentsItem" | "FetchPlaylistContents" | "episodeTrailerUri" | "podcastEpisode" | "podcastMetadataV2" | "minimalAudiobook" | "audiobookChapter" | "audiobookMetadataV2" | "fetchExtractedColors" | "queryFullscreenMode" | "queryNpvEpisode" | "queryNpvArtist" | "albumTrack" | "getAlbum" | "queryAlbumTracks" | "queryArtistOverview" | "queryArtistAppearsOn" | "discographyAlbum" | "albumMetadataReleases" | "albumMetadata" | "queryArtistDiscographyAlbums" | "queryArtistDiscographySingles" | "queryArtistDiscographyCompilations" | "queryArtistDiscographyAll" | "queryArtistDiscographyOverview" | "artistPlaylist" | "queryArtistPlaylists" | "queryArtistDiscoveredOn" | "queryArtistFeaturing" | "queryArtistRelated" | "queryArtistMinimal" | "searchModalResults" | "queryWhatsNewFeed" | "whatsNewFeedNewItems" | "SetItemsStateInWhatsNewFeed" | "browseImageURLAndSize" | "browseImageSources" | "browseAlbum" | "browseArtist" | "browseEpisode" | "browseChapter" | "browsePlaylist" | "browsePodcast" | "browseAudiobook" | "browseTrack" | "browseUser" | "browseMerch" | "browseArtistConcerts" | "browseContent" | "browseSectionContainer" | "browseClientFeature" | "browseItem" | "browseAll" | "browsePage";
1866
+ /**
1867
+ * Collection of GraphQL definitions.
1868
+ */
1869
+ const Definitions: Record<Query | string, any>;
1870
+ /**
1871
+ * Sends a GraphQL query to Spotify.
1872
+ * @description A preinitialized version of `Spicetify.GraphQL.Handler` using current context.
1873
+ * @param query Query to send
1874
+ * @param variables Variables to use
1875
+ * @param context Context to use
1876
+ * @return Promise that resolves to the response
1877
+ */
1878
+ function Request(query: (typeof Definitions)[Query | string], variables?: Record<string, any>, context?: Record<string, any>): Promise<any>;
1879
+ /**
1880
+ * Context for GraphQL queries.
1881
+ * @description Used to set context for the handler and initialze it.
1882
+ */
1883
+ const Context: Record<string, any>;
1884
+ /**
1885
+ * Handler for GraphQL queries.
1886
+ * @param context Context to use
1887
+ * @return Function to handle GraphQL queries
1888
+ */
1889
+ function Handler(context: Record<string, any>): (query: (typeof Definitions)[Query | string], variables?: Record<string, any>, context?: Record<string, any>) => Promise<any>;
1890
+ }
1891
+ namespace ReactHook {
1892
+ /**
1893
+ * React Hook to create interactive drag-and-drop element
1894
+ * @description Used to create a draggable element that can be dropped into Spotify's components (e.g. Playlist, Folder, Sidebar, Queue)
1895
+ * @param uris List of URIs to be dragged
1896
+ * @param label Label to be displayed when dragging
1897
+ * @param contextUri Context URI of the element from which the drag originated (e.g. Playlist URI)
1898
+ * @param sectionIndex Index of the section in which the drag originated
1899
+ * @param dropOriginUri URI of the desired drop target. Leave empty to allow drop anywhere
1900
+ * @return Function to handle drag event. Should be passed to `onDragStart` prop of the element. All parameters passed onto the hook will be passed onto the handler unless declared otherwise.
1901
+ *
1902
+ */
1903
+ function DragHandler(uris?: string[], label?: string, contextUri?: string, sectionIndex?: number, dropOriginUri?: string): (event: React.DragEvent, uris?: string[], label?: string, contextUri?: string, sectionIndex?: number) => void;
1904
+ /**
1905
+ * React Hook to use extracted color from GraphQL
1906
+ *
1907
+ * @note This is a wrapper of ReactQuery's `useQuery` hook.
1908
+ * The component using this hook must be wrapped in a `QueryClientProvider` component.
1909
+ *
1910
+ * @see https://tanstack.com/query/v3/docs/react/reference/QueryClientProvider
1911
+ *
1912
+ * @param uri URI of the Spotify image to extract color from.
1913
+ * @param fallbackColor Fallback color to use if the image is not available. Defaults to `#535353`.
1914
+ * @param variant Variant of the color to use. Defaults to `colorRaw`.
1915
+ *
1916
+ * @return Extracted color hex code.
1917
+ */
1918
+ function useExtractedColor(uri: string, fallbackColor?: string, variant?: "colorRaw" | "colorLight" | "colorDark"): string;
1919
+ }
1920
+ /**
1921
+ * react-flip-toolkit
1922
+ * @description A lightweight magic-move library for configurable layout transitions.
1923
+ * @link https://github.com/aholachek/react-flip-toolkit
1924
+ */
1925
+ namespace ReactFlipToolkit {
1926
+ const Flipper: any;
1927
+ const Flipped: any;
1928
+ const spring: any;
1929
+ }
1930
+ /**
1931
+ * classnames
1932
+ * @description A simple JavaScript utility for conditionally joining classNames together.
1933
+ * @link https://github.com/JedWatson/classnames
1934
+ */
1935
+ function classnames(...args: any[]): string;
1936
+ /**
1937
+ * React Query v3
1938
+ * @description A hook for fetching, caching and updating asynchronous data in React.
1939
+ * @link https://github.com/TanStack/query/tree/v3
1940
+ */
1941
+ const ReactQuery: any;
1942
+ /**
1943
+ * Analyse and extract color presets from an image. Works for any valid image URL/URI.
1944
+ * @param image Spotify URI to an image, or an image URL.
1945
+ */
1946
+ function extractColorPreset(image: string | string[]): Promise<{
1947
+ colorRaw: Color;
1948
+ colorLight: Color;
1949
+ colorDark: Color;
1950
+ isFallback: boolean;
1951
+ }[]>;
1952
+ interface hsl {
1953
+ h: number;
1954
+ s: number;
1955
+ l: number;
1956
+ }
1957
+ interface hsv {
1958
+ h: number;
1959
+ s: number;
1960
+ v: number;
1961
+ }
1962
+ interface rgb {
1963
+ r: number;
1964
+ g: number;
1965
+ b: number;
1966
+ }
1967
+ type CSSColors = "HEX" | "HEXA" | "HSL" | "HSLA" | "RGB" | "RGBA";
1968
+ /**
1969
+ * Spotify's internal color class
1970
+ */
1971
+ class Color {
1972
+ constructor(rgb: rgb, hsl: hsl, hsv: hsv, alpha?: number);
1973
+ static BLACK: Color;
1974
+ static WHITE: Color;
1975
+ static CSSFormat: Record<CSSColors, number> & Record<number, CSSColors>;
1976
+ a: number;
1977
+ hsl: hsl;
1978
+ hsv: hsv;
1979
+ rgb: rgb;
1980
+ /**
1981
+ * Convert CSS representation to Color
1982
+ * @param cssColor CSS representation of the color. Must not contain spaces.
1983
+ * @param alpha Alpha value of the color. Defaults to 1.
1984
+ * @return Color object
1985
+ * @throws {Error} If the CSS color is invalid or unsupported
1986
+ */
1987
+ static fromCSS(cssColor: string, alpha?: number): Color;
1988
+ static fromHSL(hsl: hsl, alpha?: number): Color;
1989
+ static fromHSV(hsv: hsv, alpha?: number): Color;
1990
+ static fromRGB(rgb: rgb, alpha?: number): Color;
1991
+ static fromHex(hex: string, alpha?: number): Color;
1992
+ /**
1993
+ * Change the contrast of the color against another so that
1994
+ * the contrast between them is at least `strength`.
1995
+ */
1996
+ contrastAdjust(against: Color, strength?: number): Color;
1997
+ /**
1998
+ * Stringify JSON result
1999
+ */
2000
+ stringify(): string;
2001
+ /**
2002
+ * Convert to CSS representation
2003
+ * @param colorFormat CSS color format to convert to
2004
+ * @return CSS representation of the color
2005
+ */
2006
+ toCSS(colorFormat: number): string;
2007
+ /**
2008
+ * Return RGBA representation of the color
2009
+ */
2010
+ toString(): string;
2011
+ }
2012
+ /**
2013
+ * Spotify internal library for localization
2014
+ */
2015
+ namespace Locale {
2016
+ /**
2017
+ * Relative time format
2018
+ */
2019
+ const _relativeTimeFormat: Intl.RelativeTimeFormat | null;
2020
+ /**
2021
+ * Registered date time formats in the current session
2022
+ */
2023
+ const _dateTimeFormats: Record<string, Intl.DateTimeFormat>;
2024
+ /**
2025
+ * Current locale of the client
2026
+ */
2027
+ const _locale: string;
2028
+ const _urlLocale: string;
2029
+ /**
2030
+ * Collection of supported locales
2031
+ */
2032
+ const _supportedLocales: Record<string, string>;
2033
+ /**
2034
+ * Dictionary of localized strings
2035
+ */
2036
+ const _dictionary: Record<string, string | {
2037
+ one: string;
2038
+ other: string;
2039
+ }>;
2040
+ /**
2041
+ * Format date into locale string
2042
+ *
2043
+ * @param date Date to format
2044
+ * @param options Options to use
2045
+ * @return Localized string
2046
+ * @throws {RangeError} If the date is invalid
2047
+ */
2048
+ function formatDate(date: number | Date | undefined, options?: Intl.DateTimeFormatOptions): string;
2049
+ /**
2050
+ * Format time into relative locale string
2051
+ *
2052
+ * @param date Date to format
2053
+ * @param options Options to use
2054
+ * @return Localized string
2055
+ * @throws {RangeError} If the date is invalid
2056
+ */
2057
+ function formatRelativeTime(date: number | Date | undefined, options?: Intl.DateTimeFormatOptions): string;
2058
+ /**
2059
+ * Format number into locale string
2060
+ *
2061
+ * @param number Number to format
2062
+ * @param options Options to use
2063
+ * @return Localized string
2064
+ */
2065
+ function formatNumber(number: number, options?: Intl.NumberFormatOptions): string;
2066
+ /**
2067
+ * Format number into compact locale string
2068
+ *
2069
+ * @param number Number to format
2070
+ * @return Localized string
2071
+ */
2072
+ function formatNumberCompact(number: number): string;
2073
+ /**
2074
+ * Get localized string
2075
+ *
2076
+ * @param key Key of the string
2077
+ * @param children React children to pass the string into
2078
+ * @return Localized string or React Fragment of the children
2079
+ */
2080
+ function get(key: string, ...children: React.ReactNode[]): string | React.ReactNode;
2081
+ /**
2082
+ * Get date time format of the passed options.
2083
+ *
2084
+ * Function calls here will register to the `_dateTimeFormats` dictionary.
2085
+ *
2086
+ * @param options Options to use
2087
+ * @return Date time format
2088
+ */
2089
+ function getDateTimeFormat(options?: Intl.DateTimeFormatOptions): Intl.DateTimeFormat;
2090
+ /**
2091
+ * Get the current locale dictionary
2092
+ *
2093
+ * @return Current locale dictionary
2094
+ */
2095
+ function getDictionary(): Record<string, string | {
2096
+ one: string;
2097
+ other: string;
2098
+ }>;
2099
+ /**
2100
+ * Get the current locale
2101
+ *
2102
+ * @return Current locale
2103
+ */
2104
+ function getLocale(): string;
2105
+ /**
2106
+ * Get the current locale code for Smartling
2107
+ *
2108
+ * @return Current locale code for Smartling
2109
+ */
2110
+ function getSmartlingLocale(): string;
2111
+ /**
2112
+ * Get the current locale code for URL
2113
+ *
2114
+ * @return Current locale code for URL
2115
+ */
2116
+ function getUrlLocale(): string;
2117
+ /**
2118
+ * Get the current relative time format
2119
+ *
2120
+ * @return Current relative time format
2121
+ */
2122
+ function getRelativeTimeFormat(): Intl.RelativeTimeFormat;
2123
+ /**
2124
+ * Get the separator for the current locale
2125
+ *
2126
+ * @return Separator for the current locale
2127
+ */
2128
+ function getSeparator(): string;
2129
+ /**
2130
+ * Set the current locale
2131
+ *
2132
+ * This will clear all previously set relative time formats and key-value pairs.
2133
+ *
2134
+ * @param locale Locale to set
2135
+ */
2136
+ function setLocale(locale: string): void;
2137
+ /**
2138
+ * Set the current locale code for URL
2139
+ *
2140
+ * @param locale Locale code for URL to set
2141
+ */
2142
+ function setUrlLocale(locale: string): void;
2143
+ /**
2144
+ * Set the dictionary for the current locale
2145
+ *
2146
+ * @param dictionary Dictionary to set
2147
+ */
2148
+ function setDictionary(dictionary: Record<string, string | {
2149
+ one: string;
2150
+ other: string;
2151
+ }>): void;
2152
+ /**
2153
+ * Transform text into locale lowercase
2154
+ *
2155
+ * @param text Text to transform
2156
+ * @return Locale lowercase text
2157
+ */
2158
+ function toLocaleLowerCase(text: string): string;
2159
+ /**
2160
+ * Transform text into locale uppercase
2161
+ *
2162
+ * @param text Text to transform
2163
+ * @return Locale uppercase text
2164
+ */
2165
+ function toLocaleUpperCase(text: string): string;
2166
+ }
2167
+ }
2168
+ declare global {
2169
+ const Spicetify: typeof _Spicetify;
2170
+ }
2171
+ //#endregion
2172
+ //#region src/client/index.d.ts
2173
+ declare function defineConfig(config: FileConfig): FileConfig;
2174
+ //#endregion
2175
+ export { _Spicetify as Spicetify, defineConfig };