@devultur/convex 1.4.1 → 1.4.3

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 (67) hide show
  1. package/README.md +6 -1
  2. package/dist/chunk-JZYKPLI4.js +185 -0
  3. package/dist/{chunk-EX3W77VY.js → chunk-YYOZ3PDH.js} +16 -3
  4. package/dist/component/_generated/api.d.ts +0 -1
  5. package/dist/component/_generated/api.js.map +1 -1
  6. package/dist/component/_generated/component.d.ts +0 -1
  7. package/dist/component/_generated/component.js.map +1 -1
  8. package/dist/component/_generated/dataModel.d.ts +0 -1
  9. package/dist/component/_generated/dataModel.js.map +1 -1
  10. package/dist/component/_generated/server.d.ts +0 -1
  11. package/dist/component/_generated/server.js.map +1 -1
  12. package/dist/component/convex.config.d.ts +0 -1
  13. package/dist/component/convex.config.js.map +1 -1
  14. package/dist/component/http.d.ts +0 -1
  15. package/dist/component/http.js.map +1 -1
  16. package/dist/component/library.d.ts +0 -1
  17. package/dist/component/library.js.map +1 -1
  18. package/dist/component/lock.d.ts +0 -1
  19. package/dist/component/lock.js.map +1 -1
  20. package/dist/component/lockValidators.d.ts +0 -1
  21. package/dist/component/lockValidators.js.map +1 -1
  22. package/dist/component/mediaClient.d.ts +0 -1
  23. package/dist/component/mediaClient.js.map +1 -1
  24. package/dist/component/mediaMeta.d.ts +0 -1
  25. package/dist/component/mediaMeta.js.map +1 -1
  26. package/dist/component/metadata.d.ts +0 -1
  27. package/dist/component/metadata.js.map +1 -1
  28. package/dist/component/public.d.ts +0 -1
  29. package/dist/component/public.js.map +1 -1
  30. package/dist/component/schema.d.ts +0 -1
  31. package/dist/component/schema.js.map +1 -1
  32. package/dist/component/uploadKeys.d.ts +0 -1
  33. package/dist/component/uploadKeys.js.map +1 -1
  34. package/dist/component/uploads.d.ts +0 -1
  35. package/dist/component/uploads.js.map +1 -1
  36. package/dist/component/workerErrors.d.ts +0 -1
  37. package/dist/component/workerErrors.js.map +1 -1
  38. package/dist/{error-labels-BfqcFh2R.d.ts → error-labels-D0Vbp-qA.d.ts} +1 -1
  39. package/dist/index.d.ts +12 -8
  40. package/dist/index.js +1 -1
  41. package/dist/locales/es-formal.d.ts +14 -0
  42. package/dist/locales/es-formal.js +64 -0
  43. package/dist/locales/es.d.ts +7 -4
  44. package/dist/locales/es.js +10 -156
  45. package/dist/{media-picker-labels-CiVcNUZo.d.ts → preview-labels-B7HNa7Va.d.ts} +59 -2
  46. package/dist/react.d.ts +24 -64
  47. package/dist/react.js +37 -17
  48. package/dist/types-DZxN6Eij.d.ts +190 -0
  49. package/package.json +9 -4
  50. package/dist/component/_generated/api.d.ts.map +0 -1
  51. package/dist/component/_generated/component.d.ts.map +0 -1
  52. package/dist/component/_generated/dataModel.d.ts.map +0 -1
  53. package/dist/component/_generated/server.d.ts.map +0 -1
  54. package/dist/component/convex.config.d.ts.map +0 -1
  55. package/dist/component/http.d.ts.map +0 -1
  56. package/dist/component/library.d.ts.map +0 -1
  57. package/dist/component/lock.d.ts.map +0 -1
  58. package/dist/component/lockValidators.d.ts.map +0 -1
  59. package/dist/component/mediaClient.d.ts.map +0 -1
  60. package/dist/component/mediaMeta.d.ts.map +0 -1
  61. package/dist/component/metadata.d.ts.map +0 -1
  62. package/dist/component/public.d.ts.map +0 -1
  63. package/dist/component/schema.d.ts.map +0 -1
  64. package/dist/component/uploadKeys.d.ts.map +0 -1
  65. package/dist/component/uploads.d.ts.map +0 -1
  66. package/dist/component/workerErrors.d.ts.map +0 -1
  67. package/dist/types-LrusGVDf.d.ts +0 -62
package/README.md CHANGED
@@ -654,7 +654,12 @@ any other error, so your app keeps its own fallback. A code it doesn't know gets
654
654
  `devulturErrorLabels` is the English map, typed `Record<DevulturErrorCode, string | ((details) => string)>`:
655
655
  `DevulturErrorCode` is the union of every stable code (`DEVULTUR_ERROR_CODES` lists them), and a function label reads
656
656
  the error's details, such as `file_too_large`'s `limit`. `@devultur/convex/locales/es` exports the Spanish map under
