@anvilkit/plugin-asset-manager 0.1.6 → 0.1.8

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 (251) hide show
  1. package/README.md +28 -20
  2. package/dist/adapters/data-url.d.cts +13 -0
  3. package/dist/adapters/data-url.d.cts.map +1 -1
  4. package/dist/adapters/data-url.d.ts +13 -0
  5. package/dist/adapters/data-url.d.ts.map +1 -1
  6. package/dist/adapters/in-memory.d.cts +8 -1
  7. package/dist/adapters/in-memory.d.cts.map +1 -1
  8. package/dist/adapters/in-memory.d.ts +8 -1
  9. package/dist/adapters/in-memory.d.ts.map +1 -1
  10. package/dist/i18n/entry.cjs +75 -0
  11. package/dist/i18n/entry.d.cts +15 -0
  12. package/dist/i18n/entry.d.cts.map +1 -0
  13. package/dist/i18n/entry.d.ts +15 -0
  14. package/dist/i18n/entry.d.ts.map +1 -0
  15. package/dist/i18n/entry.js +29 -0
  16. package/dist/i18n/provider.cjs +49 -0
  17. package/dist/i18n/provider.d.cts +20 -0
  18. package/dist/i18n/provider.d.cts.map +1 -0
  19. package/dist/i18n/provider.d.ts +20 -0
  20. package/dist/i18n/provider.d.ts.map +1 -0
  21. package/dist/i18n/provider.js +11 -0
  22. package/dist/index.cjs +7 -0
  23. package/dist/index.d.cts +11 -3
  24. package/dist/index.d.cts.map +1 -1
  25. package/dist/index.d.ts +11 -3
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +2 -1
  28. package/dist/plugin.cjs +70 -5
  29. package/dist/plugin.d.cts +3 -2
  30. package/dist/plugin.d.cts.map +1 -1
  31. package/dist/plugin.d.ts +3 -2
  32. package/dist/plugin.d.ts.map +1 -1
  33. package/dist/plugin.js +70 -5
  34. package/dist/sources/composite-source.cjs +138 -0
  35. package/dist/sources/composite-source.d.cts +39 -0
  36. package/dist/sources/composite-source.d.cts.map +1 -0
  37. package/dist/sources/composite-source.d.ts +39 -0
  38. package/dist/sources/composite-source.d.ts.map +1 -0
  39. package/dist/sources/composite-source.js +100 -0
  40. package/dist/sources/federated-search.cjs +173 -0
  41. package/dist/sources/federated-search.d.cts +33 -0
  42. package/dist/sources/federated-search.d.cts.map +1 -0
  43. package/dist/sources/federated-search.d.ts +33 -0
  44. package/dist/sources/federated-search.d.ts.map +1 -0
  45. package/dist/sources/federated-search.js +123 -0
  46. package/dist/sources/provider.cjs +18 -0
  47. package/dist/sources/provider.d.cts +51 -0
  48. package/dist/sources/provider.d.cts.map +1 -0
  49. package/dist/sources/provider.d.ts +51 -0
  50. package/dist/sources/provider.d.ts.map +1 -0
  51. package/dist/sources/provider.js +1 -0
  52. package/dist/sources/unsplash/client.cjs +189 -0
  53. package/dist/sources/unsplash/client.d.cts +87 -0
  54. package/dist/sources/unsplash/client.d.cts.map +1 -0
  55. package/dist/sources/unsplash/client.d.ts +87 -0
  56. package/dist/sources/unsplash/client.d.ts.map +1 -0
  57. package/dist/sources/unsplash/client.js +151 -0
  58. package/dist/sources/unsplash/index.cjs +194 -0
  59. package/dist/sources/unsplash/index.d.cts +16 -0
  60. package/dist/sources/unsplash/index.d.cts.map +1 -0
  61. package/dist/sources/unsplash/index.d.ts +16 -0
  62. package/dist/sources/unsplash/index.d.ts.map +1 -0
  63. package/dist/sources/unsplash/index.js +150 -0
  64. package/dist/sources/unsplash/themes.cjs +141 -0
  65. package/dist/sources/unsplash/themes.d.cts +18 -0
  66. package/dist/sources/unsplash/themes.d.cts.map +1 -0
  67. package/dist/sources/unsplash/themes.d.ts +18 -0
  68. package/dist/sources/unsplash/themes.d.ts.map +1 -0
  69. package/dist/sources/unsplash/themes.js +93 -0
  70. package/dist/sources/unsplash/throttle-cache.cjs +86 -0
  71. package/dist/sources/unsplash/throttle-cache.d.cts +25 -0
  72. package/dist/sources/unsplash/throttle-cache.d.cts.map +1 -0
  73. package/dist/sources/unsplash/throttle-cache.d.ts +25 -0
  74. package/dist/sources/unsplash/throttle-cache.d.ts.map +1 -0
  75. package/dist/sources/unsplash/throttle-cache.js +45 -0
  76. package/dist/types/categories.cjs +18 -0
  77. package/dist/types/categories.d.cts +48 -0
  78. package/dist/types/categories.d.cts.map +1 -0
  79. package/dist/types/categories.d.ts +48 -0
  80. package/dist/types/categories.d.ts.map +1 -0
  81. package/dist/types/categories.js +1 -0
  82. package/dist/types/data-source.cjs +18 -0
  83. package/dist/types/data-source.d.cts +59 -0
  84. package/dist/types/data-source.d.cts.map +1 -0
  85. package/dist/types/data-source.d.ts +59 -0
  86. package/dist/types/data-source.d.ts.map +1 -0
  87. package/dist/types/data-source.js +1 -0
  88. package/dist/types/filter.cjs +18 -0
  89. package/dist/types/filter.d.cts +55 -0
  90. package/dist/types/filter.d.cts.map +1 -0
  91. package/dist/types/filter.d.ts +55 -0
  92. package/dist/types/filter.d.ts.map +1 -0
  93. package/dist/types/filter.js +1 -0
  94. package/dist/types/folders.cjs +42 -0
  95. package/dist/types/folders.d.cts +46 -0
  96. package/dist/types/folders.d.cts.map +1 -0
  97. package/dist/types/folders.d.ts +46 -0
  98. package/dist/types/folders.d.ts.map +1 -0
  99. package/dist/types/folders.js +4 -0
  100. package/dist/types/options.cjs +18 -0
  101. package/dist/types/options.d.cts +68 -0
  102. package/dist/types/options.d.cts.map +1 -0
  103. package/dist/types/options.d.ts +68 -0
  104. package/dist/types/options.d.ts.map +1 -0
  105. package/dist/types/options.js +1 -0
  106. package/dist/types/types.d.cts +21 -27
  107. package/dist/types/types.d.cts.map +1 -1
  108. package/dist/types/types.d.ts +21 -27
  109. package/dist/types/types.d.ts.map +1 -1
  110. package/dist/types/unsplash.cjs +18 -0
  111. package/dist/types/unsplash.d.cts +60 -0
  112. package/dist/types/unsplash.d.cts.map +1 -0
  113. package/dist/types/unsplash.d.ts +60 -0
  114. package/dist/types/unsplash.d.ts.map +1 -0
  115. package/dist/types/unsplash.js +1 -0
  116. package/dist/ui/AssetBrowser.cjs +183 -121
  117. package/dist/ui/AssetBrowser.d.cts +12 -1
  118. package/dist/ui/AssetBrowser.d.cts.map +1 -1
  119. package/dist/ui/AssetBrowser.d.ts +12 -1
  120. package/dist/ui/AssetBrowser.d.ts.map +1 -1
  121. package/dist/ui/AssetBrowser.js +183 -121
  122. package/dist/ui/AssetCommandPalette.cjs +20 -18
  123. package/dist/ui/AssetCommandPalette.d.cts.map +1 -1
  124. package/dist/ui/AssetCommandPalette.d.ts.map +1 -1
  125. package/dist/ui/AssetCommandPalette.js +20 -18
  126. package/dist/ui/AssetManagerUI.cjs +31 -17
  127. package/dist/ui/AssetManagerUI.d.cts +19 -3
  128. package/dist/ui/AssetManagerUI.d.cts.map +1 -1
  129. package/dist/ui/AssetManagerUI.d.ts +19 -3
  130. package/dist/ui/AssetManagerUI.d.ts.map +1 -1
  131. package/dist/ui/AssetManagerUI.js +31 -17
  132. package/dist/ui/DeleteAssetDialog.cjs +5 -3
  133. package/dist/ui/DeleteAssetDialog.d.cts.map +1 -1
  134. package/dist/ui/DeleteAssetDialog.d.ts.map +1 -1
  135. package/dist/ui/DeleteAssetDialog.js +5 -3
  136. package/dist/ui/DeleteFolderDialog.cjs +80 -0
  137. package/dist/ui/DeleteFolderDialog.d.cts +11 -0
  138. package/dist/ui/DeleteFolderDialog.d.cts.map +1 -0
  139. package/dist/ui/DeleteFolderDialog.d.ts +11 -0
  140. package/dist/ui/DeleteFolderDialog.d.ts.map +1 -0
  141. package/dist/ui/DeleteFolderDialog.js +42 -0
  142. package/dist/ui/EmptyFolderState.cjs +56 -0
  143. package/dist/ui/EmptyFolderState.d.cts +6 -0
  144. package/dist/ui/EmptyFolderState.d.cts.map +1 -0
  145. package/dist/ui/EmptyFolderState.d.ts +6 -0
  146. package/dist/ui/EmptyFolderState.d.ts.map +1 -0
  147. package/dist/ui/EmptyFolderState.js +18 -0
  148. package/dist/ui/FolderBreadcrumb.cjs +76 -0
  149. package/dist/ui/FolderBreadcrumb.d.cts +9 -0
  150. package/dist/ui/FolderBreadcrumb.d.cts.map +1 -0
  151. package/dist/ui/FolderBreadcrumb.d.ts +9 -0
  152. package/dist/ui/FolderBreadcrumb.d.ts.map +1 -0
  153. package/dist/ui/FolderBreadcrumb.js +38 -0
  154. package/dist/ui/FolderNameDialog.cjs +105 -0
  155. package/dist/ui/FolderNameDialog.d.cts +14 -0
  156. package/dist/ui/FolderNameDialog.d.cts.map +1 -0
  157. package/dist/ui/FolderNameDialog.d.ts +14 -0
  158. package/dist/ui/FolderNameDialog.d.ts.map +1 -0
  159. package/dist/ui/FolderNameDialog.js +67 -0
  160. package/dist/ui/FolderTree.cjs +85 -0
  161. package/dist/ui/FolderTree.d.cts +13 -0
  162. package/dist/ui/FolderTree.d.cts.map +1 -0
  163. package/dist/ui/FolderTree.d.ts +13 -0
  164. package/dist/ui/FolderTree.d.ts.map +1 -0
  165. package/dist/ui/FolderTree.js +44 -0
  166. package/dist/ui/MetadataPanel.cjs +23 -17
  167. package/dist/ui/MetadataPanel.d.cts.map +1 -1
  168. package/dist/ui/MetadataPanel.d.ts.map +1 -1
  169. package/dist/ui/MetadataPanel.js +23 -17
  170. package/dist/ui/MoveTargetPicker.cjs +87 -0
  171. package/dist/ui/MoveTargetPicker.d.cts +16 -0
  172. package/dist/ui/MoveTargetPicker.d.cts.map +1 -0
  173. package/dist/ui/MoveTargetPicker.d.ts +16 -0
  174. package/dist/ui/MoveTargetPicker.d.ts.map +1 -0
  175. package/dist/ui/MoveTargetPicker.js +49 -0
  176. package/dist/ui/ReplaceAssetDialog.cjs +19 -17
  177. package/dist/ui/ReplaceAssetDialog.d.cts +2 -1
  178. package/dist/ui/ReplaceAssetDialog.d.cts.map +1 -1
  179. package/dist/ui/ReplaceAssetDialog.d.ts +2 -1
  180. package/dist/ui/ReplaceAssetDialog.d.ts.map +1 -1
  181. package/dist/ui/ReplaceAssetDialog.js +19 -17
  182. package/dist/ui/UnsplashPanel.cjs +137 -0
  183. package/dist/ui/UnsplashPanel.d.cts +28 -0
  184. package/dist/ui/UnsplashPanel.d.cts.map +1 -0
  185. package/dist/ui/UnsplashPanel.d.ts +28 -0
  186. package/dist/ui/UnsplashPanel.d.ts.map +1 -0
  187. package/dist/ui/UnsplashPanel.js +99 -0
  188. package/dist/ui/UploadButton.cjs +12 -13
  189. package/dist/ui/UploadButton.d.cts +9 -2
  190. package/dist/ui/UploadButton.d.cts.map +1 -1
  191. package/dist/ui/UploadButton.d.ts +9 -2
  192. package/dist/ui/UploadButton.d.ts.map +1 -1
  193. package/dist/ui/UploadButton.js +12 -13
  194. package/dist/ui/index.cjs +41 -0
  195. package/dist/ui/index.d.cts +15 -0
  196. package/dist/ui/index.d.cts.map +1 -1
  197. package/dist/ui/index.d.ts +15 -0
  198. package/dist/ui/index.d.ts.map +1 -1
  199. package/dist/ui/index.js +8 -0
  200. package/dist/utils/data-source.cjs +190 -0
  201. package/dist/utils/data-source.d.cts +63 -0
  202. package/dist/utils/data-source.d.cts.map +1 -0
  203. package/dist/utils/data-source.d.ts +63 -0
  204. package/dist/utils/data-source.d.ts.map +1 -0
  205. package/dist/utils/data-source.js +149 -0
  206. package/dist/utils/errors.cjs +18 -0
  207. package/dist/utils/errors.d.cts +27 -0
  208. package/dist/utils/errors.d.cts.map +1 -1
  209. package/dist/utils/errors.d.ts +27 -0
  210. package/dist/utils/errors.d.ts.map +1 -1
  211. package/dist/utils/errors.js +16 -1
  212. package/dist/utils/folders.cjs +335 -0
  213. package/dist/utils/folders.d.cts +54 -0
  214. package/dist/utils/folders.d.cts.map +1 -0
  215. package/dist/utils/folders.d.ts +54 -0
  216. package/dist/utils/folders.d.ts.map +1 -0
  217. package/dist/utils/folders.js +297 -0
  218. package/dist/utils/header-action.cjs +1 -1
  219. package/dist/utils/header-action.d.cts.map +1 -1
  220. package/dist/utils/header-action.d.ts.map +1 -1
  221. package/dist/utils/header-action.js +1 -1
  222. package/dist/utils/registry.cjs +38 -12
  223. package/dist/utils/registry.d.cts +29 -1
  224. package/dist/utils/registry.d.cts.map +1 -1
  225. package/dist/utils/registry.d.ts +29 -1
  226. package/dist/utils/registry.d.ts.map +1 -1
  227. package/dist/utils/registry.js +31 -11
  228. package/dist/utils/resolver.cjs +5 -4
  229. package/dist/utils/resolver.d.cts.map +1 -1
  230. package/dist/utils/resolver.d.ts.map +1 -1
  231. package/dist/utils/resolver.js +5 -4
  232. package/dist/utils/studio-asset-source.cjs +13 -4
  233. package/dist/utils/studio-asset-source.d.cts +6 -1
  234. package/dist/utils/studio-asset-source.d.cts.map +1 -1
  235. package/dist/utils/studio-asset-source.d.ts +6 -1
  236. package/dist/utils/studio-asset-source.d.ts.map +1 -1
  237. package/dist/utils/studio-asset-source.js +9 -3
  238. package/dist/utils/validate-upload-result.d.cts +2 -1
  239. package/dist/utils/validate-upload-result.d.cts.map +1 -1
  240. package/dist/utils/validate-upload-result.d.ts +2 -1
  241. package/dist/utils/validate-upload-result.d.ts.map +1 -1
  242. package/dist/version.cjs +1 -1
  243. package/dist/version.d.cts +1 -1
  244. package/dist/version.d.ts +1 -1
  245. package/dist/version.js +1 -1
  246. package/i18n/messages/en.json +99 -0
  247. package/i18n/messages/ja.json +99 -0
  248. package/i18n/messages/ko.json +99 -0
  249. package/i18n/messages/zh.json +99 -0
  250. package/meta/config.json +1 -1
  251. package/package.json +19 -8
