@fairu/sdk 1.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 (150) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +447 -0
  3. package/dist/FairuClient-BUObk5LJ.cjs +91 -0
  4. package/dist/FairuClient-BUObk5LJ.cjs.map +1 -0
  5. package/dist/FairuClient-CT-IPh8i.js +92 -0
  6. package/dist/FairuClient-CT-IPh8i.js.map +1 -0
  7. package/dist/FairuError-D8sSmRAa.js +214 -0
  8. package/dist/FairuError-D8sSmRAa.js.map +1 -0
  9. package/dist/FairuError-DWH_Nwk0.cjs +213 -0
  10. package/dist/FairuError-DWH_Nwk0.cjs.map +1 -0
  11. package/dist/FairuProvider-BRpRddCI.cjs +51 -0
  12. package/dist/FairuProvider-BRpRddCI.cjs.map +1 -0
  13. package/dist/FairuProvider-Tc0vFo5L.js +52 -0
  14. package/dist/FairuProvider-Tc0vFo5L.js.map +1 -0
  15. package/dist/FileProxyBuilder-D-jZpAtd.cjs +269 -0
  16. package/dist/FileProxyBuilder-D-jZpAtd.cjs.map +1 -0
  17. package/dist/FileProxyBuilder-vHw1zBpJ.js +270 -0
  18. package/dist/FileProxyBuilder-vHw1zBpJ.js.map +1 -0
  19. package/dist/FragmentBuilder-BinoxeVS.js +194 -0
  20. package/dist/FragmentBuilder-BinoxeVS.js.map +1 -0
  21. package/dist/FragmentBuilder-BuvIC0aT.cjs +193 -0
  22. package/dist/FragmentBuilder-BuvIC0aT.cjs.map +1 -0
  23. package/dist/UploadError-CHBJuChw.cjs +81 -0
  24. package/dist/UploadError-CHBJuChw.cjs.map +1 -0
  25. package/dist/UploadError-_gEcJqSS.js +82 -0
  26. package/dist/UploadError-_gEcJqSS.js.map +1 -0
  27. package/dist/client/FairuClient.d.ts +8 -0
  28. package/dist/client/FairuClient.d.ts.map +1 -0
  29. package/dist/client/FairuProvider.d.ts +78 -0
  30. package/dist/client/FairuProvider.d.ts.map +1 -0
  31. package/dist/client/cache.d.ts +6 -0
  32. package/dist/client/cache.d.ts.map +1 -0
  33. package/dist/client/config.d.ts +77 -0
  34. package/dist/client/config.d.ts.map +1 -0
  35. package/dist/client/index.d.ts +5 -0
  36. package/dist/client/index.d.ts.map +1 -0
  37. package/dist/errors/FairuError.d.ts +107 -0
  38. package/dist/errors/FairuError.d.ts.map +1 -0
  39. package/dist/errors/UploadError.d.ts +54 -0
  40. package/dist/errors/UploadError.d.ts.map +1 -0
  41. package/dist/errors/index.d.ts +3 -0
  42. package/dist/errors/index.d.ts.map +1 -0
  43. package/dist/fileproxy/FileProxyBuilder.d.ts +141 -0
  44. package/dist/fileproxy/FileProxyBuilder.d.ts.map +1 -0
  45. package/dist/fileproxy/index.d.ts +4 -0
  46. package/dist/fileproxy/index.d.ts.map +1 -0
  47. package/dist/fileproxy/types.d.ts +79 -0
  48. package/dist/fileproxy/types.d.ts.map +1 -0
  49. package/dist/fileproxy/useFileProxyUrl.d.ts +91 -0
  50. package/dist/fileproxy/useFileProxyUrl.d.ts.map +1 -0
  51. package/dist/fileproxy.cjs +10 -0
  52. package/dist/fileproxy.cjs.map +1 -0
  53. package/dist/fileproxy.d.ts +2 -0
  54. package/dist/fileproxy.js +10 -0
  55. package/dist/fileproxy.js.map +1 -0
  56. package/dist/fragments/FragmentBuilder.d.ts +107 -0
  57. package/dist/fragments/FragmentBuilder.d.ts.map +1 -0
  58. package/dist/fragments/FragmentRegistry.d.ts +93 -0
  59. package/dist/fragments/FragmentRegistry.d.ts.map +1 -0
  60. package/dist/fragments/index.d.ts +5 -0
  61. package/dist/fragments/index.d.ts.map +1 -0
  62. package/dist/fragments/predefined/assetFragments.d.ts +39 -0
  63. package/dist/fragments/predefined/assetFragments.d.ts.map +1 -0
  64. package/dist/fragments/predefined/copyrightFragments.d.ts +12 -0
  65. package/dist/fragments/predefined/copyrightFragments.d.ts.map +1 -0
  66. package/dist/fragments/predefined/folderFragments.d.ts +28 -0
  67. package/dist/fragments/predefined/folderFragments.d.ts.map +1 -0
  68. package/dist/fragments/predefined/galleryFragments.d.ts +24 -0
  69. package/dist/fragments/predefined/galleryFragments.d.ts.map +1 -0
  70. package/dist/fragments/predefined/index.d.ts +6 -0
  71. package/dist/fragments/predefined/index.d.ts.map +1 -0
  72. package/dist/fragments/predefined/licenseFragments.d.ts +12 -0
  73. package/dist/fragments/predefined/licenseFragments.d.ts.map +1 -0
  74. package/dist/fragments/types.d.ts +46 -0
  75. package/dist/fragments/types.d.ts.map +1 -0
  76. package/dist/fragments.cjs +403 -0
  77. package/dist/fragments.cjs.map +1 -0
  78. package/dist/fragments.d.ts +2 -0
  79. package/dist/fragments.js +403 -0
  80. package/dist/fragments.js.map +1 -0
  81. package/dist/generated/graphql.d.ts +3464 -0
  82. package/dist/generated/graphql.d.ts.map +1 -0
  83. package/dist/hooks/index.d.ts +3 -0
  84. package/dist/hooks/index.d.ts.map +1 -0
  85. package/dist/hooks/mutations/index.d.ts +5 -0
  86. package/dist/hooks/mutations/index.d.ts.map +1 -0
  87. package/dist/hooks/mutations/useAssetMutations.d.ts +66 -0
  88. package/dist/hooks/mutations/useAssetMutations.d.ts.map +1 -0
  89. package/dist/hooks/mutations/useFolderMutations.d.ts +69 -0
  90. package/dist/hooks/mutations/useFolderMutations.d.ts.map +1 -0
  91. package/dist/hooks/mutations/useGalleryMutations.d.ts +39 -0
  92. package/dist/hooks/mutations/useGalleryMutations.d.ts.map +1 -0
  93. package/dist/hooks/mutations/useUpdateAsset.d.ts +50 -0
  94. package/dist/hooks/mutations/useUpdateAsset.d.ts.map +1 -0
  95. package/dist/hooks/queries/index.d.ts +8 -0
  96. package/dist/hooks/queries/index.d.ts.map +1 -0
  97. package/dist/hooks/queries/useAsset.d.ts +46 -0
  98. package/dist/hooks/queries/useAsset.d.ts.map +1 -0
  99. package/dist/hooks/queries/useAssets.d.ts +58 -0
  100. package/dist/hooks/queries/useAssets.d.ts.map +1 -0
  101. package/dist/hooks/queries/useCopyright.d.ts +51 -0
  102. package/dist/hooks/queries/useCopyright.d.ts.map +1 -0
  103. package/dist/hooks/queries/useFolder.d.ts +93 -0
  104. package/dist/hooks/queries/useFolder.d.ts.map +1 -0
  105. package/dist/hooks/queries/useGallery.d.ts +101 -0
  106. package/dist/hooks/queries/useGallery.d.ts.map +1 -0
  107. package/dist/hooks/queries/useLicense.d.ts +63 -0
  108. package/dist/hooks/queries/useLicense.d.ts.map +1 -0
  109. package/dist/hooks/queries/useTenant.d.ts +89 -0
  110. package/dist/hooks/queries/useTenant.d.ts.map +1 -0
  111. package/dist/index.cjs +244 -0
  112. package/dist/index.cjs.map +1 -0
  113. package/dist/index.d.ts +18 -0
  114. package/dist/index.d.ts.map +1 -0
  115. package/dist/index.js +244 -0
  116. package/dist/index.js.map +1 -0
  117. package/dist/react.cjs +596 -0
  118. package/dist/react.cjs.map +1 -0
  119. package/dist/react.d.ts +22 -0
  120. package/dist/react.d.ts.map +1 -0
  121. package/dist/react.js +596 -0
  122. package/dist/react.js.map +1 -0
  123. package/dist/upload/index.d.ts +4 -0
  124. package/dist/upload/index.d.ts.map +1 -0
  125. package/dist/upload/types.d.ts +96 -0
  126. package/dist/upload/types.d.ts.map +1 -0
  127. package/dist/upload/useMultipartUpload.d.ts +67 -0
  128. package/dist/upload/useMultipartUpload.d.ts.map +1 -0
  129. package/dist/upload/useUpload.d.ts +64 -0
  130. package/dist/upload/useUpload.d.ts.map +1 -0
  131. package/dist/upload.cjs +6 -0
  132. package/dist/upload.cjs.map +1 -0
  133. package/dist/upload.d.ts +2 -0
  134. package/dist/upload.js +6 -0
  135. package/dist/upload.js.map +1 -0
  136. package/dist/useFileProxyUrl-BCcux6re.cjs +87 -0
  137. package/dist/useFileProxyUrl-BCcux6re.cjs.map +1 -0
  138. package/dist/useFileProxyUrl-D_S1R_7O.js +88 -0
  139. package/dist/useFileProxyUrl-D_S1R_7O.js.map +1 -0
  140. package/dist/useMultipartUpload-BKnDbl8h.cjs +423 -0
  141. package/dist/useMultipartUpload-BKnDbl8h.cjs.map +1 -0
  142. package/dist/useMultipartUpload-CPK_PgUU.js +424 -0
  143. package/dist/useMultipartUpload-CPK_PgUU.js.map +1 -0
  144. package/dist/vanilla.cjs +219 -0
  145. package/dist/vanilla.cjs.map +1 -0
  146. package/dist/vanilla.d.ts +94 -0
  147. package/dist/vanilla.d.ts.map +1 -0
  148. package/dist/vanilla.js +220 -0
  149. package/dist/vanilla.js.map +1 -0
  150. package/package.json +177 -0