657
- the same name:
657
+ the same name.
658
+
659
+ `@devultur/convex/locales/es` addresses the reader with «tú» ("Vuelve a intentarlo"). For «usted» ("Vuelva a
660
+ intentarlo", "No tiene permiso…"), import the same names from `@devultur/convex/locales/es-formal`: it exports exactly
661
+ what `locales/es` does (error, attachment, preview, library and picker labels), and differs only in the strings that
662
+ address the reader.
658
663
 
659
664
  ```tsx
660
665
  import { describeDevulturError } from "@devultur/convex";
@@ -0,0 +1,185 @@
1
+ import {
2
+ formatDuration,
3
+ formatFileSize
4
+ } from "./chunk-QBHIZBOQ.js";
5
+ import {
6
+ describeDevulturError,
7
+ formatBytes,
8
+ formatDate,
9
+ labelText
10
+ } from "./chunk-YYOZ3PDH.js";
11
+
12
+ // src/locales/es.ts
13
+ var LOCALE = "es";
14
+ var devulturErrorLabels = {
15
+ file_too_large: (details) => {
16
+ const limit = typeof details.limit === "number" ? formatBytes(details.limit, LOCALE) : null;
17
+ return limit ? `El archivo supera el tama\xF1o m\xE1ximo (${limit}).` : "El archivo supera el tama\xF1o m\xE1ximo.";
18
+ },
19
+ content_type_not_allowed: "Este tipo de archivo no est\xE1 permitido.",
20
+ content_type_mismatch: "El contenido del archivo no coincide con su tipo.",
21
+ content_unverified: "No se pudo verificar la subida. Vuelve a intentarlo.",
22
+ unsupported_content_type: "Este tipo de archivo no es compatible.",
23
+ media_type_mismatch: "El tipo de archivo no coincide con el tipo de contenido esperado.",
24
+ already_exists: "Ya existe un archivo con este nombre.",
25
+ write_conflict: "El archivo cambi\xF3 mientras se guardaba. Vuelve a intentarlo.",
26
+ upload_not_found: "No se encontr\xF3 la subida o ya venci\xF3. Vuelve a empezarla.",
27
+ invalid_upload_key: "Esta subida no es v\xE1lida.",
28
+ invalid_path: "La ruta del archivo no es v\xE1lida.",
29
+ path_required: "Esta subida necesita una ruta de archivo.",
30
+ invalid_expires_in: "El tiempo de vencimiento no es v\xE1lido.",
31
+ invalid_file_expires_in: "El tiempo de vencimiento del archivo no es v\xE1lido.",
32
+ invalid_cache_control: "La configuraci\xF3n de cach\xE9 no es v\xE1lida.",
33
+ invalid_limits: "Los l\xEDmites de la subida no son v\xE1lidos.",
34
+ invalid_prefix: "La carpeta no es v\xE1lida.",
35
+ invalid_visibility: "La visibilidad debe ser p\xFAblica o privada.",
36
+ invalid_cursor: "La p\xE1gina de resultados no es v\xE1lida. Vuelve a cargar la lista.",
37
+ invalid_sha256: "La suma de verificaci\xF3n del archivo no es v\xE1lida.",
38
+ sha256_mismatch: "El archivo se da\xF1\xF3 durante la subida. Vuelve a intentarlo.",
39
+ max_files_reached: "Alcanzaste el n\xFAmero m\xE1ximo de archivos para esta subida.",
40
+ invalid_multipart: "La solicitud de subida no es v\xE1lida.",
41
+ invalid_size: "El tama\xF1o del archivo no es v\xE1lido.",
42
+ invalid_part: "Una parte de la subida no es v\xE1lida. Vuelve a intentarlo.",
43
+ invalid_parts: "La subida est\xE1 incompleta. Vuelve a intentarlo.",
44
+ part_size_mismatch: "Una parte de la subida tiene un tama\xF1o incorrecto. Vuelve a intentarlo.",
45
+ part_sha256_required: "A una parte de la subida le falta la suma de verificaci\xF3n.",
46
+ invalid_media_metadata: (details) => {
47
+ if (details.field === "title") return "El t\xEDtulo no puede tener m\xE1s de 200 caracteres.";
48
+ if (details.field === "alt") return "El texto alternativo no puede tener m\xE1s de 1000 caracteres.";
49
+ if (details.field === "tags") return "Usa como m\xE1ximo 20 etiquetas, de hasta 50 caracteres cada una.";
50
+ return "Los datos del archivo no son v\xE1lidos.";
51
+ },
52
+ expired: "Este archivo ya venci\xF3.",
53
+ invalid_key: "La referencia del archivo no es v\xE1lida.",
54
+ invalid_max_uses: "El n\xFAmero de usos no es v\xE1lido.",
55
+ link_exists: "Este enlace de descarga ya existe.",
56
+ link_not_found: "Este enlace de descarga no existe.",
57
+ link_expired: "Este enlace de descarga ya venci\xF3.",
58
+ link_used: "Este enlace de descarga ya se us\xF3.",
59
+ not_configured: "Esta funci\xF3n no est\xE1 configurada.",
60
+ retention_active: (details) => {
61
+ if (details.hold === true) return "Este archivo tiene una retenci\xF3n legal y no se puede modificar ni eliminar.";
62
+ const until = formatDate(details.until, LOCALE);
63
+ return until ? `Este archivo est\xE1 protegido hasta el ${until} y no se puede modificar ni eliminar antes de esa fecha.` : "Este archivo est\xE1 protegido y no se puede modificar ni eliminar.";
64
+ },
65
+ lock_conflict: "La protecci\xF3n del archivo cambi\xF3 mientras tanto. Vuelve a intentarlo.",
66
+ compliance_extend_only: "La protecci\xF3n de este archivo solo se puede extender.",
67
+ lock_privilege_required: "No tienes permiso para acortar ni quitar la protecci\xF3n de este archivo.",
68
+ lock_record_unreadable: "No se pudo leer la protecci\xF3n del archivo.",
69
+ lock_below_minimum: "Esta subida requiere una protecci\xF3n m\xE1s estricta.",
70
+ invalid_lock: "La configuraci\xF3n de protecci\xF3n no es v\xE1lida.",
71
+ invalid_hold: "La configuraci\xF3n de retenci\xF3n legal no es v\xE1lida.",
72
+ reserved_key: "Este nombre de archivo est\xE1 reservado.",
73
+ keys_bucket_missing: "En este momento no se pueden guardar archivos de forma segura.",
74
+ encryption_key_missing: "Este archivo ya no se puede leer. Vuelve a subirlo.",
75
+ unauthorized: "No tienes autorizaci\xF3n para hacer esto.",
76
+ session_mismatch: "Tu sesi\xF3n cambi\xF3. Vuelve a cargar la p\xE1gina.",
77
+ token_rejected: "Se deneg\xF3 el acceso.",
78
+ reserved_user_id: "Este identificador de usuario est\xE1 reservado.",
79
+ invalid_scopes: "Los permisos solicitados no son v\xE1lidos.",
80
+ user_mismatch: "Solo puedes ver y cambiar tu propio progreso.",
81
+ transcode_not_configured: "El procesamiento de video no est\xE1 configurado.",
82
+ transcode_runner_unavailable: "El procesamiento de video est\xE1 ocupado en este momento. Vuelve a intentarlo m\xE1s tarde.",
83
+ transcode_launch_failed: "No se pudo procesar el video.",
84
+ original_not_retained: "El video original ya no est\xE1 disponible, as\xED que no se puede volver a procesar. Vuelve a subirlo.",
85
+ locale_not_allowed: "Los subt\xEDtulos no est\xE1n disponibles en este idioma.",
86
+ captions_provider_rate_limited: "El servicio de subt\xEDtulos est\xE1 ocupado en este momento. Vuelve a intentarlo m\xE1s tarde.",
87
+ captions_provider_error: "No se pudieron generar los subt\xEDtulos.",
88
+ captions_failed: "No se pudieron generar los subt\xEDtulos.",
89
+ webhook_secret_missing: "El procesamiento de video no est\xE1 configurado.",
90
+ worker_auth_secret_missing: "El servicio de medios no est\xE1 configurado.",
91
+ worker_error: "El servicio de medios no pudo completar la solicitud.",
92
+ http_error: "No se pudo cargar el archivo.",
93
+ too_large: "El archivo es demasiado grande para la vista previa.",
94
+ unsupported_type: "Este tipo de archivo no tiene vista previa.",
95
+ type_mismatch: "El contenido del archivo no coincide con su tipo.",
96
+ token_unavailable: "No se pudo autorizar el acceso a este archivo. Vuelve a intentarlo.",
97
+ page_cap: (details) => {
98
+ const { shown, total } = details;
99
+ if (typeof shown !== "number" || typeof total !== "number") return "Solo se muestran las primeras p\xE1ginas.";
100
+ return `Solo se muestran las primeras ${shown.toLocaleString(LOCALE)} de ${total.toLocaleString(LOCALE)} p\xE1ginas.`;
101
+ },
102
+ render_failed: "No se pudo mostrar el archivo.",
103
+ capability_unavailable: "Esta aplicaci\xF3n no puede hacer eso aqu\xED."
104
+ };
105
+ var previewLabels = {
106
+ document: (title, pageCount) => `${title}, ${pagesText(pageCount)}`,
107
+ page: (page, pageCount) => `P\xE1gina ${page} de ${pageCount}`,
108
+ loading: "Cargando\u2026",
109
+ pageCap: (shown, total) => `Se muestran las primeras ${shown} de ${total} p\xE1ginas.`,
110
+ error: (code) => code === "page_cap" ? "Descarga el archivo para ver todas las p\xE1ginas." : labelText(devulturErrorLabels[code]),
111
+ thumbnail: (title) => title,
112
+ untitledPdf: "PDF",
113
+ untitledMedia: "Vista previa",
114
+ download: "Descargar"
115
+ };
116
+ function pagesText(pageCount) {
117
+ return pageCount === 1 ? "1 p\xE1gina" : `${pageCount.toLocaleString(LOCALE)} p\xE1ginas`;
118
+ }
119
+ var KIND_TEXT = {
120
+ image: "Imagen",
121
+ video: "Video",
122
+ pdf: "PDF",
123
+ audio: "Audio",
124
+ text: "Texto",
125
+ file: "Archivo"
126
+ };
127
+ var attachmentLabels = {
128
+ locale: LOCALE,
129
+ size: formatFileSize,
130
+ pages: pagesText,
131
+ duration: formatDuration,
132
+ kind: (kind) => KIND_TEXT[kind],
133
+ download: "Descargar",
134
+ open: "Abrir vista previa",
135
+ untitled: "Archivo sin t\xEDtulo"
136
+ };
137
+ var mediaLibraryLabels = {
138
+ search: "Buscar archivos",
139
+ searchPlaceholder: "Busca por t\xEDtulo o nombre de archivo",
140
+ typeFilter: "Tipo",
141
+ allTypes: "Todos los tipos",
142
+ types: { image: "Im\xE1genes", video: "Videos", file: "Archivos" },
143
+ results: "Archivos",
144
+ loading: "Cargando archivos\u2026",
145
+ empty: "Todav\xEDa no hay archivos.",
146
+ noResults: (search) => `Nada coincide con \xAB${search}\xBB.`,
147
+ loadMore: "Cargar m\xE1s",
148
+ loadingMore: "Cargando\u2026",
149
+ error: (error) => describeDevulturError(error, devulturErrorLabels) ?? "No se pudieron cargar los archivos.",
150
+ retry: "Reintentar",
151
+ size: (bytes) => formatFileSize(bytes, LOCALE)
152
+ };
153
+ var mediaPickerLabels = {
154
+ upload: (multiple) => multiple ? "Subir archivos" : "Subir un archivo",
155
+ dropHint: (multiple) => multiple ? "o suelta los archivos aqu\xED" : "o suelta un archivo aqu\xED",
156
+ uploads: "Subidas",
157
+ progress: (filename) => `Subiendo ${filename}`,
158
+ percent: (percent) => `${percent} %`,
159
+ uploading: (filename) => `Subiendo ${filename}.`,
160
+ uploaded: (filename) => `${filename} se subi\xF3 y qued\xF3 seleccionado.`,
161
+ cancel: "Cancelar",
162
+ cancelUpload: (filename) => `Cancelar la subida de ${filename}`,
163
+ cancelled: (filename) => `Se cancel\xF3 la subida de ${filename}.`,
164
+ notAccepted: (filename) => `${filename} no es un tipo de archivo que se pueda elegir aqu\xED.`,
165
+ uploadError: (error) => describeDevulturError(error, devulturErrorLabels) ?? "La subida fall\xF3. Vuelve a intentarlo.",
166
+ retry: "Reintentar",
167
+ dismiss: "Descartar",
168
+ selection: "Archivos seleccionados",
169
+ empty: "No hay nada seleccionado.",
170
+ remove: "Quitar",
171
+ removeItem: (name) => `Quitar ${name}`,
172
+ clear: "Limpiar",
173
+ replace: "Reemplazar",
174
+ selected: (name) => `${name} seleccionado.`,
175
+ removed: (name) => `${name} se quit\xF3.`,
176
+ cleared: "Se limpi\xF3 la selecci\xF3n."
177
+ };
178
+
179
+ export {
180
+ devulturErrorLabels,
181
+ previewLabels,
182
+ attachmentLabels,
183
+ mediaLibraryLabels,
184
+ mediaPickerLabels
185
+ };
@@ -81,6 +81,8 @@ var DEVULTUR_ERROR_CODES = [
81
81
  "unsupported_type",
82
82
  "type_mismatch",
83
83
  "token_unavailable",
84
+ "page_cap",
85
+ "render_failed",
84
86
  // `DevulturCapabilityError` (an action the provider wasn't given)
85
87
  "capability_unavailable"
86
88
  ];
@@ -104,6 +106,9 @@ function devulturErrorOf(error) {
104
106
  }
105
107
 
106
108
  // src/error-labels.ts
109
+ function labelText(label, details = {}) {
110
+ return typeof label === "function" ? label(details) : label;
111
+ }
107
112
  function formatBytes(bytes, locale) {
108
113
  const isMegabytes = bytes >= 1e6;
109
114
  const amount = isMegabytes ? bytes / 1e6 : bytes / 1e3;
@@ -202,6 +207,12 @@ var devulturErrorLabels = {
202
207
  unsupported_type: "This file type can't be previewed.",
203
208
  type_mismatch: "The file's content doesn't match its type.",
204
209
  token_unavailable: "Access to this file couldn't be granted. Try again.",
210
+ page_cap: (details) => {
211
+ const { shown, total } = details;
212
+ if (typeof shown !== "number" || typeof total !== "number") return "Only the first pages are shown.";
213
+ return `Only the first ${shown.toLocaleString("en")} of ${total.toLocaleString("en")} pages are shown.`;
214
+ },
215
+ render_failed: "The file couldn't be displayed.",
205
216
  capability_unavailable: "This app can't do that here."
206
217
  };
207
218
  function asRecord(value) {
@@ -211,7 +222,9 @@ function codedErrorOf(error) {
211
222
  if (!(error instanceof Error)) return null;
212
223
  const { code, status, details, limit } = error;
213
224
  const statusField = typeof status === "number" ? { status } : {};
214
- if (error.name === "MediaFetchError" && typeof code === "string") return { code, details: statusField };
225
+ if (error.name === "MediaFetchError" && typeof code === "string") {
226
+ return { code, details: { ...asRecord(details), ...statusField } };
227
+ }
215
228
  if (error.name === "DevulturCapabilityError") return { code: "capability_unavailable", details: {} };
216
229
  if (error.name !== "DevulturApiError") return null;
217
230
  const limitField = typeof limit === "number" ? { limit } : {};
@@ -229,8 +242,7 @@ function describeDevulturError(error, labels) {
229
242
  const descriptor = descriptorOf(error);
230
243
  if (!descriptor) return null;
231
244
  const code = isDevulturErrorCode(descriptor.code) ? descriptor.code : "worker_error";
232
- const label = labels?.[code] ?? devulturErrorLabels[code];
233
- return typeof label === "function" ? label(descriptor.details) : label;
245
+ return labelText(labels?.[code] ?? devulturErrorLabels[code], descriptor.details);
234
246
  }
235
247
 
236
248
  export {
@@ -238,6 +250,7 @@ export {
238
250
  isDevulturErrorCode,
239
251
  isDevulturError,
240
252
  devulturErrorOf,
253
+ labelText,
241
254
  formatBytes,
242
255
  formatDate,
243
256
  devulturErrorLabels,
@@ -51,4 +51,3 @@ export declare const api: FilterApi<typeof fullApi, FunctionReference<any, "publ
51
51
  export declare const internal: FilterApi<typeof fullApi, FunctionReference<any, "internal">>;
52
52
  export declare const components: {};
53
53
  export {};
54
- //# sourceMappingURL=api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG;AAmBH,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,OAAO,GAYR,MAAa,CAAC;AAEnB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,GAAG,GAGZ,MAAa,CAAC;AAElB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAGjB,MAAa,CAAC;AAElB,MAAM,CAAC,MAAM,UAAU,GAAG,iBAAiB,EAAmB,CAAC"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG;AAmBH,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,OAAO,GAYR,MAAa,CAAC;AAEnB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,GAAG,GAGZ,MAAa,CAAC;AAElB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAGjB,MAAa,CAAC;AAElB,MAAM,CAAC,MAAM,UAAU,GAAG,iBAAiB,EAAmB,CAAC","sourcesContent":["/* eslint-disable */\n/**\n * Generated `api` utility.\n *\n * THIS CODE IS AUTOMATICALLY GENERATED.\n *\n * To regenerate, run `npx convex dev`.\n * @module\n */\n\nimport type * as http from \"../http.js\";\nimport type * as library from \"../library.js\";\nimport type * as lock from \"../lock.js\";\nimport type * as lockValidators from \"../lockValidators.js\";\nimport type * as mediaClient from \"../mediaClient.js\";\nimport type * as mediaMeta from \"../mediaMeta.js\";\nimport type * as metadata from \"../metadata.js\";\nimport type * as public_ from \"../public.js\";\nimport type * as uploadKeys from \"../uploadKeys.js\";\nimport type * as uploads from \"../uploads.js\";\nimport type * as workerErrors from \"../workerErrors.js\";\n\nimport type {\n ApiFromModules,\n FilterApi,\n FunctionReference,\n} from \"convex/server\";\nimport { anyApi, componentsGeneric } from \"convex/server\";\n\nconst fullApi: ApiFromModules<{\n http: typeof http;\n library: typeof library;\n lock: typeof lock;\n lockValidators: typeof lockValidators;\n mediaClient: typeof mediaClient;\n mediaMeta: typeof mediaMeta;\n metadata: typeof metadata;\n public: typeof public_;\n uploadKeys: typeof uploadKeys;\n uploads: typeof uploads;\n workerErrors: typeof workerErrors;\n}> = anyApi as any;\n\n/**\n * A utility for referencing Convex functions in your app's public API.\n *\n * Usage:\n * ```js\n * const myFunctionReference = api.myModule.myFunction;\n * ```\n */\nexport const api: FilterApi<\n typeof fullApi,\n FunctionReference<any, \"public\">\n> = anyApi as any;\n\n/**\n * A utility for referencing Convex functions in your app's internal API.\n *\n * Usage:\n * ```js\n * const myFunctionReference = internal.myModule.myFunction;\n * ```\n */\nexport const internal: FilterApi<\n typeof fullApi,\n FunctionReference<any, \"internal\">\n> = anyApi as any;\n\nexport const components = componentsGeneric() as unknown as {};\n"]}
@@ -178,4 +178,3 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
178
178
  }, any, Name>;
179
179
  };
180
180
  };
181
- //# sourceMappingURL=component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/component/_generated/component.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG"}
1
+ {"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/component/_generated/component.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG","sourcesContent":["/* eslint-disable */\n/**\n * Generated `ComponentApi` utility.\n *\n * THIS CODE IS AUTOMATICALLY GENERATED.\n *\n * To regenerate, run `npx convex dev`.\n * @module\n */\n\nimport type { FunctionReference } from \"convex/server\";\n\n/**\n * A utility for referencing a Convex component's exposed API.\n *\n * Useful when expecting a parameter like `components.myComponent`.\n * Usage:\n * ```ts\n * async function myFunction(ctx: QueryCtx, component: ComponentApi) {\n * return ctx.runQuery(component.someFile.someQuery, { ...args });\n * }\n * ```\n */\nexport type ComponentApi<Name extends string | undefined = string | undefined> =\n {\n library: {\n backfillSearchText: FunctionReference<\n \"mutation\",\n \"internal\",\n { batchSize?: number },\n any,\n Name\n >;\n searchMedia: FunctionReference<\n \"query\",\n \"internal\",\n {\n paginationOpts: {\n cursor: string | null;\n endCursor?: string | null;\n id?: number;\n maximumBytesRead?: number;\n maximumRowsRead?: number;\n numItems: number;\n };\n search: string;\n type?: \"video\" | \"image\" | \"file\";\n },\n any,\n Name\n >;\n };\n lock: {\n getLock: FunctionReference<\n \"action\",\n \"internal\",\n { key: string },\n any,\n Name\n >;\n releaseHold: FunctionReference<\n \"action\",\n \"internal\",\n { keys: Array<string> },\n any,\n Name\n >;\n setHold: FunctionReference<\n \"action\",\n \"internal\",\n { keys: Array<string> },\n any,\n Name\n >;\n setLock: FunctionReference<\n \"action\",\n \"internal\",\n {\n bypassGovernance?: boolean;\n derivatives?: \"inherit\" | \"original-only\";\n key: string;\n mode?: \"governance\" | \"compliance\";\n period?: number;\n remove?: true;\n until?: string;\n },\n any,\n Name\n >;\n };\n metadata: {\n updateMediaMeta: FunctionReference<\n \"mutation\",\n \"internal\",\n { alt?: string; key: string; tags?: Array<string>; title?: string },\n any,\n Name\n >;\n };\n public: {\n createMedia: FunctionReference<\n \"mutation\",\n \"internal\",\n {\n contentType: string;\n filename: string;\n key: string;\n sizeBytes: number;\n type: \"video\" | \"image\" | \"file\";\n },\n any,\n Name\n >;\n createUploadUrl: FunctionReference<\n \"action\",\n \"internal\",\n {\n contentType: string;\n filename: string;\n hold?: boolean;\n lock?: {\n hold?: boolean;\n retention?: {\n derivatives?: \"inherit\" | \"original-only\";\n mode: \"governance\" | \"compliance\";\n period?: number;\n until?: string;\n };\n };\n visibility?: \"public\" | \"private\";\n },\n any,\n Name\n >;\n deleteMediaAction: FunctionReference<\n \"action\",\n \"internal\",\n { key: string },\n any,\n Name\n >;\n deleteVideo: FunctionReference<\n \"action\",\n \"internal\",\n { videoId: string; visibility?: \"public\" | \"private\" },\n any,\n Name\n >;\n getCourseProgress: FunctionReference<\n \"query\",\n \"internal\",\n { userId: string; videoIds: Array<string> },\n any,\n Name\n >;\n getMediaByKey: FunctionReference<\n \"query\",\n \"internal\",\n { key: string },\n any,\n Name\n >;\n issueViewerToken: FunctionReference<\n \"action\",\n \"internal\",\n { sessionSecret?: string; userId?: string },\n any,\n Name\n >;\n listCaptionsByMedia: FunctionReference<\n \"query\",\n \"internal\",\n { mediaKey: string },\n any,\n Name\n >;\n listMedia: FunctionReference<\n \"query\",\n \"internal\",\n { type?: \"video\" | \"image\" | \"file\" },\n any,\n Name\n >;\n listMediaPage: FunctionReference<\n \"query\",\n \"internal\",\n {\n paginationOpts: {\n cursor: string | null;\n endCursor?: string | null;\n id?: number;\n maximumBytesRead?: number;\n maximumRowsRead?: number;\n numItems: number;\n };\n type?: \"video\" | \"image\" | \"file\";\n },\n any,\n Name\n >;\n loadProgress: FunctionReference<\n \"query\",\n \"internal\",\n { userId: string; videoId: string },\n any,\n Name\n >;\n markComplete: FunctionReference<\n \"mutation\",\n \"internal\",\n { userId: string; videoId: string },\n any,\n Name\n >;\n processVideo: FunctionReference<\n \"action\",\n \"internal\",\n {\n callbackUrl?: string;\n key: string;\n locales?: Array<string>;\n preset?: string;\n },\n any,\n Name\n >;\n resetProgress: FunctionReference<\n \"mutation\",\n \"internal\",\n { userId: string; videoId: string },\n any,\n Name\n >;\n saveProgress: FunctionReference<\n \"mutation\",\n \"internal\",\n { position: number; userId: string; videoId: string },\n any,\n Name\n >;\n updateMedia: FunctionReference<\n \"mutation\",\n \"internal\",\n {\n captionLocales?: Array<string>;\n captionsPending?: boolean;\n duration?: number;\n failureReason?:\n | \"invalid_input\"\n | \"unsupported_codec\"\n | \"timeout\"\n | \"capacity\"\n | \"internal\";\n key: string;\n playlistUrl?: string;\n retriable?: boolean;\n thumbnailKey?: string;\n transcodeError?: string;\n transcodeProgress?: { current: number; total: number };\n transcodeStatus?:\n | \"queued\"\n | \"transcoding\"\n | \"captioning\"\n | \"ready\"\n | \"failed\";\n },\n any,\n Name\n >;\n upsertCaption: FunctionReference<\n \"mutation\",\n \"internal\",\n { locale: string; mediaKey: string; srtUrl?: string; vttUrl: string },\n any,\n Name\n >;\n };\n uploads: {\n confirmUpload: FunctionReference<\n \"action\",\n \"internal\",\n {\n filename?: string;\n height?: number;\n key: string;\n pageCount?: number;\n width?: number;\n },\n any,\n Name\n >;\n };\n };\n"]}
@@ -43,4 +43,3 @@ export type Id<TableName extends TableNames | SystemTableNames> = GenericId<Tabl
43
43
  * `mutationGeneric` to make them type-safe.
44
44
  */
45
45
  export type DataModel = DataModelFromSchemaDefinition<typeof schema>;
46
- //# sourceMappingURL=dataModel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dataModel.js","sourceRoot":"","sources":["../../../src/component/_generated/dataModel.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG"}
1
+ {"version":3,"file":"dataModel.js","sourceRoot":"","sources":["../../../src/component/_generated/dataModel.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG","sourcesContent":["/* eslint-disable */\n/**\n * Generated data model types.\n *\n * THIS CODE IS AUTOMATICALLY GENERATED.\n *\n * To regenerate, run `npx convex dev`.\n * @module\n */\n\nimport type {\n DataModelFromSchemaDefinition,\n DocumentByName,\n TableNamesInDataModel,\n SystemTableNames,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\nimport schema from \"../schema.js\";\n\n/**\n * The names of all of your Convex tables.\n */\nexport type TableNames = TableNamesInDataModel<DataModel>;\n\n/**\n * The type of a document stored in Convex.\n *\n * @typeParam TableName - A string literal type of the table name (like \"users\").\n */\nexport type Doc<TableName extends TableNames> = DocumentByName<\n DataModel,\n TableName\n>;\n\n/**\n * An identifier for a document in Convex.\n *\n * Convex documents are uniquely identified by their `Id`, which is accessible\n * on the `_id` field. To learn more, see [Document IDs](https://docs.convex.dev/using/document-ids).\n *\n * Documents can be loaded using `db.get(tableName, id)` in query and mutation functions.\n *\n * IDs are just strings at runtime, but this type can be used to distinguish them from other\n * strings when type checking.\n *\n * @typeParam TableName - A string literal type of the table name (like \"users\").\n */\nexport type Id<TableName extends TableNames | SystemTableNames> =\n GenericId<TableName>;\n\n/**\n * A type describing your Convex data model.\n *\n * This type includes information about what tables you have, the type of\n * documents stored in those tables, and the indexes defined on them.\n *\n * This type is used to parameterize methods like `queryGeneric` and\n * `mutationGeneric` to make them type-safe.\n */\nexport type DataModel = DataModelFromSchemaDefinition<typeof schema>;\n"]}
@@ -127,4 +127,3 @@ export type DatabaseReader = GenericDatabaseReader<DataModel>;
127
127
  */
128
128
  export type DatabaseWriter = GenericDatabaseWriter<DataModel>;
129
129
  export {};
130
- //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/component/_generated/server.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG;AAaH,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAWvB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,KAAK,GAAsC,YAAY,CAAC;AAErE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GACxB,oBAAoB,CAAC;AAEvB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAyC,eAAe,CAAC;AAE9E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAC3B,uBAAuB,CAAC;AAE1B;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,MAAM,GAAuC,aAAa,CAAC;AAExE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GACzB,qBAAqB,CAAC;AAExB;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,UAAU,GAAsB,iBAAiB,CAAC;AAC/D,MAAM,CAAC,MAAM,GAAG,GAAQ,OAAO,CAAC,GAAqB,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/component/_generated/server.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG;AAaH,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAWvB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,KAAK,GAAsC,YAAY,CAAC;AAErE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GACxB,oBAAoB,CAAC;AAEvB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAyC,eAAe,CAAC;AAE9E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAC3B,uBAAuB,CAAC;AAE1B;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,MAAM,GAAuC,aAAa,CAAC;AAExE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GACzB,qBAAqB,CAAC;AAExB;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,UAAU,GAAsB,iBAAiB,CAAC;AAC/D,MAAM,CAAC,MAAM,GAAG,GAAQ,OAAO,CAAC,GAAqB,CAAC","sourcesContent":["/* eslint-disable */\n/**\n * Generated utilities for implementing server-side Convex query and mutation functions.\n *\n * THIS CODE IS AUTOMATICALLY GENERATED.\n *\n * To regenerate, run `npx convex dev`.\n * @module\n */\n\nimport type {\n ActionBuilder,\n HttpActionBuilder,\n MutationBuilder,\n QueryBuilder,\n GenericActionCtx,\n GenericMutationCtx,\n GenericQueryCtx,\n GenericDatabaseReader,\n GenericDatabaseWriter,\n} from \"convex/server\";\nimport {\n actionGeneric,\n httpActionGeneric,\n queryGeneric,\n mutationGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n} from \"convex/server\";\nimport type { DataModel } from \"./dataModel.js\";\n\n/**\n * Typesafe environment variables declared in `convex.config.ts`.\n */\ntype Env = {\n readonly DEVULTUR_API_URL: string;\n readonly DEVULTUR_SECRET: string;\n};\n\n/**\n * Define a query in this Convex app's public API.\n *\n * This function will be allowed to read your Convex database and will be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an `export` to name it and make it accessible.\n */\nexport const query: QueryBuilder<DataModel, \"public\"> = queryGeneric;\n\n/**\n * Define a query that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to read from your Convex database. It will not be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an `export` to name it and make it accessible.\n */\nexport const internalQuery: QueryBuilder<DataModel, \"internal\"> =\n internalQueryGeneric;\n\n/**\n * Define a mutation in this Convex app's public API.\n *\n * This function will be allowed to modify your Convex database and will be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.\n */\nexport const mutation: MutationBuilder<DataModel, \"public\"> = mutationGeneric;\n\n/**\n * Define a mutation that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to modify your Convex database. It will not be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.\n */\nexport const internalMutation: MutationBuilder<DataModel, \"internal\"> =\n internalMutationGeneric;\n\n/**\n * Define an action in this Convex app's public API.\n *\n * An action is a function which can execute any JavaScript code, including non-deterministic\n * code and code with side-effects, like calling third-party services.\n * They can be run in Convex's JavaScript environment or in Node.js using the \"use node\" directive.\n * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.\n *\n * @param func - The action. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped action. Include this as an `export` to name it and make it accessible.\n */\nexport const action: ActionBuilder<DataModel, \"public\"> = actionGeneric;\n\n/**\n * Define an action that is only accessible from other Convex functions (but not from the client).\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped function. Include this as an `export` to name it and make it accessible.\n */\nexport const internalAction: ActionBuilder<DataModel, \"internal\"> =\n internalActionGeneric;\n\n/**\n * Define an HTTP action.\n *\n * The wrapped function will be used to respond to HTTP requests received\n * by a Convex deployment if the requests matches the path and method where\n * this action is routed. Be sure to route your httpAction in `convex/http.js`.\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument\n * and a Fetch API `Request` object as its second.\n * @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.\n */\nexport const httpAction: HttpActionBuilder = httpActionGeneric;\nexport const env: Env = process.env as unknown as Env;\n\n/**\n * A set of services for use within Convex query functions.\n *\n * The query context is passed as the first argument to any Convex query\n * function run on the server.\n *\n * If you're using code generation, use the `QueryCtx` type in `convex/_generated/server.d.ts` instead.\n */\nexport type QueryCtx = GenericQueryCtx<DataModel>;\n\n/**\n * A set of services for use within Convex mutation functions.\n *\n * The mutation context is passed as the first argument to any Convex mutation\n * function run on the server.\n *\n * If you're using code generation, use the `MutationCtx` type in `convex/_generated/server.d.ts` instead.\n */\nexport type MutationCtx = GenericMutationCtx<DataModel>;\n\n/**\n * A set of services for use within Convex action functions.\n *\n * The action context is passed as the first argument to any Convex action\n * function run on the server.\n */\nexport type ActionCtx = GenericActionCtx<DataModel>;\n\n/**\n * An interface to read from the database within Convex query functions.\n *\n * The two entry points are {@link DatabaseReader.get}, which fetches a single\n * document by its {@link Id}, or {@link DatabaseReader.query}, which starts\n * building a query.\n */\nexport type DatabaseReader = GenericDatabaseReader<DataModel>;\n\n/**\n * An interface to read from and write to the database within Convex mutation\n * functions.\n *\n * Convex guarantees that all writes within a single mutation are\n * executed atomically, so you never have to worry about partial writes leaving\n * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control)\n * for the guarantees Convex provides your functions.\n */\nexport type DatabaseWriter = GenericDatabaseWriter<DataModel>;\n"]}
@@ -3,4 +3,3 @@ declare const component: import("convex/server").ComponentDefinition<any, {
3
3
  readonly DEVULTUR_API_URL: import("convex/values").VString<string, "required">;
4
4
  }>;
5
5
  export default component;
6
- //# sourceMappingURL=convex.config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"convex.config.js","sourceRoot":"","sources":["../../src/component/convex.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAElC,MAAM,SAAS,GAAG,eAAe,CAAC,UAAU,EAAE;IAC7C,GAAG,EAAE;QACJ,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE;QAC3B,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE;KAC5B;CACD,CAAC,CAAC;AAEH,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"convex.config.js","sourceRoot":"","sources":["../../src/component/convex.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAElC,MAAM,SAAS,GAAG,eAAe,CAAC,UAAU,EAAE;IAC7C,GAAG,EAAE;QACJ,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE;QAC3B,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE;KAC5B;CACD,CAAC,CAAC;AAEH,eAAe,SAAS,CAAC","sourcesContent":["import { defineComponent } from \"convex/server\";\nimport { v } from \"convex/values\";\n\nconst component = defineComponent(\"devultur\", {\n\tenv: {\n\t\tDEVULTUR_SECRET: v.string(),\n\t\tDEVULTUR_API_URL: v.string(),\n\t},\n});\n\nexport default component;\n"]}
@@ -1,3 +1,2 @@
1
1
  declare const http: import("convex/server").HttpRouter;
2
2
  export default http;
3
- //# sourceMappingURL=http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/component/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;AAE1B,IAAI,CAAC,KAAK,CAAC;IACV,IAAI,EAAE,UAAU;IAChB,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;QAC1C,gFAAgF;QAChF,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;YAC5E,OAAO,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACnC,MAAM,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;YACjE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,IAAI,QAAQ,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACrD,CAAC;IACF,CAAC,CAAC;CACF,CAAC,CAAC;AAEH,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/component/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;AAE1B,IAAI,CAAC,KAAK,CAAC;IACV,IAAI,EAAE,UAAU;IAChB,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;QAC1C,gFAAgF;QAChF,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;YAC5E,OAAO,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACnC,MAAM,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;YACjE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,IAAI,QAAQ,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACrD,CAAC;IACF,CAAC,CAAC;CACF,CAAC,CAAC;AAEH,eAAe,IAAI,CAAC","sourcesContent":["import { isBearerOf } from \"@devultur/core\";\nimport { httpRouter } from \"convex/server\";\nimport { internal } from \"./_generated/api\";\nimport { env, httpAction } from \"./_generated/server\";\n\nconst http = httpRouter();\n\nhttp.route({\n\tpath: \"/webhook\",\n\tmethod: \"POST\",\n\thandler: httpAction(async (ctx, request) => {\n\t\t// Fails closed: with `DEVULTUR_SECRET` unset or empty no request is authorized.\n\t\tif (!isBearerOf(request.headers.get(\"Authorization\"), env.DEVULTUR_SECRET)) {\n\t\t\treturn new Response(\"Unauthorized\", { status: 401 });\n\t\t}\n\n\t\ttry {\n\t\t\tconst event = await request.json();\n\t\t\tawait ctx.runMutation(internal.public.handleWebhookEvent, event);\n\t\t\treturn new Response(\"OK\", { status: 200 });\n\t\t} catch {\n\t\t\treturn new Response(\"Bad Request\", { status: 400 });\n\t\t}\n\t}),\n});\n\nexport default http;\n"]}
@@ -90,4 +90,3 @@ export declare const backfillSearchTextBatch: import("convex/server").Registered
90
90
  batchSize: number;
91
91
  }, Promise<BackfillResult>>;
92
92
  export {};
93
- //# sourceMappingURL=library.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"library.js","sourceRoot":"","sources":["../../src/component/library.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"library.js","sourceRoot":"","sources":["../../src/component/library.ts"],"names":[],"mappings":"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","sourcesContent":["// The media library: search over the records' `searchText` (title + filename), and the one-off backfill that gives\n// records from before 1.4.0 the `searchText` they were written without.\nimport { type PaginationOptions, type PaginationResult, paginationOptsValidator } from \"convex/server\";\nimport { v } from \"convex/values\";\nimport { internal } from \"./_generated/api\";\nimport type { Doc } from \"./_generated/dataModel\";\nimport type { MutationCtx, QueryCtx } from \"./_generated/server\";\nimport { internalMutation, mutation, query } from \"./_generated/server\";\nimport { missingSearchText } from \"./mediaMeta\";\n\nconst mediaType = v.union(v.literal(\"video\"), v.literal(\"image\"), v.literal(\"file\"));\ntype MediaType = Doc<\"media\">[\"type\"];\n\n/** Longest search kept: Convex matches at most 16 terms, so a longer query only costs. */\nconst SEARCH_MAX_LENGTH = 200;\nexport const BACKFILL_BATCH_SIZE = { default: 100, max: 1000 } as const;\n\n/** One page of the library, newest first, optionally of one kind (`by_type` index). */\nexport function listNewestFirst(\n\tctx: QueryCtx,\n\ttype: MediaType | undefined,\n\tpaginationOpts: PaginationOptions,\n): Promise<PaginationResult<Doc<\"media\">>> {\n\tconst records = type ? ctx.db.query(\"media\").withIndex(\"by_type\", (q) => q.eq(\"type\", type)) : ctx.db.query(\"media\");\n\treturn records.order(\"desc\").paginate(paginationOpts);\n}\n\n/**\n * One page of the records whose title or filename matches `search` (the last word as a prefix), best match first,\n * optionally of one kind. A blank `search` lists the library newest first, like `listMediaPage`. Records from before\n * 1.4.0 match only once they have a `searchText` (`backfillSearchText`, or any write to them).\n */\nexport const searchMedia = query({\n\targs: { search: v.string(), type: v.optional(mediaType), paginationOpts: paginationOptsValidator },\n\thandler: async (ctx, args): Promise<PaginationResult<Doc<\"media\">>> => {\n\t\tconst { type, paginationOpts } = args;\n\t\tconst search = args.search.trim().toLowerCase().slice(0, SEARCH_MAX_LENGTH);\n\t\tif (search === \"\") return listNewestFirst(ctx, type, paginationOpts);\n\n\t\treturn ctx.db\n\t\t\t.query(\"media\")\n\t\t\t.withSearchIndex(\"search_text\", (q) => {\n\t\t\t\tconst matches = q.search(\"searchText\", search);\n\t\t\t\treturn type ? matches.eq(\"type\", type) : matches;\n\t\t\t})\n\t\t\t.paginate(paginationOpts);\n\t},\n});\n\ninterface BackfillResult {\n\t/** Records given a `searchText` by this batch. */\n\tupdated: number;\n\t/** `false` while later batches are scheduled. */\n\tisDone: boolean;\n}\n\nfunction batchSizeOf(requested: number | undefined): number {\n\tif (requested === undefined || !Number.isFinite(requested)) return BACKFILL_BATCH_SIZE.default;\n\treturn Math.min(Math.max(Math.floor(requested), 1), BACKFILL_BATCH_SIZE.max);\n}\n\n/** Fills one page of records, then schedules the next page until the table is done. */\nasync function backfillBatch(ctx: MutationCtx, cursor: string | null, batchSize: number): Promise<BackfillResult> {\n\tconst page = await ctx.db.query(\"media\").paginate({ cursor, numItems: batchSize });\n\tlet updated = 0;\n\tfor (const record of page.page) {\n\t\tconst fill = missingSearchText(record);\n\t\tif (fill.searchText === undefined) continue;\n\t\tawait ctx.db.patch(record._id, fill);\n\t\tupdated++;\n\t}\n\tif (!page.isDone) {\n\t\tawait ctx.scheduler.runAfter(0, internal.library.backfillSearchTextBatch, {\n\t\t\tcursor: page.continueCursor,\n\t\t\tbatchSize,\n\t\t});\n\t}\n\treturn { updated, isDone: page.isDone };\n}\n\n/**\n * Gives every record without a `searchText` (written before 1.4.0) its title and filename, `batchSize` records per\n * mutation (default 100, at most 1000). Runs the first batch now and schedules the rest; safe to run again.\n */\nexport const backfillSearchText = mutation({\n\targs: { batchSize: v.optional(v.number()) },\n\thandler: async (ctx, args): Promise<BackfillResult> => backfillBatch(ctx, null, batchSizeOf(args.batchSize)),\n});\n\nexport const backfillSearchTextBatch = internalMutation({\n\targs: { cursor: v.union(v.string(), v.null()), batchSize: v.number() },\n\thandler: async (ctx, args): Promise<BackfillResult> => backfillBatch(ctx, args.cursor, args.batchSize),\n});\n"]}
@@ -30,4 +30,3 @@ export declare const releaseHold: import("convex/server").RegisteredAction<"publ
30
30
  }[];
31
31
  pageSize: number;
32
32
  }>>;
33
- //# sourceMappingURL=lock.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/component/lock.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/component/lock.ts"],"names":[],"mappings":"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","sourcesContent":["// Object lock from the app's server: read and change an object's retention, and set or release holds on a list of\n// keys. These are component functions, so only the app's own functions can call them (never a browser). A bulk hold\n// by prefix stays on the app's server, with `@devultur/core`'s `createWorkerClient(...).lock.holdAll({ prefix })`.\n// A refusal throws a `ConvexError` whose `data.code` is the Worker's (`retention_active`, `compliance_extend_only`,\n// `lock_privilege_required`, `lock_conflict`, ...); see workerErrors.ts.\nimport { HOLD_PAGE_SIZE } from \"@devultur/core\";\nimport { v } from \"convex/values\";\nimport { derivativesValidator, retentionModeValidator } from \"./lockValidators\";\nimport { getMediaClient } from \"./mediaClient\";\nimport { workerAction } from \"./workerErrors\";\n\nconst keysValidator = v.array(v.string());\n\nexport const getLock = workerAction({\n\targs: { key: v.string() },\n\thandler: async (_ctx, args) => getMediaClient().lock.get(args.key),\n});\n\nexport const setLock = workerAction({\n\targs: {\n\t\tkey: v.string(),\n\t\tmode: v.optional(retentionModeValidator),\n\t\tuntil: v.optional(v.string()),\n\t\tperiod: v.optional(v.number()),\n\t\tderivatives: v.optional(derivativesValidator),\n\t\tremove: v.optional(v.literal(true)),\n\t\tbypassGovernance: v.optional(v.boolean()),\n\t},\n\thandler: async (_ctx, { key, ...options }) => getMediaClient().lock.set(key, options),\n});\n\n/** Holds every key, a page of {@link HOLD_PAGE_SIZE} at a time; returns what changed and what didn't. */\nasync function changeHolds(keys: string[], hold: boolean) {\n\tconst lock = getMediaClient().lock;\n\tconst updated: string[] = [];\n\tconst skipped: { key: string; reason: string }[] = [];\n\tfor await (const page of hold ? lock.holdAll(keys) : lock.releaseAll(keys)) {\n\t\tupdated.push(...page.updated);\n\t\tskipped.push(...page.skipped);\n\t}\n\treturn { updated, skipped, pageSize: HOLD_PAGE_SIZE };\n}\n\nexport const setHold = workerAction({\n\targs: { keys: keysValidator },\n\thandler: async (_ctx, args) => changeHolds(args.keys, true),\n});\n\nexport const releaseHold = workerAction({\n\targs: { keys: keysValidator },\n\thandler: async (_ctx, args) => changeHolds(args.keys, false),\n});\n"]}
@@ -22,4 +22,3 @@ export declare const objectLockValidator: import("convex/values").VObject<{
22
22
  }, "optional", "mode" | "until" | "period" | "derivatives">;
23
23
  hold: import("convex/values").VBoolean<boolean | undefined, "optional">;
24
24
  }, "required", "retention" | "hold" | "retention.mode" | "retention.until" | "retention.period" | "retention.derivatives">;
25
- //# sourceMappingURL=lockValidators.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lockValidators.js","sourceRoot":"","sources":["../../src/component/lockValidators.ts"],"names":[],"mappings":"AAAA,gHAAgH;AAChH,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAElC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;AAChG,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;AAE9F,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,SAAS,EAAE,CAAC,CAAC,QAAQ,CACpB,CAAC,CAAC,MAAM,CAAC;QACR,IAAI,EAAE,sBAAsB;QAC5B,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC9B,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC;KAC7C,CAAC,CACF;IACD,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;CAC7B,CAAC,CAAC"}
1
+ {"version":3,"file":"lockValidators.js","sourceRoot":"","sources":["../../src/component/lockValidators.ts"],"names":[],"mappings":"AAAA,gHAAgH;AAChH,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAElC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;AAChG,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;AAE9F,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,SAAS,EAAE,CAAC,CAAC,QAAQ,CACpB,CAAC,CAAC,MAAM,CAAC;QACR,IAAI,EAAE,sBAAsB;QAC5B,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC9B,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC;KAC7C,CAAC,CACF;IACD,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;CAC7B,CAAC,CAAC","sourcesContent":["// Validators of the object lock arguments (the shapes of `@devultur/core`'s `ObjectLock` and `SetLockOptions`).\nimport { v } from \"convex/values\";\n\nexport const retentionModeValidator = v.union(v.literal(\"governance\"), v.literal(\"compliance\"));\nexport const derivativesValidator = v.union(v.literal(\"inherit\"), v.literal(\"original-only\"));\n\nexport const objectLockValidator = v.object({\n\tretention: v.optional(\n\t\tv.object({\n\t\t\tmode: retentionModeValidator,\n\t\t\tuntil: v.optional(v.string()),\n\t\t\tperiod: v.optional(v.number()),\n\t\t\tderivatives: v.optional(derivativesValidator),\n\t\t}),\n\t),\n\thold: v.optional(v.boolean()),\n});\n"]}
@@ -1,3 +1,2 @@
1
1
  import { type WorkerClient } from "@devultur/core";
2
2
  export declare function getMediaClient(): WorkerClient;
3
- //# sourceMappingURL=mediaClient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mediaClient.js","sourceRoot":"","sources":["../../src/component/mediaClient.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,OAAO,EAAE,kBAAkB,EAAqB,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAE1C,MAAM,UAAU,cAAc;IAC7B,OAAO,kBAAkB,CAAC,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;AACtE,CAAC"}
1
+ {"version":3,"file":"mediaClient.js","sourceRoot":"","sources":["../../src/component/mediaClient.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,OAAO,EAAE,kBAAkB,EAAqB,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAE1C,MAAM,UAAU,cAAc;IAC7B,OAAO,kBAAkB,CAAC,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;AACtE,CAAC","sourcesContent":["// The component's client of the media Worker, from the env the app mounts the component with.\nimport { createWorkerClient, type WorkerClient } from \"@devultur/core\";\nimport { env } from \"./_generated/server\";\n\nexport function getMediaClient(): WorkerClient {\n\treturn createWorkerClient(env.DEVULTUR_SECRET, env.DEVULTUR_API_URL);\n}\n"]}
@@ -43,4 +43,3 @@ export declare function missingSearchText(record: SearchableRecord): {
43
43
  searchText?: string;
44
44
  };
45
45
  export {};
46
- //# sourceMappingURL=mediaMeta.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mediaMeta.js","sourceRoot":"","sources":["../../src/component/mediaMeta.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mediaMeta.js","sourceRoot":"","sources":["../../src/component/mediaMeta.ts"],"names":[],"mappings":"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","sourcesContent":["// A media record's descriptive metadata: what the app edits (`title`, `alt`, `tags`), the hints an uploading client\n// sends (`width`, `height`, `pageCount`), and the `searchText` kept in step with the title and filename. Pure: no\n// database, so it is checked the same way in every function that writes a record.\nimport { ConvexError } from \"convex/values\";\n\nexport const MEDIA_META_LIMITS = {\n\ttitleLength: 200,\n\taltLength: 1000,\n\ttagCount: 20,\n\ttagLength: 50,\n\t/** Largest width, height or page count a client may report. */\n\thintValue: 100_000,\n} as const;\n\nexport interface UploadHints {\n\twidth?: number;\n\theight?: number;\n\tpageCount?: number;\n}\n\nexport interface MediaMetaInput {\n\ttitle?: string;\n\talt?: string;\n\ttags?: string[];\n}\n\n/** The fields to patch: a trimmed empty `title` or `alt` clears it (`undefined`), `tags: []` clears the tags. */\nexport interface MediaMetaPatch {\n\ttitle?: string | undefined;\n\talt?: string | undefined;\n\ttags?: string[];\n}\n\nfunction invalidMetadata(field: string, message: string) {\n\treturn new ConvexError({ code: \"invalid_media_metadata\", message, status: 400, details: { field } });\n}\n\nconst HINT_FIELDS = [\"width\", \"height\", \"pageCount\"] as const;\n\nconst isValidHint = (value: number) => Number.isInteger(value) && value > 0 && value <= MEDIA_META_LIMITS.hintValue;\n\n/**\n * The hints worth recording: positive integers up to `hintValue`. The bytes are already stored, so a bad hint (a\n * client's bug) is dropped and logged instead of failing the upload.\n */\nexport function validUploadHints(hints: UploadHints): UploadHints {\n\tconst valid: UploadHints = {};\n\tfor (const field of HINT_FIELDS) {\n\t\tconst value = hints[field];\n\t\tif (value === undefined) continue;\n\t\tif (isValidHint(value)) {\n\t\t\tvalid[field] = value;\n\t\t\tcontinue;\n\t\t}\n\t\tconsole.warn(`Devultur: dropped the upload hint ${field}=${value} (a whole number from 1 to 100,000)`);\n\t}\n\treturn valid;\n}\n\nfunction trimmedText(field: \"title\" | \"alt\", value: string, maxLength: number): string | undefined {\n\tconst trimmed = value.trim();\n\tif (trimmed.length > maxLength) throw invalidMetadata(field, `${field} must be at most ${maxLength} characters`);\n\treturn trimmed === \"\" ? undefined : trimmed;\n}\n\n/** Trimmed, without empty ones or repeats (first spelling wins), within the count and length limits. */\nexport function normalizeTags(tags: string[]): string[] {\n\tconst seen = new Set<string>();\n\tconst normalized: string[] = [];\n\tfor (const tag of tags) {\n\t\tconst trimmed = tag.trim();\n\t\tif (trimmed === \"\" || seen.has(trimmed.toLowerCase())) continue;\n\t\tif (trimmed.length > MEDIA_META_LIMITS.tagLength) {\n\t\t\tthrow invalidMetadata(\"tags\", `Each tag must be at most ${MEDIA_META_LIMITS.tagLength} characters`);\n\t\t}\n\t\tseen.add(trimmed.toLowerCase());\n\t\tnormalized.push(trimmed);\n\t}\n\tif (normalized.length > MEDIA_META_LIMITS.tagCount) {\n\t\tthrow invalidMetadata(\"tags\", `A media can have at most ${MEDIA_META_LIMITS.tagCount} tags`);\n\t}\n\treturn normalized;\n}\n\n/** The patch for an edit; only the fields the caller passed are in it. Throws `invalid_media_metadata`. */\nexport function mediaMetaPatch(input: MediaMetaInput): MediaMetaPatch {\n\tconst patch: MediaMetaPatch = {};\n\tif (input.title !== undefined) patch.title = trimmedText(\"title\", input.title, MEDIA_META_LIMITS.titleLength);\n\tif (input.alt !== undefined) patch.alt = trimmedText(\"alt\", input.alt, MEDIA_META_LIMITS.altLength);\n\tif (input.tags !== undefined) patch.tags = normalizeTags(input.tags);\n\treturn patch;\n}\n\n/** What the media library's search matches: the title and the filename, lowercased. */\nexport function searchTextOf(title: string | undefined, filename: string): string {\n\treturn (title ? `${title} ${filename}` : filename).toLowerCase();\n}\n\ninterface SearchableRecord {\n\ttitle?: string;\n\tfilename: string;\n\tsearchText?: string;\n}\n\n/** `{ searchText }` for a record written before 1.4.0 (it has none), else `{}`: spread it into any patch of a record. */\nexport function missingSearchText(record: SearchableRecord): { searchText?: string } {\n\tif (record.searchText !== undefined) return {};\n\treturn { searchText: searchTextOf(record.title, record.filename) };\n}\n"]}
@@ -56,4 +56,3 @@ export declare const updateMediaMeta: import("convex/server").RegisteredMutation
56
56
  sizeBytes: number;
57
57
  createdAt: number;
58
58
  } | null>>;
59
- //# sourceMappingURL=metadata.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/component/metadata.ts"],"names":[],"mappings":"AAAA,mHAAmH;AACnH,mGAAmG;AACnG,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3D;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC;IACvC,IAAI,EAAE;QACL,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;QACf,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC7B,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC3B,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;KACrC;IACD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAgC,EAAE;QAC1D,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC;QAC/B,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE;aACzB,KAAK,CAAC,OAAO,CAAC;aACd,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;aAC5C,KAAK,EAAE,CAAC;QACV,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAEzB,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QAC5D,MAAM,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC/F,OAAO,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;CACD,CAAC,CAAC"}
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/component/metadata.ts"],"names":[],"mappings":"AAAA,mHAAmH;AACnH,mGAAmG;AACnG,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3D;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC;IACvC,IAAI,EAAE;QACL,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;QACf,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC7B,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC3B,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;KACrC;IACD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAgC,EAAE;QAC1D,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC;QAC/B,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE;aACzB,KAAK,CAAC,OAAO,CAAC;aACd,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;aAC5C,KAAK,EAAE,CAAC;QACV,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAEzB,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QAC5D,MAAM,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC/F,OAAO,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;CACD,CAAC,CAAC","sourcesContent":["// Editing a media record's descriptive metadata (title, alt text, tags). The upload's own facts (size, dimensions,\n// duration, page count) are recorded by `uploads.ts` and the transcode webhook, never edited here.\nimport { v } from \"convex/values\";\nimport type { Doc } from \"./_generated/dataModel\";\nimport { mutation } from \"./_generated/server\";\nimport { mediaMetaPatch, searchTextOf } from \"./mediaMeta\";\n\n/**\n * Sets a record's `title`, `alt` and/or `tags` (only the ones passed). Trimmed; an empty title or alt clears it, and\n * tags are deduplicated. Throws `invalid_media_metadata` past the limits (title 200, alt 1000, 20 tags of 50). Returns\n * the updated record, or `null` when no record has this media id.\n */\nexport const updateMediaMeta = mutation({\n\targs: {\n\t\tkey: v.string(),\n\t\ttitle: v.optional(v.string()),\n\t\talt: v.optional(v.string()),\n\t\ttags: v.optional(v.array(v.string())),\n\t},\n\thandler: async (ctx, args): Promise<Doc<\"media\"> | null> => {\n\t\tconst { key, ...input } = args;\n\t\tconst patch = mediaMetaPatch(input);\n\t\tconst record = await ctx.db\n\t\t\t.query(\"media\")\n\t\t\t.withIndex(\"by_key\", (q) => q.eq(\"key\", key))\n\t\t\t.first();\n\t\tif (!record) return null;\n\n\t\tconst title = \"title\" in patch ? patch.title : record.title;\n\t\tawait ctx.db.patch(record._id, { ...patch, searchText: searchTextOf(title, record.filename) });\n\t\treturn ctx.db.get(record._id);\n\t},\n});\n"]}
@@ -312,4 +312,3 @@ export declare const handleWebhookEvent: import("convex/server").RegisteredMutat
312
312
  videoId: string;
313
313
  event: string;
314
314
  }, Promise<void>>;
315
- //# sourceMappingURL=public.d.ts.map