@howells/stow-server 0.7.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Stow
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.js CHANGED
@@ -294,12 +294,12 @@ var StowServer = class {
294
294
  constructor(config) {
295
295
  if (typeof config === "string") {
296
296
  this.apiKey = config;
297
- this.baseUrl = "https://app.stow.sh";
297
+ this.baseUrl = "https://api.stow.sh";
298
298
  this.timeout = 3e4;
299
299
  this.retries = 3;
300
300
  } else {
301
301
  this.apiKey = config.apiKey;
302
- this.baseUrl = config.baseUrl || "https://app.stow.sh";
302
+ this.baseUrl = config.baseUrl || "https://api.stow.sh";
303
303
  this.bucket = config.bucket;
304
304
  this.timeout = config.timeout ?? 3e4;
305
305
  this.retries = config.retries ?? 3;
@@ -315,20 +315,20 @@ var StowServer = class {
315
315
  * Return account usage and API key info for the current credential.
316
316
  */
317
317
  whoami() {
318
- return this.request("/api/whoami", { method: "GET" }, whoamiSchema);
318
+ return this.request("/whoami", { method: "GET" }, whoamiSchema);
319
319
  }
320
320
  /**
321
321
  * List all buckets available to the current organization.
322
322
  */
323
323
  listBuckets() {
324
- return this.request("/api/buckets", { method: "GET" }, listBucketsSchema);
324
+ return this.request("/buckets", { method: "GET" }, listBucketsSchema);
325
325
  }
326
326
  /**
327
327
  * Create a new bucket.
328
328
  */
329
329
  async createBucket(request) {
330
330
  const result = await this.request(
331
- "/api/buckets",
331
+ "/buckets",
332
332
  {
333
333
  method: "POST",
334
334
  headers: { "Content-Type": "application/json" },
@@ -343,7 +343,7 @@ var StowServer = class {
343
343
  */
344
344
  async getBucket(id) {
345
345
  const result = await this.request(
346
- `/api/buckets/${encodeURIComponent(id)}`,
346
+ `/buckets/${encodeURIComponent(id)}`,
347
347
  { method: "GET" },
348
348
  bucketResponseSchema
349
349
  );
@@ -354,7 +354,7 @@ var StowServer = class {
354
354
  */
355
355
  async updateBucket(id, updates) {
356
356
  const result = await this.request(
357
- `/api/buckets/${encodeURIComponent(id)}`,
357
+ `/buckets/${encodeURIComponent(id)}`,
358
358
  {
359
359
  method: "PATCH",
360
360
  headers: { "Content-Type": "application/json" },
@@ -369,7 +369,7 @@ var StowServer = class {
369
369
  */
370
370
  async updateBucketByName(name, updates) {
371
371
  const result = await this.request(
372
- `/api/buckets/_?bucket=${encodeURIComponent(name)}`,
372
+ `/buckets/_?bucket=${encodeURIComponent(name)}`,
373
373
  {
374
374
  method: "PATCH",
375
375
  headers: { "Content-Type": "application/json" },
@@ -389,7 +389,7 @@ var StowServer = class {
389
389
  * Delete a bucket by id.
390
390
  */
391
391
  async deleteBucket(id) {
392
- await this.request(`/api/buckets/${encodeURIComponent(id)}`, {
392
+ await this.request(`/buckets/${encodeURIComponent(id)}`, {
393
393
  method: "DELETE"
394
394
  });
395
395
  }
@@ -517,7 +517,7 @@ var StowServer = class {
517
517
  }
518
518
  return this.request(
519
519
  this.withBucket(
520
- presign.confirmUrl || "/api/presign/confirm",
520
+ presign.confirmUrl || "/presign/confirm",
521
521
  options?.bucket
522
522
  ),
523
523
  {
@@ -543,7 +543,7 @@ var StowServer = class {
543
543
  */
544
544
  async uploadFromUrl(url, filename, options) {
545
545
  const result = await this.request(
546
- this.withBucket("/api/upload", options?.bucket),
546
+ this.withBucket("/upload", options?.bucket),
547
547
  {
548
548
  method: "POST",
549
549
  headers: { "Content-Type": "application/json" },
@@ -576,7 +576,7 @@ var StowServer = class {
576
576
  */
577
577
  async queueUploadFromUrl(url, filename, options) {
578
578
  return this.request(
579
- this.withBucket("/api/upload", options?.bucket),
579
+ this.withBucket("/upload", options?.bucket),
580
580
  {
581
581
  method: "POST",
582
582
  headers: { "Content-Type": "application/json" },
@@ -614,7 +614,7 @@ var StowServer = class {
614
614
  contentHash
615
615
  } = request;
616
616
  return this.request(
617
- this.withBucket("/api/presign", bucket),
617
+ this.withBucket("/presign", bucket),
618
618
  {
619
619
  method: "POST",
620
620
  headers: { "Content-Type": "application/json" },
@@ -648,7 +648,7 @@ var StowServer = class {
648
648
  altText
649
649
  } = request;
650
650
  return this.request(
651
- this.withBucket("/api/presign/confirm", bucket),
651
+ this.withBucket("/presign/confirm", bucket),
652
652
  {
653
653
  method: "POST",
654
654
  headers: { "Content-Type": "application/json" },
@@ -689,7 +689,7 @@ var StowServer = class {
689
689
  if (options?.include?.length) {
690
690
  params.set("include", options.include.join(","));
691
691
  }
692
- const path = `/api/files?${params}`;
692
+ const path = `/files?${params}`;
693
693
  return this.request(
694
694
  this.withBucket(path, options?.bucket),
695
695
  { method: "GET" },
@@ -700,7 +700,7 @@ var StowServer = class {
700
700
  * Delete a file by key
701
701
  */
702
702
  async deleteFile(key, options) {
703
- const path = `/api/files/${encodeURIComponent(key)}`;
703
+ const path = `/files/${encodeURIComponent(key)}`;
704
704
  await this.request(this.withBucket(path, options?.bucket), {
705
705
  method: "DELETE"
706
706
  });
@@ -709,7 +709,7 @@ var StowServer = class {
709
709
  * Update metadata on an existing file
710
710
  */
711
711
  updateFileMetadata(key, metadata, options) {
712
- const path = `/api/files/${encodeURIComponent(key)}`;
712
+ const path = `/files/${encodeURIComponent(key)}`;
713
713
  return this.request(this.withBucket(path, options?.bucket), {
714
714
  method: "PATCH",
715
715
  headers: { "Content-Type": "application/json" },
@@ -727,7 +727,7 @@ var StowServer = class {
727
727
  params.set("include", options.include.join(","));
728
728
  }
729
729
  const qs = params.toString();
730
- const path = `/api/files/${encodeURIComponent(key)}${qs ? `?${qs}` : ""}`;
730
+ const path = `/files/${encodeURIComponent(key)}${qs ? `?${qs}` : ""}`;
731
731
  return this.request(
732
732
  this.withBucket(path, options?.bucket),
733
733
  { method: "GET" },
@@ -739,7 +739,7 @@ var StowServer = class {
739
739
  * Requires a searchable bucket.
740
740
  */
741
741
  extractColors(key, options) {
742
- const path = `/api/files/${encodeURIComponent(key)}/colors`;
742
+ const path = `/files/${encodeURIComponent(key)}/colors`;
743
743
  return this.request(
744
744
  this.withBucket(path, options?.bucket),
745
745
  { method: "POST" },
@@ -750,7 +750,7 @@ var StowServer = class {
750
750
  * Extract dimensions (width/height) from an image or video file.
751
751
  */
752
752
  extractDimensions(key, options) {
753
- const path = `/api/files/${encodeURIComponent(key)}/dimensions`;
753
+ const path = `/files/${encodeURIComponent(key)}/dimensions`;
754
754
  return this.request(
755
755
  this.withBucket(path, options?.bucket),
756
756
  { method: "POST" },
@@ -762,7 +762,7 @@ var StowServer = class {
762
762
  * Requires a searchable bucket.
763
763
  */
764
764
  embed(key, options) {
765
- const path = `/api/files/${encodeURIComponent(key)}/embedding`;
765
+ const path = `/files/${encodeURIComponent(key)}/embedding`;
766
766
  return this.request(
767
767
  this.withBucket(path, options?.bucket),
768
768
  { method: "POST" },
@@ -774,7 +774,7 @@ var StowServer = class {
774
774
  * Requires a searchable bucket.
775
775
  */
776
776
  generateTitle(key, options) {
777
- const path = `/api/files/${encodeURIComponent(key)}/title`;
777
+ const path = `/files/${encodeURIComponent(key)}/title`;
778
778
  return this.request(
779
779
  this.withBucket(path, options?.bucket),
780
780
  { method: "POST" },
@@ -786,7 +786,7 @@ var StowServer = class {
786
786
  * Requires a searchable bucket.
787
787
  */
788
788
  generateDescription(key, options) {
789
- const path = `/api/files/${encodeURIComponent(key)}/description`;
789
+ const path = `/files/${encodeURIComponent(key)}/description`;
790
790
  return this.request(
791
791
  this.withBucket(path, options?.bucket),
792
792
  { method: "POST" },
@@ -798,7 +798,7 @@ var StowServer = class {
798
798
  * Requires a searchable bucket.
799
799
  */
800
800
  generateAltText(key, options) {
801
- const path = `/api/files/${encodeURIComponent(key)}/alt-text`;
801
+ const path = `/files/${encodeURIComponent(key)}/alt-text`;
802
802
  return this.request(
803
803
  this.withBucket(path, options?.bucket),
804
804
  { method: "POST" },
@@ -813,7 +813,7 @@ var StowServer = class {
813
813
  * tasks are re-dispatched as if the file were newly uploaded.
814
814
  */
815
815
  replaceFile(key, url, options) {
816
- const path = `/api/files/${encodeURIComponent(key)}/replace`;
816
+ const path = `/files/${encodeURIComponent(key)}/replace`;
817
817
  return this.request(
818
818
  this.withBucket(path, options?.bucket),
819
819
  {
@@ -870,17 +870,17 @@ var StowServer = class {
870
870
  };
871
871
  }
872
872
  listTags() {
873
- return this.request("/api/tags", { method: "GET" });
873
+ return this.request("/tags", { method: "GET" });
874
874
  }
875
875
  createTag(params) {
876
- return this.request("/api/tags", {
876
+ return this.request("/tags", {
877
877
  method: "POST",
878
878
  headers: { "Content-Type": "application/json" },
879
879
  body: JSON.stringify(params)
880
880
  });
881
881
  }
882
882
  async deleteTag(id) {
883
- await this.request(`/api/tags/${encodeURIComponent(id)}`, {
883
+ await this.request(`/tags/${encodeURIComponent(id)}`, {
884
884
  method: "DELETE"
885
885
  });
886
886
  }
@@ -891,7 +891,7 @@ var StowServer = class {
891
891
  * Add tags to a file
892
892
  */
893
893
  async addTags(key, tagIds, options) {
894
- const path = `/api/files/${encodeURIComponent(key)}/tags`;
894
+ const path = `/files/${encodeURIComponent(key)}/tags`;
895
895
  await this.request(this.withBucket(path, options?.bucket), {
896
896
  method: "POST",
897
897
  headers: { "Content-Type": "application/json" },
@@ -902,7 +902,7 @@ var StowServer = class {
902
902
  * Remove a tag from a file
903
903
  */
904
904
  async removeTag(key, tagId, options) {
905
- const path = `/api/files/${encodeURIComponent(key)}/tags/${encodeURIComponent(tagId)}`;
905
+ const path = `/files/${encodeURIComponent(key)}/tags/${encodeURIComponent(tagId)}`;
906
906
  await this.request(this.withBucket(path, options?.bucket), {
907
907
  method: "DELETE"
908
908
  });
@@ -927,7 +927,7 @@ var StowServer = class {
927
927
  };
928
928
  }
929
929
  listTaxonomies() {
930
- return this.request("/api/taxonomies", { method: "GET" });
930
+ return this.request("/taxonomies", { method: "GET" });
931
931
  }
932
932
  // ============================================================
933
933
  // SEARCH - Vector similarity search
@@ -945,7 +945,7 @@ var StowServer = class {
945
945
  }
946
946
  searchSimilar(params) {
947
947
  const bucket = this.resolveBucket(params.bucket);
948
- return this.request("/api/search/similar", {
948
+ return this.request("/search/similar", {
949
949
  method: "POST",
950
950
  headers: { "Content-Type": "application/json" },
951
951
  body: JSON.stringify({
@@ -964,7 +964,7 @@ var StowServer = class {
964
964
  }
965
965
  searchDiverse(params) {
966
966
  const bucket = this.resolveBucket(params.bucket);
967
- return this.request("/api/search/diverse", {
967
+ return this.request("/search/diverse", {
968
968
  method: "POST",
969
969
  headers: { "Content-Type": "application/json" },
970
970
  body: JSON.stringify({
@@ -984,7 +984,7 @@ var StowServer = class {
984
984
  }
985
985
  searchText(params) {
986
986
  const bucket = this.resolveBucket(params.bucket);
987
- return this.request("/api/search/text", {
987
+ return this.request("/search/text", {
988
988
  method: "POST",
989
989
  headers: { "Content-Type": "application/json" },
990
990
  body: JSON.stringify({
@@ -999,7 +999,7 @@ var StowServer = class {
999
999
  }
1000
1000
  searchColor(params) {
1001
1001
  const bucket = this.resolveBucket(params.bucket);
1002
- return this.request("/api/search/color", {
1002
+ return this.request("/search/color", {
1003
1003
  method: "POST",
1004
1004
  headers: { "Content-Type": "application/json" },
1005
1005
  body: JSON.stringify({
@@ -1032,7 +1032,7 @@ var StowServer = class {
1032
1032
  const contentType = options?.contentType || "application/octet-stream";
1033
1033
  const filename = options?.filename || "file";
1034
1034
  const buffer = Buffer.isBuffer(file) ? file : Buffer.from(await file.arrayBuffer());
1035
- const presign = await this.request("/api/drops/presign", {
1035
+ const presign = await this.request("/drops/presign", {
1036
1036
  method: "POST",
1037
1037
  headers: { "Content-Type": "application/json" },
1038
1038
  body: JSON.stringify({
@@ -1050,7 +1050,7 @@ var StowServer = class {
1050
1050
  throw new StowError("Failed to upload to storage", putRes.status);
1051
1051
  }
1052
1052
  return this.request(
1053
- presign.confirmUrl || "/api/drops/presign/confirm",
1053
+ presign.confirmUrl || "/drops/presign/confirm",
1054
1054
  {
1055
1055
  method: "POST",
1056
1056
  headers: { "Content-Type": "application/json" },
@@ -1070,13 +1070,13 @@ var StowServer = class {
1070
1070
  * List all drops for the authenticated user
1071
1071
  */
1072
1072
  listDrops() {
1073
- return this.request("/api/drops", { method: "GET" }, listDropsSchema);
1073
+ return this.request("/drops", { method: "GET" }, listDropsSchema);
1074
1074
  }
1075
1075
  /**
1076
1076
  * Delete a drop by ID
1077
1077
  */
1078
1078
  async deleteDrop(id) {
1079
- await this.request(`/api/drops/${encodeURIComponent(id)}`, {
1079
+ await this.request(`/drops/${encodeURIComponent(id)}`, {
1080
1080
  method: "DELETE"
1081
1081
  });
1082
1082
  }
@@ -1102,7 +1102,7 @@ var StowServer = class {
1102
1102
  }
1103
1103
  createProfile(params) {
1104
1104
  return this.request(
1105
- "/api/profiles",
1105
+ "/profiles",
1106
1106
  {
1107
1107
  method: "POST",
1108
1108
  headers: { "Content-Type": "application/json" },
@@ -1117,19 +1117,19 @@ var StowServer = class {
1117
1117
  }
1118
1118
  getProfile(id) {
1119
1119
  return this.request(
1120
- `/api/profiles/${encodeURIComponent(id)}`,
1120
+ `/profiles/${encodeURIComponent(id)}`,
1121
1121
  { method: "GET" },
1122
1122
  profileResultSchema
1123
1123
  );
1124
1124
  }
1125
1125
  async deleteProfile(id) {
1126
- await this.request(`/api/profiles/${encodeURIComponent(id)}`, {
1126
+ await this.request(`/profiles/${encodeURIComponent(id)}`, {
1127
1127
  method: "DELETE"
1128
1128
  });
1129
1129
  }
1130
1130
  addProfileFiles(id, fileKeys, bucket) {
1131
1131
  return this.request(
1132
- `/api/profiles/${encodeURIComponent(id)}/files`,
1132
+ `/profiles/${encodeURIComponent(id)}/files`,
1133
1133
  {
1134
1134
  method: "POST",
1135
1135
  headers: { "Content-Type": "application/json" },
@@ -1143,7 +1143,7 @@ var StowServer = class {
1143
1143
  }
1144
1144
  removeProfileFiles(id, fileKeys, bucket) {
1145
1145
  return this.request(
1146
- `/api/profiles/${encodeURIComponent(id)}/files`,
1146
+ `/profiles/${encodeURIComponent(id)}/files`,
1147
1147
  {
1148
1148
  method: "DELETE",
1149
1149
  headers: { "Content-Type": "application/json" },
@@ -1157,7 +1157,7 @@ var StowServer = class {
1157
1157
  }
1158
1158
  signalProfile(id, signals, bucket) {
1159
1159
  return this.request(
1160
- `/api/profiles/${encodeURIComponent(id)}/signals`,
1160
+ `/profiles/${encodeURIComponent(id)}/signals`,
1161
1161
  {
1162
1162
  method: "POST",
1163
1163
  headers: { "Content-Type": "application/json" },
@@ -1171,7 +1171,7 @@ var StowServer = class {
1171
1171
  }
1172
1172
  deleteProfileSignals(id, signalIds) {
1173
1173
  return this.request(
1174
- `/api/profiles/${encodeURIComponent(id)}/signals`,
1174
+ `/profiles/${encodeURIComponent(id)}/signals`,
1175
1175
  {
1176
1176
  method: "DELETE",
1177
1177
  headers: { "Content-Type": "application/json" },
@@ -1181,12 +1181,12 @@ var StowServer = class {
1181
1181
  );
1182
1182
  }
1183
1183
  getProfileClusters(id) {
1184
- return this.request(`/api/profiles/${encodeURIComponent(id)}/clusters`, {
1184
+ return this.request(`/profiles/${encodeURIComponent(id)}/clusters`, {
1185
1185
  method: "GET"
1186
1186
  });
1187
1187
  }
1188
1188
  reclusterProfile(id, params) {
1189
- return this.request(`/api/profiles/${encodeURIComponent(id)}/clusters`, {
1189
+ return this.request(`/profiles/${encodeURIComponent(id)}/clusters`, {
1190
1190
  method: "POST",
1191
1191
  headers: { "Content-Type": "application/json" },
1192
1192
  body: JSON.stringify({
@@ -1196,7 +1196,7 @@ var StowServer = class {
1196
1196
  }
1197
1197
  renameProfileCluster(profileId, clusterId, params) {
1198
1198
  return this.request(
1199
- `/api/profiles/${encodeURIComponent(profileId)}/clusters/${encodeURIComponent(clusterId)}`,
1199
+ `/profiles/${encodeURIComponent(profileId)}/clusters/${encodeURIComponent(clusterId)}`,
1200
1200
  {
1201
1201
  method: "PUT",
1202
1202
  headers: { "Content-Type": "application/json" },
package/dist/index.mjs CHANGED
@@ -269,12 +269,12 @@ var StowServer = class {
269
269
  constructor(config) {
270
270
  if (typeof config === "string") {
271
271
  this.apiKey = config;
272
- this.baseUrl = "https://app.stow.sh";
272
+ this.baseUrl = "https://api.stow.sh";
273
273
  this.timeout = 3e4;
274
274
  this.retries = 3;
275
275
  } else {
276
276
  this.apiKey = config.apiKey;
277
- this.baseUrl = config.baseUrl || "https://app.stow.sh";
277
+ this.baseUrl = config.baseUrl || "https://api.stow.sh";
278
278
  this.bucket = config.bucket;
279
279
  this.timeout = config.timeout ?? 3e4;
280
280
  this.retries = config.retries ?? 3;
@@ -290,20 +290,20 @@ var StowServer = class {
290
290
  * Return account usage and API key info for the current credential.
291
291
  */
292
292
  whoami() {
293
- return this.request("/api/whoami", { method: "GET" }, whoamiSchema);
293
+ return this.request("/whoami", { method: "GET" }, whoamiSchema);
294
294
  }
295
295
  /**
296
296
  * List all buckets available to the current organization.
297
297
  */
298
298
  listBuckets() {
299
- return this.request("/api/buckets", { method: "GET" }, listBucketsSchema);
299
+ return this.request("/buckets", { method: "GET" }, listBucketsSchema);
300
300
  }
301
301
  /**
302
302
  * Create a new bucket.
303
303
  */
304
304
  async createBucket(request) {
305
305
  const result = await this.request(
306
- "/api/buckets",
306
+ "/buckets",
307
307
  {
308
308
  method: "POST",
309
309
  headers: { "Content-Type": "application/json" },
@@ -318,7 +318,7 @@ var StowServer = class {
318
318
  */
319
319
  async getBucket(id) {
320
320
  const result = await this.request(
321
- `/api/buckets/${encodeURIComponent(id)}`,
321
+ `/buckets/${encodeURIComponent(id)}`,
322
322
  { method: "GET" },
323
323
  bucketResponseSchema
324
324
  );
@@ -329,7 +329,7 @@ var StowServer = class {
329
329
  */
330
330
  async updateBucket(id, updates) {
331
331
  const result = await this.request(
332
- `/api/buckets/${encodeURIComponent(id)}`,
332
+ `/buckets/${encodeURIComponent(id)}`,
333
333
  {
334
334
  method: "PATCH",
335
335
  headers: { "Content-Type": "application/json" },
@@ -344,7 +344,7 @@ var StowServer = class {
344
344
  */
345
345
  async updateBucketByName(name, updates) {
346
346
  const result = await this.request(
347
- `/api/buckets/_?bucket=${encodeURIComponent(name)}`,
347
+ `/buckets/_?bucket=${encodeURIComponent(name)}`,
348
348
  {
349
349
  method: "PATCH",
350
350
  headers: { "Content-Type": "application/json" },
@@ -364,7 +364,7 @@ var StowServer = class {
364
364
  * Delete a bucket by id.
365
365
  */
366
366
  async deleteBucket(id) {
367
- await this.request(`/api/buckets/${encodeURIComponent(id)}`, {
367
+ await this.request(`/buckets/${encodeURIComponent(id)}`, {
368
368
  method: "DELETE"
369
369
  });
370
370
  }
@@ -492,7 +492,7 @@ var StowServer = class {
492
492
  }
493
493
  return this.request(
494
494
  this.withBucket(
495
- presign.confirmUrl || "/api/presign/confirm",
495
+ presign.confirmUrl || "/presign/confirm",
496
496
  options?.bucket
497
497
  ),
498
498
  {
@@ -518,7 +518,7 @@ var StowServer = class {
518
518
  */
519
519
  async uploadFromUrl(url, filename, options) {
520
520
  const result = await this.request(
521
- this.withBucket("/api/upload", options?.bucket),
521
+ this.withBucket("/upload", options?.bucket),
522
522
  {
523
523
  method: "POST",
524
524
  headers: { "Content-Type": "application/json" },
@@ -551,7 +551,7 @@ var StowServer = class {
551
551
  */
552
552
  async queueUploadFromUrl(url, filename, options) {
553
553
  return this.request(
554
- this.withBucket("/api/upload", options?.bucket),
554
+ this.withBucket("/upload", options?.bucket),
555
555
  {
556
556
  method: "POST",
557
557
  headers: { "Content-Type": "application/json" },
@@ -589,7 +589,7 @@ var StowServer = class {
589
589
  contentHash
590
590
  } = request;
591
591
  return this.request(
592
- this.withBucket("/api/presign", bucket),
592
+ this.withBucket("/presign", bucket),
593
593
  {
594
594
  method: "POST",
595
595
  headers: { "Content-Type": "application/json" },
@@ -623,7 +623,7 @@ var StowServer = class {
623
623
  altText
624
624
  } = request;
625
625
  return this.request(
626
- this.withBucket("/api/presign/confirm", bucket),
626
+ this.withBucket("/presign/confirm", bucket),
627
627
  {
628
628
  method: "POST",
629
629
  headers: { "Content-Type": "application/json" },
@@ -664,7 +664,7 @@ var StowServer = class {
664
664
  if (options?.include?.length) {
665
665
  params.set("include", options.include.join(","));
666
666
  }
667
- const path = `/api/files?${params}`;
667
+ const path = `/files?${params}`;
668
668
  return this.request(
669
669
  this.withBucket(path, options?.bucket),
670
670
  { method: "GET" },
@@ -675,7 +675,7 @@ var StowServer = class {
675
675
  * Delete a file by key
676
676
  */
677
677
  async deleteFile(key, options) {
678
- const path = `/api/files/${encodeURIComponent(key)}`;
678
+ const path = `/files/${encodeURIComponent(key)}`;
679
679
  await this.request(this.withBucket(path, options?.bucket), {
680
680
  method: "DELETE"
681
681
  });
@@ -684,7 +684,7 @@ var StowServer = class {
684
684
  * Update metadata on an existing file
685
685
  */
686
686
  updateFileMetadata(key, metadata, options) {
687
- const path = `/api/files/${encodeURIComponent(key)}`;
687
+ const path = `/files/${encodeURIComponent(key)}`;
688
688
  return this.request(this.withBucket(path, options?.bucket), {
689
689
  method: "PATCH",
690
690
  headers: { "Content-Type": "application/json" },
@@ -702,7 +702,7 @@ var StowServer = class {
702
702
  params.set("include", options.include.join(","));
703
703
  }
704
704
  const qs = params.toString();
705
- const path = `/api/files/${encodeURIComponent(key)}${qs ? `?${qs}` : ""}`;
705
+ const path = `/files/${encodeURIComponent(key)}${qs ? `?${qs}` : ""}`;
706
706
  return this.request(
707
707
  this.withBucket(path, options?.bucket),
708
708
  { method: "GET" },
@@ -714,7 +714,7 @@ var StowServer = class {
714
714
  * Requires a searchable bucket.
715
715
  */
716
716
  extractColors(key, options) {
717
- const path = `/api/files/${encodeURIComponent(key)}/colors`;
717
+ const path = `/files/${encodeURIComponent(key)}/colors`;
718
718
  return this.request(
719
719
  this.withBucket(path, options?.bucket),
720
720
  { method: "POST" },
@@ -725,7 +725,7 @@ var StowServer = class {
725
725
  * Extract dimensions (width/height) from an image or video file.
726
726
  */
727
727
  extractDimensions(key, options) {
728
- const path = `/api/files/${encodeURIComponent(key)}/dimensions`;
728
+ const path = `/files/${encodeURIComponent(key)}/dimensions`;
729
729
  return this.request(
730
730
  this.withBucket(path, options?.bucket),
731
731
  { method: "POST" },
@@ -737,7 +737,7 @@ var StowServer = class {
737
737
  * Requires a searchable bucket.
738
738
  */
739
739
  embed(key, options) {
740
- const path = `/api/files/${encodeURIComponent(key)}/embedding`;
740
+ const path = `/files/${encodeURIComponent(key)}/embedding`;
741
741
  return this.request(
742
742
  this.withBucket(path, options?.bucket),
743
743
  { method: "POST" },
@@ -749,7 +749,7 @@ var StowServer = class {
749
749
  * Requires a searchable bucket.
750
750
  */
751
751
  generateTitle(key, options) {
752
- const path = `/api/files/${encodeURIComponent(key)}/title`;
752
+ const path = `/files/${encodeURIComponent(key)}/title`;
753
753
  return this.request(
754
754
  this.withBucket(path, options?.bucket),
755
755
  { method: "POST" },
@@ -761,7 +761,7 @@ var StowServer = class {
761
761
  * Requires a searchable bucket.
762
762
  */
763
763
  generateDescription(key, options) {
764
- const path = `/api/files/${encodeURIComponent(key)}/description`;
764
+ const path = `/files/${encodeURIComponent(key)}/description`;
765
765
  return this.request(
766
766
  this.withBucket(path, options?.bucket),
767
767
  { method: "POST" },
@@ -773,7 +773,7 @@ var StowServer = class {
773
773
  * Requires a searchable bucket.
774
774
  */
775
775
  generateAltText(key, options) {
776
- const path = `/api/files/${encodeURIComponent(key)}/alt-text`;
776
+ const path = `/files/${encodeURIComponent(key)}/alt-text`;
777
777
  return this.request(
778
778
  this.withBucket(path, options?.bucket),
779
779
  { method: "POST" },
@@ -788,7 +788,7 @@ var StowServer = class {
788
788
  * tasks are re-dispatched as if the file were newly uploaded.
789
789
  */
790
790
  replaceFile(key, url, options) {
791
- const path = `/api/files/${encodeURIComponent(key)}/replace`;
791
+ const path = `/files/${encodeURIComponent(key)}/replace`;
792
792
  return this.request(
793
793
  this.withBucket(path, options?.bucket),
794
794
  {
@@ -845,17 +845,17 @@ var StowServer = class {
845
845
  };
846
846
  }
847
847
  listTags() {
848
- return this.request("/api/tags", { method: "GET" });
848
+ return this.request("/tags", { method: "GET" });
849
849
  }
850
850
  createTag(params) {
851
- return this.request("/api/tags", {
851
+ return this.request("/tags", {
852
852
  method: "POST",
853
853
  headers: { "Content-Type": "application/json" },
854
854
  body: JSON.stringify(params)
855
855
  });
856
856
  }
857
857
  async deleteTag(id) {
858
- await this.request(`/api/tags/${encodeURIComponent(id)}`, {
858
+ await this.request(`/tags/${encodeURIComponent(id)}`, {
859
859
  method: "DELETE"
860
860
  });
861
861
  }
@@ -866,7 +866,7 @@ var StowServer = class {
866
866
  * Add tags to a file
867
867
  */
868
868
  async addTags(key, tagIds, options) {
869
- const path = `/api/files/${encodeURIComponent(key)}/tags`;
869
+ const path = `/files/${encodeURIComponent(key)}/tags`;
870
870
  await this.request(this.withBucket(path, options?.bucket), {
871
871
  method: "POST",
872
872
  headers: { "Content-Type": "application/json" },
@@ -877,7 +877,7 @@ var StowServer = class {
877
877
  * Remove a tag from a file
878
878
  */
879
879
  async removeTag(key, tagId, options) {
880
- const path = `/api/files/${encodeURIComponent(key)}/tags/${encodeURIComponent(tagId)}`;
880
+ const path = `/files/${encodeURIComponent(key)}/tags/${encodeURIComponent(tagId)}`;
881
881
  await this.request(this.withBucket(path, options?.bucket), {
882
882
  method: "DELETE"
883
883
  });
@@ -902,7 +902,7 @@ var StowServer = class {
902
902
  };
903
903
  }
904
904
  listTaxonomies() {
905
- return this.request("/api/taxonomies", { method: "GET" });
905
+ return this.request("/taxonomies", { method: "GET" });
906
906
  }
907
907
  // ============================================================
908
908
  // SEARCH - Vector similarity search
@@ -920,7 +920,7 @@ var StowServer = class {
920
920
  }
921
921
  searchSimilar(params) {
922
922
  const bucket = this.resolveBucket(params.bucket);
923
- return this.request("/api/search/similar", {
923
+ return this.request("/search/similar", {
924
924
  method: "POST",
925
925
  headers: { "Content-Type": "application/json" },
926
926
  body: JSON.stringify({
@@ -939,7 +939,7 @@ var StowServer = class {
939
939
  }
940
940
  searchDiverse(params) {
941
941
  const bucket = this.resolveBucket(params.bucket);
942
- return this.request("/api/search/diverse", {
942
+ return this.request("/search/diverse", {
943
943
  method: "POST",
944
944
  headers: { "Content-Type": "application/json" },
945
945
  body: JSON.stringify({
@@ -959,7 +959,7 @@ var StowServer = class {
959
959
  }
960
960
  searchText(params) {
961
961
  const bucket = this.resolveBucket(params.bucket);
962
- return this.request("/api/search/text", {
962
+ return this.request("/search/text", {
963
963
  method: "POST",
964
964
  headers: { "Content-Type": "application/json" },
965
965
  body: JSON.stringify({
@@ -974,7 +974,7 @@ var StowServer = class {
974
974
  }
975
975
  searchColor(params) {
976
976
  const bucket = this.resolveBucket(params.bucket);
977
- return this.request("/api/search/color", {
977
+ return this.request("/search/color", {
978
978
  method: "POST",
979
979
  headers: { "Content-Type": "application/json" },
980
980
  body: JSON.stringify({
@@ -1007,7 +1007,7 @@ var StowServer = class {
1007
1007
  const contentType = options?.contentType || "application/octet-stream";
1008
1008
  const filename = options?.filename || "file";
1009
1009
  const buffer = Buffer.isBuffer(file) ? file : Buffer.from(await file.arrayBuffer());
1010
- const presign = await this.request("/api/drops/presign", {
1010
+ const presign = await this.request("/drops/presign", {
1011
1011
  method: "POST",
1012
1012
  headers: { "Content-Type": "application/json" },
1013
1013
  body: JSON.stringify({
@@ -1025,7 +1025,7 @@ var StowServer = class {
1025
1025
  throw new StowError("Failed to upload to storage", putRes.status);
1026
1026
  }
1027
1027
  return this.request(
1028
- presign.confirmUrl || "/api/drops/presign/confirm",
1028
+ presign.confirmUrl || "/drops/presign/confirm",
1029
1029
  {
1030
1030
  method: "POST",
1031
1031
  headers: { "Content-Type": "application/json" },
@@ -1045,13 +1045,13 @@ var StowServer = class {
1045
1045
  * List all drops for the authenticated user
1046
1046
  */
1047
1047
  listDrops() {
1048
- return this.request("/api/drops", { method: "GET" }, listDropsSchema);
1048
+ return this.request("/drops", { method: "GET" }, listDropsSchema);
1049
1049
  }
1050
1050
  /**
1051
1051
  * Delete a drop by ID
1052
1052
  */
1053
1053
  async deleteDrop(id) {
1054
- await this.request(`/api/drops/${encodeURIComponent(id)}`, {
1054
+ await this.request(`/drops/${encodeURIComponent(id)}`, {
1055
1055
  method: "DELETE"
1056
1056
  });
1057
1057
  }
@@ -1077,7 +1077,7 @@ var StowServer = class {
1077
1077
  }
1078
1078
  createProfile(params) {
1079
1079
  return this.request(
1080
- "/api/profiles",
1080
+ "/profiles",
1081
1081
  {
1082
1082
  method: "POST",
1083
1083
  headers: { "Content-Type": "application/json" },
@@ -1092,19 +1092,19 @@ var StowServer = class {
1092
1092
  }
1093
1093
  getProfile(id) {
1094
1094
  return this.request(
1095
- `/api/profiles/${encodeURIComponent(id)}`,
1095
+ `/profiles/${encodeURIComponent(id)}`,
1096
1096
  { method: "GET" },
1097
1097
  profileResultSchema
1098
1098
  );
1099
1099
  }
1100
1100
  async deleteProfile(id) {
1101
- await this.request(`/api/profiles/${encodeURIComponent(id)}`, {
1101
+ await this.request(`/profiles/${encodeURIComponent(id)}`, {
1102
1102
  method: "DELETE"
1103
1103
  });
1104
1104
  }
1105
1105
  addProfileFiles(id, fileKeys, bucket) {
1106
1106
  return this.request(
1107
- `/api/profiles/${encodeURIComponent(id)}/files`,
1107
+ `/profiles/${encodeURIComponent(id)}/files`,
1108
1108
  {
1109
1109
  method: "POST",
1110
1110
  headers: { "Content-Type": "application/json" },
@@ -1118,7 +1118,7 @@ var StowServer = class {
1118
1118
  }
1119
1119
  removeProfileFiles(id, fileKeys, bucket) {
1120
1120
  return this.request(
1121
- `/api/profiles/${encodeURIComponent(id)}/files`,
1121
+ `/profiles/${encodeURIComponent(id)}/files`,
1122
1122
  {
1123
1123
  method: "DELETE",
1124
1124
  headers: { "Content-Type": "application/json" },
@@ -1132,7 +1132,7 @@ var StowServer = class {
1132
1132
  }
1133
1133
  signalProfile(id, signals, bucket) {
1134
1134
  return this.request(
1135
- `/api/profiles/${encodeURIComponent(id)}/signals`,
1135
+ `/profiles/${encodeURIComponent(id)}/signals`,
1136
1136
  {
1137
1137
  method: "POST",
1138
1138
  headers: { "Content-Type": "application/json" },
@@ -1146,7 +1146,7 @@ var StowServer = class {
1146
1146
  }
1147
1147
  deleteProfileSignals(id, signalIds) {
1148
1148
  return this.request(
1149
- `/api/profiles/${encodeURIComponent(id)}/signals`,
1149
+ `/profiles/${encodeURIComponent(id)}/signals`,
1150
1150
  {
1151
1151
  method: "DELETE",
1152
1152
  headers: { "Content-Type": "application/json" },
@@ -1156,12 +1156,12 @@ var StowServer = class {
1156
1156
  );
1157
1157
  }
1158
1158
  getProfileClusters(id) {
1159
- return this.request(`/api/profiles/${encodeURIComponent(id)}/clusters`, {
1159
+ return this.request(`/profiles/${encodeURIComponent(id)}/clusters`, {
1160
1160
  method: "GET"
1161
1161
  });
1162
1162
  }
1163
1163
  reclusterProfile(id, params) {
1164
- return this.request(`/api/profiles/${encodeURIComponent(id)}/clusters`, {
1164
+ return this.request(`/profiles/${encodeURIComponent(id)}/clusters`, {
1165
1165
  method: "POST",
1166
1166
  headers: { "Content-Type": "application/json" },
1167
1167
  body: JSON.stringify({
@@ -1171,7 +1171,7 @@ var StowServer = class {
1171
1171
  }
1172
1172
  renameProfileCluster(profileId, clusterId, params) {
1173
1173
  return this.request(
1174
- `/api/profiles/${encodeURIComponent(profileId)}/clusters/${encodeURIComponent(clusterId)}`,
1174
+ `/profiles/${encodeURIComponent(profileId)}/clusters/${encodeURIComponent(clusterId)}`,
1175
1175
  {
1176
1176
  method: "PUT",
1177
1177
  headers: { "Content-Type": "application/json" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@howells/stow-server",
3
- "version": "0.7.0",
3
+ "version": "2.0.0",
4
4
  "description": "Server-side SDK for Stow file storage",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -29,21 +29,21 @@
29
29
  "files": [
30
30
  "dist"
31
31
  ],
32
- "scripts": {
33
- "build": "tsup src/index.ts --format cjs,esm --dts",
34
- "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
35
- "test": "vitest run",
36
- "test:watch": "vitest"
37
- },
38
32
  "peerDependencies": {
39
33
  "zod": "^3.0.0 || ^4.0.0"
40
34
  },
41
35
  "devDependencies": {
42
- "@stow/typescript-config": "workspace:*",
43
36
  "@types/node": "^25.3.0",
44
37
  "tsup": "^8.5.1",
45
38
  "typescript": "^5.9.3",
46
39
  "vitest": "^4.0.18",
47
- "zod": "^4.3.6"
40
+ "zod": "^4.3.6",
41
+ "@stow/typescript-config": "0.0.0"
42
+ },
43
+ "scripts": {
44
+ "build": "tsup src/index.ts --format cjs,esm --dts",
45
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
46
+ "test": "vitest run",
47
+ "test:watch": "vitest"
48
48
  }
49
- }
49
+ }