@@ -0,0 +1,269 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ const DEFAULT_BASE_URL = "https://files.fairu.app";
6
+ class FileProxyBuilder {
7
+ constructor(id, name, baseUrl) {
8
+ __publicField(this, "params", {});
9
+ __publicField(this, "baseUrl");
10
+ this.id = id;
11
+ this.name = name;
12
+ this.baseUrl = baseUrl ?? DEFAULT_BASE_URL;
13
+ }
14
+ /**
15
+ * Set the width in pixels (1-6000).
16
+ */
17
+ width(value) {
18
+ if (value < 1 || value > 6e3) {
19
+ throw new Error("Width must be between 1 and 6000");
20
+ }
21
+ this.params.width = value;
22
+ return this;
23
+ }
24
+ /**
25
+ * Set the height in pixels (1-6000).
26
+ */
27
+ height(value) {
28
+ if (value < 1 || value > 6e3) {
29
+ throw new Error("Height must be between 1 and 6000");
30
+ }
31
+ this.params.height = value;
32
+ return this;
33
+ }
34
+ /**
35
+ * Set dimensions (width and height).
36
+ */
37
+ dimensions(width, height) {
38
+ return this.width(width).height(height);
39
+ }
40
+ /**
41
+ * Set the quality (1-100, default: 95).
42
+ */
43
+ quality(value) {
44
+ if (value < 1 || value > 100) {
45
+ throw new Error("Quality must be between 1 and 100");
46
+ }
47
+ this.params.quality = value;
48
+ return this;
49
+ }
50
+ /**
51
+ * Set the output format.
52
+ */
53
+ format(value) {
54
+ this.params.format = value;
55
+ return this;
56
+ }
57
+ /**
58
+ * Set the fit mode for cropping.
59
+ */
60
+ fit(value) {
61
+ this.params.fit = value;
62
+ return this;
63
+ }
64
+ /**
65
+ * Set the focal point for smart cropping.
66
+ *
67
+ * @param x - X position (0-100%)
68
+ * @param y - Y position (0-100%)
69
+ * @param zoom - Zoom multiplier (1.0-100.0)
70
+ */
71
+ focal(x, y, zoom = 1) {
72
+ if (x < 0 || x > 100) {
73
+ throw new Error("Focal X must be between 0 and 100");
74
+ }
75
+ if (y < 0 || y > 100) {
76
+ throw new Error("Focal Y must be between 0 and 100");
77
+ }
78
+ if (zoom < 1 || zoom > 100) {
79
+ throw new Error("Focal zoom must be between 1 and 100");
80
+ }
81
+ this.params.focal = `${x}-${y}-${zoom}`;
82
+ return this;
83
+ }
84
+ /**
85
+ * Set focal point from a string (e.g., "50-30-1.5" or "50,50").
86
+ */
87
+ focalFromString(value) {
88
+ if (!value) return this;
89
+ if (value.includes(",")) {
90
+ const [x, y] = value.split(",").map(Number);
91
+ if (!isNaN(x) && !isNaN(y)) {
92
+ return this.focal(x, y);
93
+ }
94
+ }
95
+ if (value.includes("-")) {
96
+ const parts = value.split("-").map(Number);
97
+ if (parts.length >= 2 && !parts.some(isNaN)) {
98
+ return this.focal(parts[0], parts[1], parts[2] ?? 1);
99
+ }
100
+ }
101
+ return this;
102
+ }
103
+ /**
104
+ * Return raw/original file without processing.
105
+ */
106
+ raw(value = true) {
107
+ this.params.raw = value;
108
+ return this;
109
+ }
110
+ /**
111
+ * Process SVG to raster WebP.
112
+ */
113
+ processSvg(value = true) {
114
+ this.params.process_svg = value;
115
+ return this;
116
+ }
117
+ /**
118
+ * Set video quality version.
119
+ */
120
+ version(value) {
121
+ this.params.version = value;
122
+ return this;
123
+ }
124
+ /**
125
+ * Set video timestamp for frame extraction.
126
+ *
127
+ * @param value - Timestamp in format HH:MM:SS.mmm
128
+ */
129
+ timestamp(value) {
130
+ this.params.timestamp = value;
131
+ return this;
132
+ }
133
+ /**
134
+ * Set timestamp from seconds.
135
+ */
136
+ timestampFromSeconds(seconds) {
137
+ const hours = Math.floor(seconds / 3600);
138
+ const minutes = Math.floor(seconds % 3600 / 60);
139
+ const secs = seconds % 60;
140
+ const ms = Math.round(seconds % 1 * 1e3);
141
+ const hh = hours.toString().padStart(2, "0");
142
+ const mm = minutes.toString().padStart(2, "0");
143
+ const ss = Math.floor(secs).toString().padStart(2, "0");
144
+ const mmm = ms.toString().padStart(3, "0");
145
+ return this.timestamp(`${hh}:${mm}:${ss}.${mmm}`);
146
+ }
147
+ /**
148
+ * Sign the URL for protected files.
149
+ */
150
+ sign(options) {
151
+ const secretKey = typeof options === "string" ? options : options.secretKey;
152
+ const now = Math.floor(Date.now() / 1e3);
153
+ const pathToSign = `/${this.id}/${this.name}`;
154
+ const stringToSign = `${pathToSign}${now}`;
155
+ const signature = this.createHmacSignature(stringToSign, secretKey);
156
+ this.params.signature = signature;
157
+ this.params.signature_date = now.toString();
158
+ return this;
159
+ }
160
+ /**
161
+ * Create HMAC-SHA256 signature (environment-specific implementation needed).
162
+ */
163
+ createHmacSignature(_data, _key) {
164
+ throw new Error(
165
+ "Synchronous signing not available. Use signAsync() instead or provide pre-computed signature."
166
+ );
167
+ }
168
+ /**
169
+ * Set a pre-computed signature.
170
+ */
171
+ withSignature(signature, signatureDate) {
172
+ this.params.signature = signature;
173
+ this.params.signature_date = typeof signatureDate === "number" ? signatureDate.toString() : signatureDate;
174
+ return this;
175
+ }
176
+ /**
177
+ * Build the URL string.
178
+ */
179
+ build() {
180
+ const path = `${this.baseUrl}/${this.id}/${encodeURIComponent(this.name)}`;
181
+ const queryParams = this.buildQueryString();
182
+ if (queryParams) {
183
+ return `${path}?${queryParams}`;
184
+ }
185
+ return path;
186
+ }
187
+ /**
188
+ * Build the query string from params.
189
+ */
190
+ buildQueryString() {
191
+ const entries = [];
192
+ if (this.params.width !== void 0) {
193
+ entries.push(["width", this.params.width.toString()]);
194
+ }
195
+ if (this.params.height !== void 0) {
196
+ entries.push(["height", this.params.height.toString()]);
197
+ }
198
+ if (this.params.quality !== void 0) {
199
+ entries.push(["quality", this.params.quality.toString()]);
200
+ }
201
+ if (this.params.format !== void 0) {
202
+ entries.push(["format", this.params.format]);
203
+ }
204
+ if (this.params.fit !== void 0) {
205
+ entries.push(["fit", this.params.fit]);
206
+ }
207
+ if (this.params.focal !== void 0) {
208
+ entries.push(["focal", this.params.focal]);
209
+ }
210
+ if (this.params.raw) {
211
+ entries.push(["raw", "true"]);
212
+ }
213
+ if (this.params.process_svg) {
214
+ entries.push(["process_svg", "true"]);
215
+ }
216
+ if (this.params.version !== void 0) {
217
+ entries.push(["version", this.params.version]);
218
+ }
219
+ if (this.params.timestamp !== void 0) {
220
+ entries.push(["timestamp", this.params.timestamp]);
221
+ }
222
+ if (this.params.signature !== void 0) {
223
+ entries.push(["signature", this.params.signature]);
224
+ }
225
+ if (this.params.signature_date !== void 0) {
226
+ entries.push(["signature_date", this.params.signature_date]);
227
+ }
228
+ return entries.map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join("&");
229
+ }
230
+ /**
231
+ * Get the current parameters.
232
+ */
233
+ getParams() {
234
+ return { ...this.params };
235
+ }
236
+ /**
237
+ * Convert to string (alias for build).
238
+ */
239
+ toString() {
240
+ return this.build();
241
+ }
242
+ }
243
+ function fileProxy(id, name, baseUrl) {
244
+ return new FileProxyBuilder(id, name, baseUrl);
245
+ }
246
+ const fileProxyUtils = {
247
+ /**
248
+ * Build a meta URL for getting image dimensions.
249
+ */
250
+ meta(id, baseUrl = DEFAULT_BASE_URL) {
251
+ return `${baseUrl}/meta/${id}`;
252
+ },
253
+ /**
254
+ * Build an HLS video streaming URL.
255
+ */
256
+ hls(tenantId, assetId, path, baseUrl = DEFAULT_BASE_URL) {
257
+ return `${baseUrl}/hls/${tenantId}/${assetId}/${path}`;
258
+ },
259
+ /**
260
+ * Build an HLS decryption key URL.
261
+ */
262
+ hlsKey(id, quality, filename, baseUrl = DEFAULT_BASE_URL) {
263
+ return `${baseUrl}/hls/key/${id}/${quality}/${filename}`;
264
+ }
265
+ };
266
+ exports.FileProxyBuilder = FileProxyBuilder;
267
+ exports.fileProxy = fileProxy;
268
+ exports.fileProxyUtils = fileProxyUtils;
269
+ //# sourceMappingURL=FileProxyBuilder-D-jZpAtd.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileProxyBuilder-D-jZpAtd.cjs","sources":["../src/fileproxy/FileProxyBuilder.ts"],"sourcesContent":["import type {\n FileProxyParams,\n ImageFormat,\n FitMode,\n VideoVersion,\n SignOptions,\n} from './types';\n\n/**\n * Default FileProxy base URL.\n */\nconst DEFAULT_BASE_URL = 'https://files.fairu.app';\n\n/**\n * Fluent builder for constructing FileProxy URLs.\n *\n * @example\n * ```typescript\n * const url = new FileProxyBuilder('asset-uuid', 'image.jpg')\n * .width(800)\n * .height(600)\n * .quality(85)\n * .format('webp')\n * .build();\n *\n * // Result: https://files.fairu.app/asset-uuid/image.jpg?width=800&height=600&quality=85&format=webp\n * ```\n */\nexport class FileProxyBuilder {\n private params: FileProxyParams = {};\n private baseUrl: string;\n\n constructor(\n private readonly id: string,\n private readonly name: string,\n baseUrl?: string\n ) {\n this.baseUrl = baseUrl ?? DEFAULT_BASE_URL;\n }\n\n /**\n * Set the width in pixels (1-6000).\n */\n width(value: number): this {\n if (value < 1 || value > 6000) {\n throw new Error('Width must be between 1 and 6000');\n }\n this.params.width = value;\n return this;\n }\n\n /**\n * Set the height in pixels (1-6000).\n */\n height(value: number): this {\n if (value < 1 || value > 6000) {\n throw new Error('Height must be between 1 and 6000');\n }\n this.params.height = value;\n return this;\n }\n\n /**\n * Set dimensions (width and height).\n */\n dimensions(width: number, height: number): this {\n return this.width(width).height(height);\n }\n\n /**\n * Set the quality (1-100, default: 95).\n */\n quality(value: number): this {\n if (value < 1 || value > 100) {\n throw new Error('Quality must be between 1 and 100');\n }\n this.params.quality = value;\n return this;\n }\n\n /**\n * Set the output format.\n */\n format(value: ImageFormat): this {\n this.params.format = value;\n return this;\n }\n\n /**\n * Set the fit mode for cropping.\n */\n fit(value: FitMode): this {\n this.params.fit = value;\n return this;\n }\n\n /**\n * Set the focal point for smart cropping.\n *\n * @param x - X position (0-100%)\n * @param y - Y position (0-100%)\n * @param zoom - Zoom multiplier (1.0-100.0)\n */\n focal(x: number, y: number, zoom: number = 1): this {\n if (x < 0 || x > 100) {\n throw new Error('Focal X must be between 0 and 100');\n }\n if (y < 0 || y > 100) {\n throw new Error('Focal Y must be between 0 and 100');\n }\n if (zoom < 1 || zoom > 100) {\n throw new Error('Focal zoom must be between 1 and 100');\n }\n this.params.focal = `${x}-${y}-${zoom}`;\n return this;\n }\n\n /**\n * Set focal point from a string (e.g., \"50-30-1.5\" or \"50,50\").\n */\n focalFromString(value: string | null | undefined): this {\n if (!value) return this;\n\n // Handle comma-separated format (e.g., \"50,50\")\n if (value.includes(',')) {\n const [x, y] = value.split(',').map(Number);\n if (!isNaN(x) && !isNaN(y)) {\n return this.focal(x, y);\n }\n }\n\n // Handle dash-separated format (e.g., \"50-30-1.5\")\n if (value.includes('-')) {\n const parts = value.split('-').map(Number);\n if (parts.length >= 2 && !parts.some(isNaN)) {\n return this.focal(parts[0], parts[1], parts[2] ?? 1);\n }\n }\n\n return this;\n }\n\n /**\n * Return raw/original file without processing.\n */\n raw(value: boolean = true): this {\n this.params.raw = value;\n return this;\n }\n\n /**\n * Process SVG to raster WebP.\n */\n processSvg(value: boolean = true): this {\n this.params.process_svg = value;\n return this;\n }\n\n /**\n * Set video quality version.\n */\n version(value: VideoVersion): this {\n this.params.version = value;\n return this;\n }\n\n /**\n * Set video timestamp for frame extraction.\n *\n * @param value - Timestamp in format HH:MM:SS.mmm\n */\n timestamp(value: string): this {\n this.params.timestamp = value;\n return this;\n }\n\n /**\n * Set timestamp from seconds.\n */\n timestampFromSeconds(seconds: number): this {\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = seconds % 60;\n const ms = Math.round((seconds % 1) * 1000);\n\n const hh = hours.toString().padStart(2, '0');\n const mm = minutes.toString().padStart(2, '0');\n const ss = Math.floor(secs).toString().padStart(2, '0');\n const mmm = ms.toString().padStart(3, '0');\n\n return this.timestamp(`${hh}:${mm}:${ss}.${mmm}`);\n }\n\n /**\n * Sign the URL for protected files.\n */\n sign(options: SignOptions | string): this {\n const secretKey = typeof options === 'string' ? options : options.secretKey;\n const now = Math.floor(Date.now() / 1000);\n\n // Build the string to sign\n const pathToSign = `/${this.id}/${this.name}`;\n const stringToSign = `${pathToSign}${now}`;\n\n // Create HMAC-SHA256 signature\n // Note: In browser, you'd use SubtleCrypto. For Node.js, you'd use crypto.\n // This is a placeholder - actual implementation depends on environment.\n const signature = this.createHmacSignature(stringToSign, secretKey);\n\n this.params.signature = signature;\n this.params.signature_date = now.toString();\n\n return this;\n }\n\n /**\n * Create HMAC-SHA256 signature (environment-specific implementation needed).\n */\n private createHmacSignature(_data: string, _key: string): string {\n // This is a placeholder. In a real implementation:\n // - Browser: Use SubtleCrypto API\n // - Node.js: Use crypto module\n // For now, we'll throw an error indicating async signing is needed\n throw new Error(\n 'Synchronous signing not available. Use signAsync() instead or provide pre-computed signature.'\n );\n }\n\n /**\n * Set a pre-computed signature.\n */\n withSignature(signature: string, signatureDate: string | number): this {\n this.params.signature = signature;\n this.params.signature_date =\n typeof signatureDate === 'number'\n ? signatureDate.toString()\n : signatureDate;\n return this;\n }\n\n /**\n * Build the URL string.\n */\n build(): string {\n const path = `${this.baseUrl}/${this.id}/${encodeURIComponent(this.name)}`;\n const queryParams = this.buildQueryString();\n\n if (queryParams) {\n return `${path}?${queryParams}`;\n }\n\n return path;\n }\n\n /**\n * Build the query string from params.\n */\n private buildQueryString(): string {\n const entries: [string, string][] = [];\n\n if (this.params.width !== undefined) {\n entries.push(['width', this.params.width.toString()]);\n }\n if (this.params.height !== undefined) {\n entries.push(['height', this.params.height.toString()]);\n }\n if (this.params.quality !== undefined) {\n entries.push(['quality', this.params.quality.toString()]);\n }\n if (this.params.format !== undefined) {\n entries.push(['format', this.params.format]);\n }\n if (this.params.fit !== undefined) {\n entries.push(['fit', this.params.fit]);\n }\n if (this.params.focal !== undefined) {\n entries.push(['focal', this.params.focal]);\n }\n if (this.params.raw) {\n entries.push(['raw', 'true']);\n }\n if (this.params.process_svg) {\n entries.push(['process_svg', 'true']);\n }\n if (this.params.version !== undefined) {\n entries.push(['version', this.params.version]);\n }\n if (this.params.timestamp !== undefined) {\n entries.push(['timestamp', this.params.timestamp]);\n }\n if (this.params.signature !== undefined) {\n entries.push(['signature', this.params.signature]);\n }\n if (this.params.signature_date !== undefined) {\n entries.push(['signature_date', this.params.signature_date]);\n }\n\n return entries.map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join('&');\n }\n\n /**\n * Get the current parameters.\n */\n getParams(): FileProxyParams {\n return { ...this.params };\n }\n\n /**\n * Convert to string (alias for build).\n */\n toString(): string {\n return this.build();\n }\n}\n\n/**\n * Create a new FileProxyBuilder.\n *\n * @example\n * ```typescript\n * import { fileProxy } from '@fairu/sdk/fileproxy';\n *\n * const url = fileProxy('asset-uuid', 'image.jpg')\n * .width(800)\n * .format('webp')\n * .build();\n * ```\n */\nexport function fileProxy(\n id: string,\n name: string,\n baseUrl?: string\n): FileProxyBuilder {\n return new FileProxyBuilder(id, name, baseUrl);\n}\n\n/**\n * Utility functions for FileProxy.\n */\nexport const fileProxyUtils = {\n /**\n * Build a meta URL for getting image dimensions.\n */\n meta(id: string, baseUrl: string = DEFAULT_BASE_URL): string {\n return `${baseUrl}/meta/${id}`;\n },\n\n /**\n * Build an HLS video streaming URL.\n */\n hls(\n tenantId: string,\n assetId: string,\n path: string,\n baseUrl: string = DEFAULT_BASE_URL\n ): string {\n return `${baseUrl}/hls/${tenantId}/${assetId}/${path}`;\n },\n\n /**\n * Build an HLS decryption key URL.\n */\n hlsKey(\n id: string,\n quality: VideoVersion,\n filename: string,\n baseUrl: string = DEFAULT_BASE_URL\n ): string {\n return `${baseUrl}/hls/key/${id}/${quality}/${filename}`;\n },\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,270 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ const DEFAULT_BASE_URL = "https://files.fairu.app";
5
+ class FileProxyBuilder {
6
+ constructor(id, name, baseUrl) {
7
+ __publicField(this, "params", {});
8
+ __publicField(this, "baseUrl");
9
+ this.id = id;
10
+ this.name = name;
11
+ this.baseUrl = baseUrl ?? DEFAULT_BASE_URL;
12
+ }
13
+ /**
14
+ * Set the width in pixels (1-6000).
15
+ */
16
+ width(value) {
17
+ if (value < 1 || value > 6e3) {
18
+ throw new Error("Width must be between 1 and 6000");
19
+ }
20
+ this.params.width = value;
21
+ return this;
22
+ }
23
+ /**
24
+ * Set the height in pixels (1-6000).
25
+ */
26
+ height(value) {
27
+ if (value < 1 || value > 6e3) {
28
+ throw new Error("Height must be between 1 and 6000");
29
+ }
30
+ this.params.height = value;
31
+ return this;
32
+ }
33
+ /**
34
+ * Set dimensions (width and height).
35
+ */
36
+ dimensions(width, height) {
37
+ return this.width(width).height(height);
38
+ }
39
+ /**
40
+ * Set the quality (1-100, default: 95).
41
+ */
42
+ quality(value) {
43
+ if (value < 1 || value > 100) {
44
+ throw new Error("Quality must be between 1 and 100");
45
+ }
46
+ this.params.quality = value;
47
+ return this;
48
+ }
49
+ /**
50
+ * Set the output format.
51
+ */
52
+ format(value) {
53
+ this.params.format = value;
54
+ return this;
55
+ }
56
+ /**
57
+ * Set the fit mode for cropping.
58
+ */
59
+ fit(value) {
60
+ this.params.fit = value;
61
+ return this;
62
+ }
63
+ /**
64
+ * Set the focal point for smart cropping.
65
+ *
66
+ * @param x - X position (0-100%)
67
+ * @param y - Y position (0-100%)
68
+ * @param zoom - Zoom multiplier (1.0-100.0)
69
+ */
70
+ focal(x, y, zoom = 1) {
71
+ if (x < 0 || x > 100) {
72
+ throw new Error("Focal X must be between 0 and 100");
73
+ }
74
+ if (y < 0 || y > 100) {
75
+ throw new Error("Focal Y must be between 0 and 100");
76
+ }
77
+ if (zoom < 1 || zoom > 100) {
78
+ throw new Error("Focal zoom must be between 1 and 100");
79
+ }
80
+ this.params.focal = `${x}-${y}-${zoom}`;
81
+ return this;
82
+ }
83
+ /**
84
+ * Set focal point from a string (e.g., "50-30-1.5" or "50,50").
85
+ */
86
+ focalFromString(value) {
87
+ if (!value) return this;
88
+ if (value.includes(",")) {
89
+ const [x, y] = value.split(",").map(Number);
90
+ if (!isNaN(x) && !isNaN(y)) {
91
+ return this.focal(x, y);
92
+ }
93
+ }
94
+ if (value.includes("-")) {
95
+ const parts = value.split("-").map(Number);
96
+ if (parts.length >= 2 && !parts.some(isNaN)) {
97
+ return this.focal(parts[0], parts[1], parts[2] ?? 1);
98
+ }
99
+ }
100
+ return this;
101
+ }
102
+ /**
103
+ * Return raw/original file without processing.
104
+ */
105
+ raw(value = true) {
106
+ this.params.raw = value;
107
+ return this;
108
+ }
109
+ /**
110
+ * Process SVG to raster WebP.
111
+ */
112
+ processSvg(value = true) {
113
+ this.params.process_svg = value;
114
+ return this;
115
+ }
116
+ /**
117
+ * Set video quality version.
118
+ */
119
+ version(value) {
120
+ this.params.version = value;
121
+ return this;
122
+ }
123
+ /**
124
+ * Set video timestamp for frame extraction.
125
+ *
126
+ * @param value - Timestamp in format HH:MM:SS.mmm
127
+ */
128
+ timestamp(value) {
129
+ this.params.timestamp = value;
130
+ return this;
131
+ }
132
+ /**
133
+ * Set timestamp from seconds.
134
+ */
135
+ timestampFromSeconds(seconds) {
136
+ const hours = Math.floor(seconds / 3600);
137
+ const minutes = Math.floor(seconds % 3600 / 60);
138
+ const secs = seconds % 60;
139
+ const ms = Math.round(seconds % 1 * 1e3);
140
+ const hh = hours.toString().padStart(2, "0");
141
+ const mm = minutes.toString().padStart(2, "0");
142
+ const ss = Math.floor(secs).toString().padStart(2, "0");
143
+ const mmm = ms.toString().padStart(3, "0");
144
+ return this.timestamp(`${hh}:${mm}:${ss}.${mmm}`);
145
+ }
146
+ /**
147
+ * Sign the URL for protected files.
148
+ */
149
+ sign(options) {
150
+ const secretKey = typeof options === "string" ? options : options.secretKey;
151
+ const now = Math.floor(Date.now() / 1e3);
152
+ const pathToSign = `/${this.id}/${this.name}`;
153
+ const stringToSign = `${pathToSign}${now}`;
154
+ const signature = this.createHmacSignature(stringToSign, secretKey);
155
+ this.params.signature = signature;
156
+ this.params.signature_date = now.toString();
157
+ return this;
158
+ }
159
+ /**
160
+ * Create HMAC-SHA256 signature (environment-specific implementation needed).
161
+ */
162
+ createHmacSignature(_data, _key) {
163
+ throw new Error(
164
+ "Synchronous signing not available. Use signAsync() instead or provide pre-computed signature."
165
+ );
166
+ }
167
+ /**
168
+ * Set a pre-computed signature.
169
+ */
170
+ withSignature(signature, signatureDate) {
171
+ this.params.signature = signature;
172
+ this.params.signature_date = typeof signatureDate === "number" ? signatureDate.toString() : signatureDate;
173
+ return this;
174
+ }
175
+ /**
176
+ * Build the URL string.
177
+ */
178
+ build() {
179
+ const path = `${this.baseUrl}/${this.id}/${encodeURIComponent(this.name)}`;
180
+ const queryParams = this.buildQueryString();
181
+ if (queryParams) {
182
+ return `${path}?${queryParams}`;
183
+ }
184
+ return path;
185
+ }
186
+ /**
187
+ * Build the query string from params.
188
+ */
189
+ buildQueryString() {
190
+ const entries = [];
191
+ if (this.params.width !== void 0) {
192
+ entries.push(["width", this.params.width.toString()]);
193
+ }
194
+ if (this.params.height !== void 0) {
195
+ entries.push(["height", this.params.height.toString()]);
196
+ }
197
+ if (this.params.quality !== void 0) {
198
+ entries.push(["quality", this.params.quality.toString()]);
199
+ }
200
+ if (this.params.format !== void 0) {
201
+ entries.push(["format", this.params.format]);
202
+ }
203
+ if (this.params.fit !== void 0) {
204
+ entries.push(["fit", this.params.fit]);
205
+ }
206
+ if (this.params.focal !== void 0) {
207
+ entries.push(["focal", this.params.focal]);
208
+ }
209
+ if (this.params.raw) {
210
+ entries.push(["raw", "true"]);
211
+ }
212
+ if (this.params.process_svg) {
213
+ entries.push(["process_svg", "true"]);
214
+ }
215
+ if (this.params.version !== void 0) {
216
+ entries.push(["version", this.params.version]);
217
+ }
218
+ if (this.params.timestamp !== void 0) {
219
+ entries.push(["timestamp", this.params.timestamp]);
220
+ }
221
+ if (this.params.signature !== void 0) {
222
+ entries.push(["signature", this.params.signature]);
223
+ }
224
+ if (this.params.signature_date !== void 0) {
225
+ entries.push(["signature_date", this.params.signature_date]);
226
+ }
227
+ return entries.map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join("&");
228
+ }
229
+ /**
230
+ * Get the current parameters.
231
+ */
232
+ getParams() {
233
+ return { ...this.params };
234
+ }
235
+ /**
236
+ * Convert to string (alias for build).
237
+ */
238
+ toString() {
239
+ return this.build();
240
+ }
241
+ }
242
+ function fileProxy(id, name, baseUrl) {
243
+ return new FileProxyBuilder(id, name, baseUrl);
244
+ }
245
+ const fileProxyUtils = {
246
+ /**
247
+ * Build a meta URL for getting image dimensions.
248
+ */
249
+ meta(id, baseUrl = DEFAULT_BASE_URL) {
250
+ return `${baseUrl}/meta/${id}`;
251
+ },
252
+ /**
253
+ * Build an HLS video streaming URL.
254
+ */
255
+ hls(tenantId, assetId, path, baseUrl = DEFAULT_BASE_URL) {
256
+ return `${baseUrl}/hls/${tenantId}/${assetId}/${path}`;
257
+ },
258
+ /**
259
+ * Build an HLS decryption key URL.
260
+ */
261
+ hlsKey(id, quality, filename, baseUrl = DEFAULT_BASE_URL) {
262
+ return `${baseUrl}/hls/key/${id}/${quality}/${filename}`;
263
+ }
264
+ };
265
+ export {
266
+ FileProxyBuilder as F,
267
+ fileProxyUtils as a,
268
+ fileProxy as f
269
+ };
270
+ //# sourceMappingURL=FileProxyBuilder-vHw1zBpJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileProxyBuilder-vHw1zBpJ.js","sources":["../src/fileproxy/FileProxyBuilder.ts"],"sourcesContent":["import type {\n FileProxyParams,\n ImageFormat,\n FitMode,\n VideoVersion,\n SignOptions,\n} from './types';\n\n/**\n * Default FileProxy base URL.\n */\nconst DEFAULT_BASE_URL = 'https://files.fairu.app';\n\n/**\n * Fluent builder for constructing FileProxy URLs.\n *\n * @example\n * ```typescript\n * const url = new FileProxyBuilder('asset-uuid', 'image.jpg')\n * .width(800)\n * .height(600)\n * .quality(85)\n * .format('webp')\n * .build();\n *\n * // Result: https://files.fairu.app/asset-uuid/image.jpg?width=800&height=600&quality=85&format=webp\n * ```\n */\nexport class FileProxyBuilder {\n private params: FileProxyParams = {};\n private baseUrl: string;\n\n constructor(\n private readonly id: string,\n private readonly name: string,\n baseUrl?: string\n ) {\n this.baseUrl = baseUrl ?? DEFAULT_BASE_URL;\n }\n\n /**\n * Set the width in pixels (1-6000).\n */\n width(value: number): this {\n if (value < 1 || value > 6000) {\n throw new Error('Width must be between 1 and 6000');\n }\n this.params.width = value;\n return this;\n }\n\n /**\n * Set the height in pixels (1-6000).\n */\n height(value: number): this {\n if (value < 1 || value > 6000) {\n throw new Error('Height must be between 1 and 6000');\n }\n this.params.height = value;\n return this;\n }\n\n /**\n * Set dimensions (width and height).\n */\n dimensions(width: number, height: number): this {\n return this.width(width).height(height);\n }\n\n /**\n * Set the quality (1-100, default: 95).\n */\n quality(value: number): this {\n if (value < 1 || value > 100) {\n throw new Error('Quality must be between 1 and 100');\n }\n this.params.quality = value;\n return this;\n }\n\n /**\n * Set the output format.\n */\n format(value: ImageFormat): this {\n this.params.format = value;\n return this;\n }\n\n /**\n * Set the fit mode for cropping.\n */\n fit(value: FitMode): this {\n this.params.fit = value;\n return this;\n }\n\n /**\n * Set the focal point for smart cropping.\n *\n * @param x - X position (0-100%)\n * @param y - Y position (0-100%)\n * @param zoom - Zoom multiplier (1.0-100.0)\n */\n focal(x: number, y: number, zoom: number = 1): this {\n if (x < 0 || x > 100) {\n throw new Error('Focal X must be between 0 and 100');\n }\n if (y < 0 || y > 100) {\n throw new Error('Focal Y must be between 0 and 100');\n }\n if (zoom < 1 || zoom > 100) {\n throw new Error('Focal zoom must be between 1 and 100');\n }\n this.params.focal = `${x}-${y}-${zoom}`;\n return this;\n }\n\n /**\n * Set focal point from a string (e.g., \"50-30-1.5\" or \"50,50\").\n */\n focalFromString(value: string | null | undefined): this {\n if (!value) return this;\n\n // Handle comma-separated format (e.g., \"50,50\")\n if (value.includes(',')) {\n const [x, y] = value.split(',').map(Number);\n if (!isNaN(x) && !isNaN(y)) {\n return this.focal(x, y);\n }\n }\n\n // Handle dash-separated format (e.g., \"50-30-1.5\")\n if (value.includes('-')) {\n const parts = value.split('-').map(Number);\n if (parts.length >= 2 && !parts.some(isNaN)) {\n return this.focal(parts[0], parts[1], parts[2] ?? 1);\n }\n }\n\n return this;\n }\n\n /**\n * Return raw/original file without processing.\n */\n raw(value: boolean = true): this {\n this.params.raw = value;\n return this;\n }\n\n /**\n * Process SVG to raster WebP.\n */\n processSvg(value: boolean = true): this {\n this.params.process_svg = value;\n return this;\n }\n\n /**\n * Set video quality version.\n */\n version(value: VideoVersion): this {\n this.params.version = value;\n return this;\n }\n\n /**\n * Set video timestamp for frame extraction.\n *\n * @param value - Timestamp in format HH:MM:SS.mmm\n */\n timestamp(value: string): this {\n this.params.timestamp = value;\n return this;\n }\n\n /**\n * Set timestamp from seconds.\n */\n timestampFromSeconds(seconds: number): this {\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = seconds % 60;\n const ms = Math.round((seconds % 1) * 1000);\n\n const hh = hours.toString().padStart(2, '0');\n const mm = minutes.toString().padStart(2, '0');\n const ss = Math.floor(secs).toString().padStart(2, '0');\n const mmm = ms.toString().padStart(3, '0');\n\n return this.timestamp(`${hh}:${mm}:${ss}.${mmm}`);\n }\n\n /**\n * Sign the URL for protected files.\n */\n sign(options: SignOptions | string): this {\n const secretKey = typeof options === 'string' ? options : options.secretKey;\n const now = Math.floor(Date.now() / 1000);\n\n // Build the string to sign\n const pathToSign = `/${this.id}/${this.name}`;\n const stringToSign = `${pathToSign}${now}`;\n\n // Create HMAC-SHA256 signature\n // Note: In browser, you'd use SubtleCrypto. For Node.js, you'd use crypto.\n // This is a placeholder - actual implementation depends on environment.\n const signature = this.createHmacSignature(stringToSign, secretKey);\n\n this.params.signature = signature;\n this.params.signature_date = now.toString();\n\n return this;\n }\n\n /**\n * Create HMAC-SHA256 signature (environment-specific implementation needed).\n */\n private createHmacSignature(_data: string, _key: string): string {\n // This is a placeholder. In a real implementation:\n // - Browser: Use SubtleCrypto API\n // - Node.js: Use crypto module\n // For now, we'll throw an error indicating async signing is needed\n throw new Error(\n 'Synchronous signing not available. Use signAsync() instead or provide pre-computed signature.'\n );\n }\n\n /**\n * Set a pre-computed signature.\n */\n withSignature(signature: string, signatureDate: string | number): this {\n this.params.signature = signature;\n this.params.signature_date =\n typeof signatureDate === 'number'\n ? signatureDate.toString()\n : signatureDate;\n return this;\n }\n\n /**\n * Build the URL string.\n */\n build(): string {\n const path = `${this.baseUrl}/${this.id}/${encodeURIComponent(this.name)}`;\n const queryParams = this.buildQueryString();\n\n if (queryParams) {\n return `${path}?${queryParams}`;\n }\n\n return path;\n }\n\n /**\n * Build the query string from params.\n */\n private buildQueryString(): string {\n const entries: [string, string][] = [];\n\n if (this.params.width !== undefined) {\n entries.push(['width', this.params.width.toString()]);\n }\n if (this.params.height !== undefined) {\n entries.push(['height', this.params.height.toString()]);\n }\n if (this.params.quality !== undefined) {\n entries.push(['quality', this.params.quality.toString()]);\n }\n if (this.params.format !== undefined) {\n entries.push(['format', this.params.format]);\n }\n if (this.params.fit !== undefined) {\n entries.push(['fit', this.params.fit]);\n }\n if (this.params.focal !== undefined) {\n entries.push(['focal', this.params.focal]);\n }\n if (this.params.raw) {\n entries.push(['raw', 'true']);\n }\n if (this.params.process_svg) {\n entries.push(['process_svg', 'true']);\n }\n if (this.params.version !== undefined) {\n entries.push(['version', this.params.version]);\n }\n if (this.params.timestamp !== undefined) {\n entries.push(['timestamp', this.params.timestamp]);\n }\n if (this.params.signature !== undefined) {\n entries.push(['signature', this.params.signature]);\n }\n if (this.params.signature_date !== undefined) {\n entries.push(['signature_date', this.params.signature_date]);\n }\n\n return entries.map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join('&');\n }\n\n /**\n * Get the current parameters.\n */\n getParams(): FileProxyParams {\n return { ...this.params };\n }\n\n /**\n * Convert to string (alias for build).\n */\n toString(): string {\n return this.build();\n }\n}\n\n/**\n * Create a new FileProxyBuilder.\n *\n * @example\n * ```typescript\n * import { fileProxy } from '@fairu/sdk/fileproxy';\n *\n * const url = fileProxy('asset-uuid', 'image.jpg')\n * .width(800)\n * .format('webp')\n * .build();\n * ```\n */\nexport function fileProxy(\n id: string,\n name: string,\n baseUrl?: string\n): FileProxyBuilder {\n return new FileProxyBuilder(id, name, baseUrl);\n}\n\n/**\n * Utility functions for FileProxy.\n */\nexport const fileProxyUtils = {\n /**\n * Build a meta URL for getting image dimensions.\n */\n meta(id: string, baseUrl: string = DEFAULT_BASE_URL): string {\n return `${baseUrl}/meta/${id}`;\n },\n\n /**\n * Build an HLS video streaming URL.\n */\n hls(\n tenantId: string,\n assetId: string,\n path: string,\n baseUrl: string = DEFAULT_BASE_URL\n ): string {\n return `${baseUrl}/hls/${tenantId}/${assetId}/${path}`;\n },\n\n /**\n * Build an HLS decryption key URL.\n */\n hlsKey(\n id: string,\n quality: VideoVersion,\n filename: string,\n baseUrl: string = DEFAULT_BASE_URL\n ): string {\n return `${baseUrl}/hls/key/${id}/${quality}/${filename}`;\n },\n};\n"],"names":[],"mappings":"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"}