@@ -0,0 +1,194 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
13
+ };
14
+ })();
15
+ (()=>{
16
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.r = (exports1)=>{
20
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
21
+ value: 'Module'
22
+ });
23
+ Object.defineProperty(exports1, '__esModule', {
24
+ value: true
25
+ });
26
+ };
27
+ })();
28
+ var __webpack_exports__ = {};
29
+ __webpack_require__.r(__webpack_exports__);
30
+ __webpack_require__.d(__webpack_exports__, {
31
+ UNSPLASH_THEME_FACET: ()=>UNSPLASH_THEME_FACET,
32
+ createUnsplashProvider: ()=>createUnsplashProvider,
33
+ unsplashEnabled: ()=>unsplashEnabled
34
+ });
35
+ const external_client_cjs_namespaceObject = require("./client.cjs");
36
+ const external_themes_cjs_namespaceObject = require("./themes.cjs");
37
+ const external_throttle_cache_cjs_namespaceObject = require("./throttle-cache.cjs");
38
+ const UNSPLASH_THEME_FACET = "unsplash:theme";
39
+ const BYID_MAX_ENTRIES = 512;
40
+ function unsplashEnabled(options) {
41
+ return options.enabled ?? (void 0 !== options.proxyEndpoint || void 0 !== options.accessKey);
42
+ }
43
+ function clamp(value, min, max) {
44
+ return Math.min(max, Math.max(min, value));
45
+ }
46
+ function createUnsplashProvider(options) {
47
+ const client = (0, external_client_cjs_namespaceObject.createUnsplashClient)({
48
+ ...void 0 !== options.proxyEndpoint ? {
49
+ proxyEndpoint: options.proxyEndpoint
50
+ } : {},
51
+ ...void 0 !== options.accessKey ? {
52
+ accessKey: options.accessKey
53
+ } : {},
54
+ ...void 0 !== options.fetch ? {
55
+ fetch: options.fetch
56
+ } : {},
57
+ ..."number" == typeof options.requestTimeoutMs && Number.isFinite(options.requestTimeoutMs) && options.requestTimeoutMs > 0 ? {
58
+ timeoutMs: options.requestTimeoutMs
59
+ } : {}
60
+ });
61
+ const utm = `utm_source=${encodeURIComponent(options.appName)}&utm_medium=referral`;
62
+ const themes = (0, external_themes_cjs_namespaceObject.resolveThemes)(options.themes);
63
+ const defaultThemeId = (0, external_themes_cjs_namespaceObject.resolveDefaultThemeId)(themes, options.themes);
64
+ const perPage = clamp(Math.trunc(options.perPage ?? 24), 1, 30);
65
+ const cache = (0, external_throttle_cache_cjs_namespaceObject.createTtlCache)(options.cacheTtlMs ?? 300000);
66
+ const throttle = (0, external_throttle_cache_cjs_namespaceObject.createSingleFlightThrottle)({
67
+ minIntervalMs: options.minRequestIntervalMs ?? 1200
68
+ });
69
+ const byId = (0, external_throttle_cache_cjs_namespaceObject.createTtlCache)(options.cacheTtlMs ?? 300000, BYID_MAX_ENTRIES);
70
+ const toUploadResult = (photo)=>Object.freeze({
71
+ id: `unsplash:${photo.id}`,
72
+ url: photo.urls.regular,
73
+ name: photo.description?.trim() || photo.alt_description?.trim() || `Unsplash ${photo.id}`,
74
+ meta: {
75
+ ...void 0 !== photo.width ? {
76
+ width: photo.width
77
+ } : {},
78
+ ...void 0 !== photo.height ? {
79
+ height: photo.height
80
+ } : {},
81
+ mimeType: "image/jpeg",
82
+ attribution: {
83
+ source: "unsplash",
84
+ photographerName: photo.user.name,
85
+ photographerUrl: `${photo.user.links.html}?${utm}`,
86
+ unsplashUrl: `https://unsplash.com/?${utm}`,
87
+ photoUrl: photo.links.html,
88
+ downloadLocation: photo.links.download_location
89
+ }
90
+ }
91
+ });
92
+ const findTheme = (id)=>themes.find((theme)=>theme.id === id);
93
+ const search = async (filter, page, signal)=>{
94
+ const pageNum = void 0 !== page ? Math.max(1, Number(page) || 1) : 1;
95
+ const themeId = filter.facets?.[UNSPLASH_THEME_FACET]?.[0] ?? defaultThemeId;
96
+ const theme = findTheme(themeId);
97
+ const freeText = filter.query?.trim() ?? "";
98
+ const cacheKey = `${themeId ?? ""}|${freeText}|${pageNum}`;
99
+ const hit = cache.get(cacheKey, Date.now());
100
+ if (void 0 !== hit) return hit;
101
+ let photos;
102
+ let total;
103
+ if (theme?.topicSlugs && theme.topicSlugs.length > 0 && "" === freeText && themeId !== external_themes_cjs_namespaceObject.ALL_THEME_ID) {
104
+ const slug = theme.topicSlugs[0] ?? "";
105
+ photos = await throttle.run(()=>client.topicPhotos(slug, {
106
+ page: pageNum,
107
+ perPage,
108
+ ...theme.orientation ? {
109
+ orientation: theme.orientation
110
+ } : {}
111
+ }, signal));
112
+ total = photos.length;
113
+ } else {
114
+ const query = [
115
+ theme?.query,
116
+ freeText
117
+ ].filter((part)=>Boolean(part)).join(" ") || "editorial";
118
+ const result = await throttle.run(()=>client.searchPhotos({
119
+ query,
120
+ page: pageNum,
121
+ perPage,
122
+ contentFilter: theme?.contentFilter ?? "high",
123
+ ...theme?.orientation ? {
124
+ orientation: theme.orientation
125
+ } : {}
126
+ }, signal));
127
+ photos = result.results;
128
+ total = result.total;
129
+ }
130
+ const items = photos.map(toUploadResult);
131
+ const seenAt = Date.now();
132
+ for (const item of items)byId.set(item.id, item, seenAt);
133
+ const listPage = {
134
+ items,
135
+ total,
136
+ nextCursor: photos.length >= perPage ? String(pageNum + 1) : void 0
137
+ };
138
+ cache.set(cacheKey, listPage, Date.now());
139
+ return listPage;
140
+ };
141
+ const pickResult = async (asset, signal)=>{
142
+ const cached = byId.get(asset.id, Date.now());
143
+ if (cached?.meta?.attribution !== void 0) {
144
+ client.trackDownload(cached.meta.attribution.downloadLocation, signal);
145
+ return cached;
146
+ }
147
+ const photoId = asset.id.startsWith("unsplash:") ? asset.id.slice(9) : asset.id;
148
+ try {
149
+ const result = toUploadResult(await client.getPhoto(photoId, signal));
150
+ byId.set(result.id, result, Date.now());
151
+ if (result.meta?.attribution !== void 0) client.trackDownload(result.meta.attribution.downloadLocation, signal);
152
+ return result;
153
+ } catch {
154
+ return {
155
+ id: asset.id,
156
+ url: asset.url
157
+ };
158
+ }
159
+ };
160
+ const listThemes = ()=>themes;
161
+ return {
162
+ id: "unsplash",
163
+ label: "assetManager.source.unsplash",
164
+ capabilities: {
165
+ searchable: true,
166
+ themed: true,
167
+ mutable: false,
168
+ requiresAttribution: true,
169
+ folders: false
170
+ },
171
+ requiredCsp: ()=>({
172
+ connectSrc: [
173
+ "https://api.unsplash.com"
174
+ ],
175
+ imgSrc: [
176
+ "https://images.unsplash.com"
177
+ ]
178
+ }),
179
+ listThemes,
180
+ search,
181
+ pickResult
182
+ };
183
+ }
184
+ exports.UNSPLASH_THEME_FACET = __webpack_exports__.UNSPLASH_THEME_FACET;
185
+ exports.createUnsplashProvider = __webpack_exports__.createUnsplashProvider;
186
+ exports.unsplashEnabled = __webpack_exports__.unsplashEnabled;
187
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
188
+ "UNSPLASH_THEME_FACET",
189
+ "createUnsplashProvider",
190
+ "unsplashEnabled"
191
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
192
+ Object.defineProperty(exports, '__esModule', {
193
+ value: true
194
+ });
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @file Unsplash `AssetSourceProvider` (PRD 0002 §8). Lazy entry point reached
3
+ * only via `import()` from the factory — never in the headless chunk. Public
4
+ * subpath: `@anvilkit/plugin-asset-manager/providers/unsplash`.
5
+ *
6
+ * Compliance baked in: search returns hotlinked `urls.regular` + full
7
+ * attribution metadata; `pickResult` fires the MANDATORY download trigger.
8
+ */
9
+ import type { UnsplashSourceOptions } from "../../types/unsplash.js";
10
+ import type { AssetSourceProvider } from "../provider.js";
11
+ /** The facet key the UI uses to carry the active theme into a query. */
12
+ export declare const UNSPLASH_THEME_FACET = "unsplash:theme";
13
+ /** Enabled when a proxy endpoint or access key is present (or forced via `enabled`). */
14
+ export declare function unsplashEnabled(options: UnsplashSourceOptions): boolean;
15
+ export declare function createUnsplashProvider(options: UnsplashSourceOptions): AssetSourceProvider;
16
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../../src/sources/unsplash/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,KAAK,EAAE,mBAAmB,EAAc,MAAM,gBAAgB,CAAC;AAYtE,wEAAwE;AACxE,eAAO,MAAM,oBAAoB,mBAAmB,CAAC;AASrD,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAKvE;AAMD,wBAAgB,sBAAsB,CACrC,OAAO,EAAE,qBAAqB,GAC5B,mBAAmB,CA0LrB"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @file Unsplash `AssetSourceProvider` (PRD 0002 §8). Lazy entry point reached
3
+ * only via `import()` from the factory — never in the headless chunk. Public
4
+ * subpath: `@anvilkit/plugin-asset-manager/providers/unsplash`.
5
+ *
6
+ * Compliance baked in: search returns hotlinked `urls.regular` + full
7
+ * attribution metadata; `pickResult` fires the MANDATORY download trigger.
8
+ */
9
+ import type { UnsplashSourceOptions } from "../../types/unsplash.js";
10
+ import type { AssetSourceProvider } from "../provider.js";
11
+ /** The facet key the UI uses to carry the active theme into a query. */
12
+ export declare const UNSPLASH_THEME_FACET = "unsplash:theme";
13
+ /** Enabled when a proxy endpoint or access key is present (or forced via `enabled`). */
14
+ export declare function unsplashEnabled(options: UnsplashSourceOptions): boolean;
15
+ export declare function createUnsplashProvider(options: UnsplashSourceOptions): AssetSourceProvider;
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sources/unsplash/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,KAAK,EAAE,mBAAmB,EAAc,MAAM,gBAAgB,CAAC;AAYtE,wEAAwE;AACxE,eAAO,MAAM,oBAAoB,mBAAmB,CAAC;AASrD,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAKvE;AAMD,wBAAgB,sBAAsB,CACrC,OAAO,EAAE,qBAAqB,GAC5B,mBAAmB,CA0LrB"}
@@ -0,0 +1,150 @@
1
+ import { createUnsplashClient } from "./client.js";
2
+ import { ALL_THEME_ID, resolveDefaultThemeId, resolveThemes } from "./themes.js";
3
+ import { createSingleFlightThrottle, createTtlCache } from "./throttle-cache.js";
4
+ const UNSPLASH_THEME_FACET = "unsplash:theme";
5
+ const BYID_MAX_ENTRIES = 512;
6
+ function unsplashEnabled(options) {
7
+ return options.enabled ?? (void 0 !== options.proxyEndpoint || void 0 !== options.accessKey);
8
+ }
9
+ function clamp(value, min, max) {
10
+ return Math.min(max, Math.max(min, value));
11
+ }
12
+ function createUnsplashProvider(options) {
13
+ const client = createUnsplashClient({
14
+ ...void 0 !== options.proxyEndpoint ? {
15
+ proxyEndpoint: options.proxyEndpoint
16
+ } : {},
17
+ ...void 0 !== options.accessKey ? {
18
+ accessKey: options.accessKey
19
+ } : {},
20
+ ...void 0 !== options.fetch ? {
21
+ fetch: options.fetch
22
+ } : {},
23
+ ..."number" == typeof options.requestTimeoutMs && Number.isFinite(options.requestTimeoutMs) && options.requestTimeoutMs > 0 ? {
24
+ timeoutMs: options.requestTimeoutMs
25
+ } : {}
26
+ });
27
+ const utm = `utm_source=${encodeURIComponent(options.appName)}&utm_medium=referral`;
28
+ const themes = resolveThemes(options.themes);
29
+ const defaultThemeId = resolveDefaultThemeId(themes, options.themes);
30
+ const perPage = clamp(Math.trunc(options.perPage ?? 24), 1, 30);
31
+ const cache = createTtlCache(options.cacheTtlMs ?? 300000);
32
+ const throttle = createSingleFlightThrottle({
33
+ minIntervalMs: options.minRequestIntervalMs ?? 1200
34
+ });
35
+ const byId = createTtlCache(options.cacheTtlMs ?? 300000, BYID_MAX_ENTRIES);
36
+ const toUploadResult = (photo)=>Object.freeze({
37
+ id: `unsplash:${photo.id}`,
38
+ url: photo.urls.regular,
39
+ name: photo.description?.trim() || photo.alt_description?.trim() || `Unsplash ${photo.id}`,
40
+ meta: {
41
+ ...void 0 !== photo.width ? {
42
+ width: photo.width
43
+ } : {},
44
+ ...void 0 !== photo.height ? {
45
+ height: photo.height
46
+ } : {},
47
+ mimeType: "image/jpeg",
48
+ attribution: {
49
+ source: "unsplash",
50
+ photographerName: photo.user.name,
51
+ photographerUrl: `${photo.user.links.html}?${utm}`,
52
+ unsplashUrl: `https://unsplash.com/?${utm}`,
53
+ photoUrl: photo.links.html,
54
+ downloadLocation: photo.links.download_location
55
+ }
56
+ }
57
+ });
58
+ const findTheme = (id)=>themes.find((theme)=>theme.id === id);
59
+ const search = async (filter, page, signal)=>{
60
+ const pageNum = void 0 !== page ? Math.max(1, Number(page) || 1) : 1;
61
+ const themeId = filter.facets?.[UNSPLASH_THEME_FACET]?.[0] ?? defaultThemeId;
62
+ const theme = findTheme(themeId);
63
+ const freeText = filter.query?.trim() ?? "";
64
+ const cacheKey = `${themeId ?? ""}|${freeText}|${pageNum}`;
65
+ const hit = cache.get(cacheKey, Date.now());
66
+ if (void 0 !== hit) return hit;
67
+ let photos;
68
+ let total;
69
+ if (theme?.topicSlugs && theme.topicSlugs.length > 0 && "" === freeText && themeId !== ALL_THEME_ID) {
70
+ const slug = theme.topicSlugs[0] ?? "";
71
+ photos = await throttle.run(()=>client.topicPhotos(slug, {
72
+ page: pageNum,
73
+ perPage,
74
+ ...theme.orientation ? {
75
+ orientation: theme.orientation
76
+ } : {}
77
+ }, signal));
78
+ total = photos.length;
79
+ } else {
80
+ const query = [
81
+ theme?.query,
82
+ freeText
83
+ ].filter((part)=>Boolean(part)).join(" ") || "editorial";
84
+ const result = await throttle.run(()=>client.searchPhotos({
85
+ query,
86
+ page: pageNum,
87
+ perPage,
88
+ contentFilter: theme?.contentFilter ?? "high",
89
+ ...theme?.orientation ? {
90
+ orientation: theme.orientation
91
+ } : {}
92
+ }, signal));
93
+ photos = result.results;
94
+ total = result.total;
95
+ }
96
+ const items = photos.map(toUploadResult);
97
+ const seenAt = Date.now();
98
+ for (const item of items)byId.set(item.id, item, seenAt);
99
+ const listPage = {
100
+ items,
101
+ total,
102
+ nextCursor: photos.length >= perPage ? String(pageNum + 1) : void 0
103
+ };
104
+ cache.set(cacheKey, listPage, Date.now());
105
+ return listPage;
106
+ };
107
+ const pickResult = async (asset, signal)=>{
108
+ const cached = byId.get(asset.id, Date.now());
109
+ if (cached?.meta?.attribution !== void 0) {
110
+ client.trackDownload(cached.meta.attribution.downloadLocation, signal);
111
+ return cached;
112
+ }
113
+ const photoId = asset.id.startsWith("unsplash:") ? asset.id.slice(9) : asset.id;
114
+ try {
115
+ const result = toUploadResult(await client.getPhoto(photoId, signal));
116
+ byId.set(result.id, result, Date.now());
117
+ if (result.meta?.attribution !== void 0) client.trackDownload(result.meta.attribution.downloadLocation, signal);
118
+ return result;
119
+ } catch {
120
+ return {
121
+ id: asset.id,
122
+ url: asset.url
123
+ };
124
+ }
125
+ };
126
+ const listThemes = ()=>themes;
127
+ return {
128
+ id: "unsplash",
129
+ label: "assetManager.source.unsplash",
130
+ capabilities: {
131
+ searchable: true,
132
+ themed: true,
133
+ mutable: false,
134
+ requiresAttribution: true,
135
+ folders: false
136
+ },
137
+ requiredCsp: ()=>({
138
+ connectSrc: [
139
+ "https://api.unsplash.com"
140
+ ],
141
+ imgSrc: [
142
+ "https://images.unsplash.com"
143
+ ]
144
+ }),
145
+ listThemes,
146
+ search,
147
+ pickResult
148
+ };
149
+ }
150
+ export { UNSPLASH_THEME_FACET, createUnsplashProvider, unsplashEnabled };
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
13
+ };
14
+ })();
15
+ (()=>{
16
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.r = (exports1)=>{
20
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
21
+ value: 'Module'
22
+ });
23
+ Object.defineProperty(exports1, '__esModule', {
24
+ value: true
25
+ });
26
+ };
27
+ })();
28
+ var __webpack_exports__ = {};
29
+ __webpack_require__.r(__webpack_exports__);
30
+ const ALL_THEME_ID = "__all__";
31
+ const DEFAULT_UNSPLASH_THEMES = Object.freeze([
32
+ {
33
+ id: "nature",
34
+ label: "assetManager.unsplash.theme.nature",
35
+ topicSlugs: [
36
+ "nature"
37
+ ],
38
+ query: "nature landscape",
39
+ orientation: "landscape"
40
+ },
41
+ {
42
+ id: "architecture",
43
+ label: "assetManager.unsplash.theme.architecture",
44
+ topicSlugs: [
45
+ "architecture-interior"
46
+ ],
47
+ query: "architecture building"
48
+ },
49
+ {
50
+ id: "business",
51
+ label: "assetManager.unsplash.theme.business",
52
+ topicSlugs: [
53
+ "business-work"
54
+ ],
55
+ query: "business office work"
56
+ },
57
+ {
58
+ id: "food",
59
+ label: "assetManager.unsplash.theme.food",
60
+ topicSlugs: [
61
+ "food-drink"
62
+ ],
63
+ query: "food meal"
64
+ },
65
+ {
66
+ id: "technology",
67
+ label: "assetManager.unsplash.theme.technology",
68
+ topicSlugs: [
69
+ "experimental"
70
+ ],
71
+ query: "technology computer"
72
+ },
73
+ {
74
+ id: "travel",
75
+ label: "assetManager.unsplash.theme.travel",
76
+ topicSlugs: [
77
+ "travel"
78
+ ],
79
+ query: "travel destination"
80
+ },
81
+ {
82
+ id: "texture",
83
+ label: "assetManager.unsplash.theme.texture",
84
+ topicSlugs: [
85
+ "textures-patterns"
86
+ ],
87
+ query: "abstract texture",
88
+ orientation: "squarish"
89
+ },
90
+ {
91
+ id: "people",
92
+ label: "assetManager.unsplash.theme.people",
93
+ topicSlugs: [
94
+ "people"
95
+ ],
96
+ query: "people portrait"
97
+ }
98
+ ]);
99
+ function resolveThemes(config) {
100
+ let base;
101
+ if (config?.themes) base = config.themes;
102
+ else {
103
+ const excluded = new Set(config?.excludeThemes ?? []);
104
+ const filtered = excluded.size > 0 ? DEFAULT_UNSPLASH_THEMES.filter((t)=>!excluded.has(t.id)) : DEFAULT_UNSPLASH_THEMES;
105
+ base = config?.additionalThemes ? [
106
+ ...filtered,
107
+ ...config.additionalThemes
108
+ ] : filtered;
109
+ }
110
+ const themes = [];
111
+ if (config?.allowFreeSearch !== false) themes.push({
112
+ id: ALL_THEME_ID,
113
+ label: "assetManager.unsplash.theme.all"
114
+ });
115
+ themes.push(...base);
116
+ return Object.freeze(themes);
117
+ }
118
+ function resolveDefaultThemeId(themes, config) {
119
+ if (config?.defaultThemeId && themes.some((t)=>t.id === config.defaultThemeId)) return config.defaultThemeId;
120
+ return themes[0]?.id;
121
+ }
122
+ __webpack_require__.d(__webpack_exports__, {
123
+ resolveDefaultThemeId: ()=>resolveDefaultThemeId,
124
+ resolveThemes: ()=>resolveThemes
125
+ }, {
126
+ ALL_THEME_ID: ALL_THEME_ID,
127
+ DEFAULT_UNSPLASH_THEMES: DEFAULT_UNSPLASH_THEMES
128
+ });
129
+ exports.ALL_THEME_ID = __webpack_exports__.ALL_THEME_ID;
130
+ exports.DEFAULT_UNSPLASH_THEMES = __webpack_exports__.DEFAULT_UNSPLASH_THEMES;
131
+ exports.resolveDefaultThemeId = __webpack_exports__.resolveDefaultThemeId;
132
+ exports.resolveThemes = __webpack_exports__.resolveThemes;
133
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
134
+ "ALL_THEME_ID",
135
+ "DEFAULT_UNSPLASH_THEMES",
136
+ "resolveDefaultThemeId",
137
+ "resolveThemes"
138
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
139
+ Object.defineProperty(exports, '__esModule', {
140
+ value: true
141
+ });
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @file Default Unsplash theme set + resolution (PRD 0002 §8.2). A theme maps
3
+ * to an Unsplash topic slug (tried first), a curated search query (fallback /
4
+ * supplement), or both. Labels are i18n message keys, never inline copy.
5
+ */
6
+ import type { UnsplashTheme, UnsplashThemeConfig } from "../../types/unsplash.js";
7
+ /** The free-search pseudo-theme prepended unless `allowFreeSearch === false`. */
8
+ export declare const ALL_THEME_ID = "__all__";
9
+ export declare const DEFAULT_UNSPLASH_THEMES: readonly UnsplashTheme[];
10
+ /**
11
+ * Resolve the effective theme list: replace-all when `themes` is given, else
12
+ * filter the defaults by `excludeThemes` and append `additionalThemes`. The
13
+ * `__all__` free-search pseudo-theme is prepended unless disabled.
14
+ */
15
+ export declare function resolveThemes(config?: UnsplashThemeConfig): readonly UnsplashTheme[];
16
+ /** Pick the initial theme: the configured default if present, else the first. */
17
+ export declare function resolveDefaultThemeId(themes: readonly UnsplashTheme[], config?: UnsplashThemeConfig): string | undefined;
18
+ //# sourceMappingURL=themes.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themes.d.cts","sourceRoot":"","sources":["../../../src/sources/unsplash/themes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACX,aAAa,EACb,mBAAmB,EACnB,MAAM,yBAAyB,CAAC;AAEjC,iFAAiF;AACjF,eAAO,MAAM,YAAY,YAAY,CAAC;AAEtC,eAAO,MAAM,uBAAuB,EAAE,SAAS,aAAa,EAmD1D,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,aAAa,CAC5B,MAAM,CAAC,EAAE,mBAAmB,GAC1B,SAAS,aAAa,EAAE,CAqB1B;AAED,iFAAiF;AACjF,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,MAAM,CAAC,EAAE,mBAAmB,GAC1B,MAAM,GAAG,SAAS,CAQpB"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @file Default Unsplash theme set + resolution (PRD 0002 §8.2). A theme maps
3
+ * to an Unsplash topic slug (tried first), a curated search query (fallback /
4
+ * supplement), or both. Labels are i18n message keys, never inline copy.
5
+ */
6
+ import type { UnsplashTheme, UnsplashThemeConfig } from "../../types/unsplash.js";
7
+ /** The free-search pseudo-theme prepended unless `allowFreeSearch === false`. */
8
+ export declare const ALL_THEME_ID = "__all__";
9
+ export declare const DEFAULT_UNSPLASH_THEMES: readonly UnsplashTheme[];
10
+ /**
11
+ * Resolve the effective theme list: replace-all when `themes` is given, else
12
+ * filter the defaults by `excludeThemes` and append `additionalThemes`. The
13
+ * `__all__` free-search pseudo-theme is prepended unless disabled.
14
+ */
15
+ export declare function resolveThemes(config?: UnsplashThemeConfig): readonly UnsplashTheme[];
16
+ /** Pick the initial theme: the configured default if present, else the first. */
17
+ export declare function resolveDefaultThemeId(themes: readonly UnsplashTheme[], config?: UnsplashThemeConfig): string | undefined;
18
+ //# sourceMappingURL=themes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../../src/sources/unsplash/themes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACX,aAAa,EACb,mBAAmB,EACnB,MAAM,yBAAyB,CAAC;AAEjC,iFAAiF;AACjF,eAAO,MAAM,YAAY,YAAY,CAAC;AAEtC,eAAO,MAAM,uBAAuB,EAAE,SAAS,aAAa,EAmD1D,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,aAAa,CAC5B,MAAM,CAAC,EAAE,mBAAmB,GAC1B,SAAS,aAAa,EAAE,CAqB1B;AAED,iFAAiF;AACjF,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,MAAM,CAAC,EAAE,mBAAmB,GAC1B,MAAM,GAAG,SAAS,CAQpB"}
@@ -0,0 +1,93 @@
1
+ const ALL_THEME_ID = "__all__";
2
+ const DEFAULT_UNSPLASH_THEMES = Object.freeze([
3
+ {
4
+ id: "nature",
5
+ label: "assetManager.unsplash.theme.nature",
6
+ topicSlugs: [
7
+ "nature"
8
+ ],
9
+ query: "nature landscape",
10
+ orientation: "landscape"
11
+ },
12
+ {
13
+ id: "architecture",
14
+ label: "assetManager.unsplash.theme.architecture",
15
+ topicSlugs: [
16
+ "architecture-interior"
17
+ ],
18
+ query: "architecture building"
19
+ },
20
+ {
21
+ id: "business",
22
+ label: "assetManager.unsplash.theme.business",
23
+ topicSlugs: [
24
+ "business-work"
25
+ ],
26
+ query: "business office work"
27
+ },
28
+ {
29
+ id: "food",
30
+ label: "assetManager.unsplash.theme.food",
31
+ topicSlugs: [
32
+ "food-drink"
33
+ ],
34
+ query: "food meal"
35
+ },
36
+ {
37
+ id: "technology",
38
+ label: "assetManager.unsplash.theme.technology",
39
+ topicSlugs: [
40
+ "experimental"
41
+ ],
42
+ query: "technology computer"
43
+ },
44
+ {
45
+ id: "travel",
46
+ label: "assetManager.unsplash.theme.travel",
47
+ topicSlugs: [
48
+ "travel"
49
+ ],
50
+ query: "travel destination"
51
+ },
52
+ {
53
+ id: "texture",
54
+ label: "assetManager.unsplash.theme.texture",
55
+ topicSlugs: [
56
+ "textures-patterns"
57
+ ],
58
+ query: "abstract texture",
59
+ orientation: "squarish"
60
+ },
61
+ {
62
+ id: "people",
63
+ label: "assetManager.unsplash.theme.people",
64
+ topicSlugs: [
65
+ "people"
66
+ ],
67
+ query: "people portrait"
68
+ }
69
+ ]);
70
+ function resolveThemes(config) {
71
+ let base;
72
+ if (config?.themes) base = config.themes;
73
+ else {
74
+ const excluded = new Set(config?.excludeThemes ?? []);
75
+ const filtered = excluded.size > 0 ? DEFAULT_UNSPLASH_THEMES.filter((t)=>!excluded.has(t.id)) : DEFAULT_UNSPLASH_THEMES;
76
+ base = config?.additionalThemes ? [
77
+ ...filtered,
78
+ ...config.additionalThemes
79
+ ] : filtered;
80
+ }
81
+ const themes = [];
82
+ if (config?.allowFreeSearch !== false) themes.push({
83
+ id: ALL_THEME_ID,
84
+ label: "assetManager.unsplash.theme.all"
85
+ });
86
+ themes.push(...base);
87
+ return Object.freeze(themes);
88
+ }
89
+ function resolveDefaultThemeId(themes, config) {
90
+ if (config?.defaultThemeId && themes.some((t)=>t.id === config.defaultThemeId)) return config.defaultThemeId;
91
+ return themes[0]?.id;
92
+ }
93
+ export { ALL_THEME_ID, DEFAULT_UNSPLASH_THEMES, resolveDefaultThemeId, resolveThemes };