@anvilkit/plugin-asset-manager 0.1.5 → 0.1.7

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 (224) hide show
  1. package/README.md +27 -19
  2. package/dist/adapters/data-url.cjs +9 -5
  3. package/dist/adapters/extract-image-dimensions.cjs +12 -8
  4. package/dist/adapters/in-memory.cjs +9 -5
  5. package/dist/adapters/s3-presigned.cjs +9 -5
  6. package/dist/index.cjs +16 -5
  7. package/dist/index.d.cts +11 -3
  8. package/dist/index.d.cts.map +1 -1
  9. package/dist/index.d.ts +11 -3
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +2 -1
  12. package/dist/plugin.cjs +76 -9
  13. package/dist/plugin.d.cts +3 -2
  14. package/dist/plugin.d.cts.map +1 -1
  15. package/dist/plugin.d.ts +3 -2
  16. package/dist/plugin.d.ts.map +1 -1
  17. package/dist/plugin.js +67 -4
  18. package/dist/sources/composite-source.cjs +137 -0
  19. package/dist/sources/composite-source.d.cts +39 -0
  20. package/dist/sources/composite-source.d.cts.map +1 -0
  21. package/dist/sources/composite-source.d.ts +39 -0
  22. package/dist/sources/composite-source.d.ts.map +1 -0
  23. package/dist/sources/composite-source.js +99 -0
  24. package/dist/sources/federated-search.cjs +163 -0
  25. package/dist/sources/federated-search.d.cts +33 -0
  26. package/dist/sources/federated-search.d.cts.map +1 -0
  27. package/dist/sources/federated-search.d.ts +33 -0
  28. package/dist/sources/federated-search.d.ts.map +1 -0
  29. package/dist/sources/federated-search.js +113 -0
  30. package/dist/sources/provider.cjs +18 -0
  31. package/dist/sources/provider.d.cts +51 -0
  32. package/dist/sources/provider.d.cts.map +1 -0
  33. package/dist/sources/provider.d.ts +51 -0
  34. package/dist/sources/provider.d.ts.map +1 -0
  35. package/dist/sources/provider.js +1 -0
  36. package/dist/sources/unsplash/client.cjs +189 -0
  37. package/dist/sources/unsplash/client.d.cts +87 -0
  38. package/dist/sources/unsplash/client.d.cts.map +1 -0
  39. package/dist/sources/unsplash/client.d.ts +87 -0
  40. package/dist/sources/unsplash/client.d.ts.map +1 -0
  41. package/dist/sources/unsplash/client.js +151 -0
  42. package/dist/sources/unsplash/index.cjs +192 -0
  43. package/dist/sources/unsplash/index.d.cts +16 -0
  44. package/dist/sources/unsplash/index.d.cts.map +1 -0
  45. package/dist/sources/unsplash/index.d.ts +16 -0
  46. package/dist/sources/unsplash/index.d.ts.map +1 -0
  47. package/dist/sources/unsplash/index.js +148 -0
  48. package/dist/sources/unsplash/themes.cjs +141 -0
  49. package/dist/sources/unsplash/themes.d.cts +18 -0
  50. package/dist/sources/unsplash/themes.d.cts.map +1 -0
  51. package/dist/sources/unsplash/themes.d.ts +18 -0
  52. package/dist/sources/unsplash/themes.d.ts.map +1 -0
  53. package/dist/sources/unsplash/themes.js +93 -0
  54. package/dist/sources/unsplash/throttle-cache.cjs +86 -0
  55. package/dist/sources/unsplash/throttle-cache.d.cts +25 -0
  56. package/dist/sources/unsplash/throttle-cache.d.cts.map +1 -0
  57. package/dist/sources/unsplash/throttle-cache.d.ts +25 -0
  58. package/dist/sources/unsplash/throttle-cache.d.ts.map +1 -0
  59. package/dist/sources/unsplash/throttle-cache.js +45 -0
  60. package/dist/testing/index.cjs +9 -5
  61. package/dist/types/categories.cjs +18 -0
  62. package/dist/types/categories.d.cts +48 -0
  63. package/dist/types/categories.d.cts.map +1 -0
  64. package/dist/types/categories.d.ts +48 -0
  65. package/dist/types/categories.d.ts.map +1 -0
  66. package/dist/types/categories.js +1 -0
  67. package/dist/types/data-source.cjs +18 -0
  68. package/dist/types/data-source.d.cts +59 -0
  69. package/dist/types/data-source.d.cts.map +1 -0
  70. package/dist/types/data-source.d.ts +59 -0
  71. package/dist/types/data-source.d.ts.map +1 -0
  72. package/dist/types/data-source.js +1 -0
  73. package/dist/types/filter.cjs +18 -0
  74. package/dist/types/filter.d.cts +55 -0
  75. package/dist/types/filter.d.cts.map +1 -0
  76. package/dist/types/filter.d.ts +55 -0
  77. package/dist/types/filter.d.ts.map +1 -0
  78. package/dist/types/filter.js +1 -0
  79. package/dist/types/folders.cjs +42 -0
  80. package/dist/types/folders.d.cts +46 -0
  81. package/dist/types/folders.d.cts.map +1 -0
  82. package/dist/types/folders.d.ts +46 -0
  83. package/dist/types/folders.d.ts.map +1 -0
  84. package/dist/types/folders.js +4 -0
  85. package/dist/types/options.cjs +18 -0
  86. package/dist/types/options.d.cts +68 -0
  87. package/dist/types/options.d.cts.map +1 -0
  88. package/dist/types/options.d.ts +68 -0
  89. package/dist/types/options.d.ts.map +1 -0
  90. package/dist/types/options.js +1 -0
  91. package/dist/types/types.d.cts +15 -27
  92. package/dist/types/types.d.cts.map +1 -1
  93. package/dist/types/types.d.ts +15 -27
  94. package/dist/types/types.d.ts.map +1 -1
  95. package/dist/types/unsplash.cjs +18 -0
  96. package/dist/types/unsplash.d.cts +60 -0
  97. package/dist/types/unsplash.d.cts.map +1 -0
  98. package/dist/types/unsplash.d.ts +60 -0
  99. package/dist/types/unsplash.d.ts.map +1 -0
  100. package/dist/types/unsplash.js +1 -0
  101. package/dist/ui/AssetBrowser.cjs +69 -104
  102. package/dist/ui/AssetBrowser.d.cts +17 -7
  103. package/dist/ui/AssetBrowser.d.cts.map +1 -1
  104. package/dist/ui/AssetBrowser.d.ts +17 -7
  105. package/dist/ui/AssetBrowser.d.ts.map +1 -1
  106. package/dist/ui/AssetBrowser.js +60 -99
  107. package/dist/ui/AssetCommandPalette.cjs +9 -5
  108. package/dist/ui/AssetManagerUI.cjs +17 -7
  109. package/dist/ui/AssetManagerUI.d.cts +19 -3
  110. package/dist/ui/AssetManagerUI.d.cts.map +1 -1
  111. package/dist/ui/AssetManagerUI.d.ts +19 -3
  112. package/dist/ui/AssetManagerUI.d.ts.map +1 -1
  113. package/dist/ui/AssetManagerUI.js +8 -2
  114. package/dist/ui/DeleteAssetDialog.cjs +9 -5
  115. package/dist/ui/DeleteFolderDialog.cjs +78 -0
  116. package/dist/ui/DeleteFolderDialog.d.cts +11 -0
  117. package/dist/ui/DeleteFolderDialog.d.cts.map +1 -0
  118. package/dist/ui/DeleteFolderDialog.d.ts +11 -0
  119. package/dist/ui/DeleteFolderDialog.d.ts.map +1 -0
  120. package/dist/ui/DeleteFolderDialog.js +40 -0
  121. package/dist/ui/EmptyFolderState.cjs +53 -0
  122. package/dist/ui/EmptyFolderState.d.cts +6 -0
  123. package/dist/ui/EmptyFolderState.d.cts.map +1 -0
  124. package/dist/ui/EmptyFolderState.d.ts +6 -0
  125. package/dist/ui/EmptyFolderState.d.ts.map +1 -0
  126. package/dist/ui/EmptyFolderState.js +15 -0
  127. package/dist/ui/FolderBreadcrumb.cjs +73 -0
  128. package/dist/ui/FolderBreadcrumb.d.cts +9 -0
  129. package/dist/ui/FolderBreadcrumb.d.cts.map +1 -0
  130. package/dist/ui/FolderBreadcrumb.d.ts +9 -0
  131. package/dist/ui/FolderBreadcrumb.d.ts.map +1 -0
  132. package/dist/ui/FolderBreadcrumb.js +35 -0
  133. package/dist/ui/FolderNameDialog.cjs +98 -0
  134. package/dist/ui/FolderNameDialog.d.cts +14 -0
  135. package/dist/ui/FolderNameDialog.d.cts.map +1 -0
  136. package/dist/ui/FolderNameDialog.d.ts +14 -0
  137. package/dist/ui/FolderNameDialog.d.ts.map +1 -0
  138. package/dist/ui/FolderNameDialog.js +60 -0
  139. package/dist/ui/FolderTree.cjs +83 -0
  140. package/dist/ui/FolderTree.d.cts +13 -0
  141. package/dist/ui/FolderTree.d.cts.map +1 -0
  142. package/dist/ui/FolderTree.d.ts +13 -0
  143. package/dist/ui/FolderTree.d.ts.map +1 -0
  144. package/dist/ui/FolderTree.js +42 -0
  145. package/dist/ui/MetadataPanel.cjs +16 -9
  146. package/dist/ui/MetadataPanel.d.cts.map +1 -1
  147. package/dist/ui/MetadataPanel.d.ts.map +1 -1
  148. package/dist/ui/MetadataPanel.js +7 -4
  149. package/dist/ui/MoveTargetPicker.cjs +84 -0
  150. package/dist/ui/MoveTargetPicker.d.cts +16 -0
  151. package/dist/ui/MoveTargetPicker.d.cts.map +1 -0
  152. package/dist/ui/MoveTargetPicker.d.ts +16 -0
  153. package/dist/ui/MoveTargetPicker.d.ts.map +1 -0
  154. package/dist/ui/MoveTargetPicker.js +46 -0
  155. package/dist/ui/ReplaceAssetDialog.cjs +9 -5
  156. package/dist/ui/ReplaceAssetDialog.d.cts +2 -1
  157. package/dist/ui/ReplaceAssetDialog.d.cts.map +1 -1
  158. package/dist/ui/ReplaceAssetDialog.d.ts +2 -1
  159. package/dist/ui/ReplaceAssetDialog.d.ts.map +1 -1
  160. package/dist/ui/UnsplashPanel.cjs +134 -0
  161. package/dist/ui/UnsplashPanel.d.cts +28 -0
  162. package/dist/ui/UnsplashPanel.d.cts.map +1 -0
  163. package/dist/ui/UnsplashPanel.d.ts +28 -0
  164. package/dist/ui/UnsplashPanel.d.ts.map +1 -0
  165. package/dist/ui/UnsplashPanel.js +96 -0
  166. package/dist/ui/UploadButton.cjs +10 -10
  167. package/dist/ui/UploadButton.d.cts +9 -2
  168. package/dist/ui/UploadButton.d.cts.map +1 -1
  169. package/dist/ui/UploadButton.d.ts +9 -2
  170. package/dist/ui/UploadButton.d.ts.map +1 -1
  171. package/dist/ui/UploadButton.js +1 -5
  172. package/dist/ui/index.cjs +46 -5
  173. package/dist/ui/index.d.cts +14 -0
  174. package/dist/ui/index.d.cts.map +1 -1
  175. package/dist/ui/index.d.ts +14 -0
  176. package/dist/ui/index.d.ts.map +1 -1
  177. package/dist/ui/index.js +7 -0
  178. package/dist/utils/asset-reference.cjs +12 -8
  179. package/dist/utils/csp.cjs +12 -8
  180. package/dist/utils/data-source.cjs +177 -0
  181. package/dist/utils/data-source.d.cts +63 -0
  182. package/dist/utils/data-source.d.cts.map +1 -0
  183. package/dist/utils/data-source.d.ts +63 -0
  184. package/dist/utils/data-source.d.ts.map +1 -0
  185. package/dist/utils/data-source.js +136 -0
  186. package/dist/utils/errors.cjs +31 -9
  187. package/dist/utils/errors.d.cts +27 -0
  188. package/dist/utils/errors.d.cts.map +1 -1
  189. package/dist/utils/errors.d.ts +27 -0
  190. package/dist/utils/errors.d.ts.map +1 -1
  191. package/dist/utils/errors.js +16 -1
  192. package/dist/utils/folders.cjs +261 -0
  193. package/dist/utils/folders.d.cts +49 -0
  194. package/dist/utils/folders.d.cts.map +1 -0
  195. package/dist/utils/folders.d.ts +49 -0
  196. package/dist/utils/folders.d.ts.map +1 -0
  197. package/dist/utils/folders.js +223 -0
  198. package/dist/utils/header-action.cjs +12 -8
  199. package/dist/utils/infer-kind.cjs +12 -8
  200. package/dist/utils/registry.cjs +36 -17
  201. package/dist/utils/registry.d.cts +21 -1
  202. package/dist/utils/registry.d.cts.map +1 -1
  203. package/dist/utils/registry.d.ts +21 -1
  204. package/dist/utils/registry.d.ts.map +1 -1
  205. package/dist/utils/registry.js +20 -11
  206. package/dist/utils/resolver.cjs +9 -5
  207. package/dist/utils/retry.cjs +13 -9
  208. package/dist/utils/studio-asset-source.cjs +14 -7
  209. package/dist/utils/studio-asset-source.d.cts +6 -1
  210. package/dist/utils/studio-asset-source.d.cts.map +1 -1
  211. package/dist/utils/studio-asset-source.d.ts +6 -1
  212. package/dist/utils/studio-asset-source.d.ts.map +1 -1
  213. package/dist/utils/studio-asset-source.js +1 -1
  214. package/dist/utils/validate-upload-result.cjs +9 -5
  215. package/dist/utils/validate-upload-result.d.cts +2 -1
  216. package/dist/utils/validate-upload-result.d.cts.map +1 -1
  217. package/dist/utils/validate-upload-result.d.ts +2 -1
  218. package/dist/utils/validate-upload-result.d.ts.map +1 -1
  219. package/dist/version.cjs +12 -8
  220. package/dist/version.d.cts +1 -1
  221. package/dist/version.d.ts +1 -1
  222. package/dist/version.js +1 -1
  223. package/meta/config.json +1 -1
  224. package/package.json +19 -9
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @file In-memory `AssetDataSource` (PRD 0002 §6). Adapts the synchronous
3
+ * `AssetRegistry` + the {@link FolderStore} into the async, folder-aware data
4
+ * plane, WITHOUT changing the registry's API. The registry stays the single
5
+ * store for assets; folder membership lives in the side-index the folder store
6
+ * owns. Lazy-importable so flat callers pay nothing for folder code.
7
+ */
8
+ import type { AssetDataSource, AssetSourceStatus, ReplacePayload } from "../types/data-source.js";
9
+ import type { AssetFilter, AssetListPage } from "../types/filter.js";
10
+ import type { AssetFolder, FolderId } from "../types/folders.js";
11
+ import type { AssetRegistry, UploadResult } from "../types/types.js";
12
+ import { type FolderStore } from "./folders.js";
13
+ /**
14
+ * Binary ingest used by `replace` — the same `uploadAsset`-bound callback the
15
+ * `StudioAssetSource` already threads, so the security pipeline is single-sourced.
16
+ */
17
+ export type UploadFn = (file: File, options?: {
18
+ readonly signal?: AbortSignal;
19
+ }) => Promise<UploadResult>;
20
+ /** Fully-resolved data plane (no optional methods) stored on the runtime state. */
21
+ export interface ResolvedAssetDataSource {
22
+ list(query: AssetFilter, signal?: AbortSignal): Promise<AssetListPage>;
23
+ remove(id: string, signal?: AbortSignal): Promise<void>;
24
+ replace(id: string, payload: ReplacePayload, signal?: AbortSignal): Promise<UploadResult>;
25
+ rename(id: string, name: string, signal?: AbortSignal): Promise<UploadResult>;
26
+ move(id: string, folderId: FolderId | null, signal?: AbortSignal): Promise<void>;
27
+ createFolder(parentId: FolderId | null, name: string, signal?: AbortSignal): Promise<AssetFolder>;
28
+ renameFolder(id: FolderId, name: string, signal?: AbortSignal): Promise<AssetFolder>;
29
+ removeFolder(id: FolderId, opts?: {
30
+ readonly cascade?: boolean;
31
+ }, signal?: AbortSignal): Promise<void>;
32
+ moveFolder(id: FolderId, parentId: FolderId | null, signal?: AbortSignal): Promise<AssetFolder>;
33
+ /** Fires on any asset OR folder mutation (the sidebar re-lists). */
34
+ subscribe(listener: () => void): () => void;
35
+ subscribeStatus(listener: (status: AssetSourceStatus) => void): () => void;
36
+ /** The shared folder store (for the composite source / UI). */
37
+ readonly folders: FolderStore;
38
+ }
39
+ export interface CreateInMemoryDataSourceOptions {
40
+ readonly registry: AssetRegistry;
41
+ readonly upload: UploadFn;
42
+ /** Shared folder store — injected by the factory so the UI sees the same one. */
43
+ readonly folderStore?: FolderStore;
44
+ /** Max nesting depth from `FolderOptions`. */
45
+ readonly maxDepth?: number;
46
+ }
47
+ export declare function createInMemoryDataSource(options: CreateInMemoryDataSourceOptions): ResolvedAssetDataSource;
48
+ export interface ResolveDataSourceInput extends CreateInMemoryDataSourceOptions {
49
+ /** Host-supplied backend. When absent, the full in-memory default is used. */
50
+ readonly hostDataSource?: AssetDataSource;
51
+ /** One-time dev warning sink (e.g. `ctx.log`). */
52
+ readonly warn?: (message: string) => void;
53
+ }
54
+ /**
55
+ * Per-PLANE resolution ladder (PRD 0002 §5). A host that supplies the FULL
56
+ * method set of a plane owns that plane; a PARTIAL set warns once and the WHOLE
57
+ * plane falls back to the in-memory default — so the read and write planes are
58
+ * never split across two stores. `subscribeStatus` is taken from the host when
59
+ * present; `subscribe`/`folders` always come from the in-memory layer (the
60
+ * composite re-lists after host mutations; external push is out of scope).
61
+ */
62
+ export declare function resolveDataSource(input: ResolveDataSourceInput): ResolvedAssetDataSource;
63
+ //# sourceMappingURL=data-source.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-source.d.cts","sourceRoot":"","sources":["../../src/utils/data-source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @file In-memory `AssetDataSource` (PRD 0002 §6). Adapts the synchronous
3
+ * `AssetRegistry` + the {@link FolderStore} into the async, folder-aware data
4
+ * plane, WITHOUT changing the registry's API. The registry stays the single
5
+ * store for assets; folder membership lives in the side-index the folder store
6
+ * owns. Lazy-importable so flat callers pay nothing for folder code.
7
+ */
8
+ import type { AssetDataSource, AssetSourceStatus, ReplacePayload } from "../types/data-source.js";
9
+ import type { AssetFilter, AssetListPage } from "../types/filter.js";
10
+ import type { AssetFolder, FolderId } from "../types/folders.js";
11
+ import type { AssetRegistry, UploadResult } from "../types/types.js";
12
+ import { type FolderStore } from "./folders.js";
13
+ /**
14
+ * Binary ingest used by `replace` — the same `uploadAsset`-bound callback the
15
+ * `StudioAssetSource` already threads, so the security pipeline is single-sourced.
16
+ */
17
+ export type UploadFn = (file: File, options?: {
18
+ readonly signal?: AbortSignal;
19
+ }) => Promise<UploadResult>;
20
+ /** Fully-resolved data plane (no optional methods) stored on the runtime state. */
21
+ export interface ResolvedAssetDataSource {
22
+ list(query: AssetFilter, signal?: AbortSignal): Promise<AssetListPage>;
23
+ remove(id: string, signal?: AbortSignal): Promise<void>;
24
+ replace(id: string, payload: ReplacePayload, signal?: AbortSignal): Promise<UploadResult>;
25
+ rename(id: string, name: string, signal?: AbortSignal): Promise<UploadResult>;
26
+ move(id: string, folderId: FolderId | null, signal?: AbortSignal): Promise<void>;
27
+ createFolder(parentId: FolderId | null, name: string, signal?: AbortSignal): Promise<AssetFolder>;
28
+ renameFolder(id: FolderId, name: string, signal?: AbortSignal): Promise<AssetFolder>;
29
+ removeFolder(id: FolderId, opts?: {
30
+ readonly cascade?: boolean;
31
+ }, signal?: AbortSignal): Promise<void>;
32
+ moveFolder(id: FolderId, parentId: FolderId | null, signal?: AbortSignal): Promise<AssetFolder>;
33
+ /** Fires on any asset OR folder mutation (the sidebar re-lists). */
34
+ subscribe(listener: () => void): () => void;
35
+ subscribeStatus(listener: (status: AssetSourceStatus) => void): () => void;
36
+ /** The shared folder store (for the composite source / UI). */
37
+ readonly folders: FolderStore;
38
+ }
39
+ export interface CreateInMemoryDataSourceOptions {
40
+ readonly registry: AssetRegistry;
41
+ readonly upload: UploadFn;
42
+ /** Shared folder store — injected by the factory so the UI sees the same one. */
43
+ readonly folderStore?: FolderStore;
44
+ /** Max nesting depth from `FolderOptions`. */
45
+ readonly maxDepth?: number;
46
+ }
47
+ export declare function createInMemoryDataSource(options: CreateInMemoryDataSourceOptions): ResolvedAssetDataSource;
48
+ export interface ResolveDataSourceInput extends CreateInMemoryDataSourceOptions {
49
+ /** Host-supplied backend. When absent, the full in-memory default is used. */
50
+ readonly hostDataSource?: AssetDataSource;
51
+ /** One-time dev warning sink (e.g. `ctx.log`). */
52
+ readonly warn?: (message: string) => void;
53
+ }
54
+ /**
55
+ * Per-PLANE resolution ladder (PRD 0002 §5). A host that supplies the FULL
56
+ * method set of a plane owns that plane; a PARTIAL set warns once and the WHOLE
57
+ * plane falls back to the in-memory default — so the read and write planes are
58
+ * never split across two stores. `subscribeStatus` is taken from the host when
59
+ * present; `subscribe`/`folders` always come from the in-memory layer (the
60
+ * composite re-lists after host mutations; external push is out of scope).
61
+ */
62
+ export declare function resolveDataSource(input: ResolveDataSourceInput): ResolvedAssetDataSource;
63
+ //# sourceMappingURL=data-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-source.d.ts","sourceRoot":"","sources":["../../src/utils/data-source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,136 @@
1
+ import { resolveFolderId } from "../types/folders.js";
2
+ import { AssetSourceError } from "./errors.js";
3
+ import { createFolderStore } from "./folders.js";
4
+ import { assetMatchesSearch, paginateMatches } from "./registry.js";
5
+ function makeAbortError() {
6
+ if ("u" > typeof DOMException) return new DOMException("Operation aborted", "AbortError");
7
+ const error = new Error("Operation aborted");
8
+ error.name = "AbortError";
9
+ return error;
10
+ }
11
+ function createInMemoryDataSource(options) {
12
+ const { registry, upload, maxDepth } = options;
13
+ const folders = options.folderStore ?? createFolderStore();
14
+ const buildPage = (page, query)=>{
15
+ const base = {
16
+ items: page.items,
17
+ total: page.total,
18
+ nextCursor: page.nextCursor
19
+ };
20
+ if (void 0 === query.folderId) return base;
21
+ return {
22
+ ...base,
23
+ folders: folders.listChildren(query.folderId),
24
+ folderPath: folders.path(query.folderId)
25
+ };
26
+ };
27
+ return {
28
+ folders,
29
+ list (query) {
30
+ if (void 0 === query.folderId) return Promise.resolve(buildPage(registry.search(query), query));
31
+ const target = resolveFolderId(query.folderId);
32
+ const recursive = true === query.recursive;
33
+ const subtree = recursive && null !== target ? folders.subtreeIds(target) : void 0;
34
+ const matches = registry.list().filter((entry)=>{
35
+ const owner = folders.folderOf(entry.id);
36
+ const folderOk = recursive ? null === target ? true : null !== owner && subtree?.has(owner) === true : owner === target;
37
+ return folderOk && assetMatchesSearch(entry, query);
38
+ });
39
+ return Promise.resolve(buildPage(paginateMatches(matches, query), query));
40
+ },
41
+ remove (id) {
42
+ registry.delete(id);
43
+ folders.removeAsset(id);
44
+ return Promise.resolve();
45
+ },
46
+ async replace (id, payload, signal) {
47
+ const result = await upload(payload, signal ? {
48
+ signal
49
+ } : void 0);
50
+ if (signal?.aborted) throw makeAbortError();
51
+ const replaced = registry.replace(id, result);
52
+ return replaced ?? result;
53
+ },
54
+ rename (id, name) {
55
+ const updated = registry.rename(id, name);
56
+ if (void 0 === updated) return Promise.reject(new AssetSourceError("ASSET_MUTATION_REJECTED", `Cannot rename unknown asset "${id}".`));
57
+ return Promise.resolve(updated);
58
+ },
59
+ move (id, folderId) {
60
+ folders.moveAsset(id, folderId);
61
+ return Promise.resolve();
62
+ },
63
+ createFolder (parentId, name) {
64
+ return Promise.resolve(folders.createFolder(parentId, name, maxDepth));
65
+ },
66
+ renameFolder (id, name) {
67
+ return Promise.resolve(folders.renameFolder(id, name));
68
+ },
69
+ removeFolder (id, opts) {
70
+ const { removedAssetIds } = folders.removeFolder(id, opts);
71
+ for (const assetId of removedAssetIds)registry.delete(assetId);
72
+ return Promise.resolve();
73
+ },
74
+ moveFolder (id, parentId) {
75
+ return Promise.resolve(folders.moveFolder(id, parentId, maxDepth));
76
+ },
77
+ subscribe (listener) {
78
+ const offRegistry = registry.subscribe(listener);
79
+ const offFolders = folders.subscribe(listener);
80
+ return ()=>{
81
+ offRegistry();
82
+ offFolders();
83
+ };
84
+ },
85
+ subscribeStatus (listener) {
86
+ listener({
87
+ phase: "idle"
88
+ });
89
+ return ()=>{};
90
+ }
91
+ };
92
+ }
93
+ const ASSET_PLANE = [
94
+ "list",
95
+ "remove",
96
+ "replace",
97
+ "rename",
98
+ "move"
99
+ ];
100
+ const FOLDER_PLANE = [
101
+ "createFolder",
102
+ "renameFolder",
103
+ "removeFolder",
104
+ "moveFolder"
105
+ ];
106
+ function resolveDataSource(input) {
107
+ const fallback = createInMemoryDataSource(input);
108
+ const host = input.hostDataSource;
109
+ if (void 0 === host) return fallback;
110
+ const ownsPlane = (plane, label)=>{
111
+ const provided = plane.filter((m)=>"function" == typeof host[m]);
112
+ if (0 === provided.length) return false;
113
+ if (provided.length === plane.length) return true;
114
+ input.warn?.(`asset-manager: dataSource provides a partial ${label} method set (${provided.join(", ")}) — falling back to the in-memory default for the whole ${label} plane. Provide all of {${plane.join(", ")}} or none.`);
115
+ return false;
116
+ };
117
+ const resolved = {
118
+ ...fallback
119
+ };
120
+ if (ownsPlane(ASSET_PLANE, "asset")) {
121
+ resolved.list = host.list.bind(host);
122
+ resolved.remove = host.remove.bind(host);
123
+ resolved.replace = host.replace.bind(host);
124
+ resolved.rename = host.rename.bind(host);
125
+ resolved.move = host.move.bind(host);
126
+ }
127
+ if (ownsPlane(FOLDER_PLANE, "folder")) {
128
+ resolved.createFolder = host.createFolder.bind(host);
129
+ resolved.renameFolder = host.renameFolder.bind(host);
130
+ resolved.removeFolder = host.removeFolder.bind(host);
131
+ resolved.moveFolder = host.moveFolder.bind(host);
132
+ }
133
+ if ("function" == typeof host.subscribeStatus) resolved.subscribeStatus = host.subscribeStatus.bind(host);
134
+ return resolved;
135
+ }
136
+ export { createInMemoryDataSource, resolveDataSource };
@@ -1,11 +1,15 @@
1
1
  "use strict";
2
2
  var __webpack_require__ = {};
3
3
  (()=>{
4
- __webpack_require__.d = (exports1, definition)=>{
5
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
- enumerable: true,
7
- get: definition[key]
8
- });
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");
9
13
  };
10
14
  })();
11
15
  (()=>{
@@ -23,10 +27,6 @@ var __webpack_require__ = {};
23
27
  })();
24
28
  var __webpack_exports__ = {};
25
29
  __webpack_require__.r(__webpack_exports__);
26
- __webpack_require__.d(__webpack_exports__, {
27
- AssetResolutionError: ()=>AssetResolutionError,
28
- AssetValidationError: ()=>AssetValidationError
29
- });
30
30
  class AssetValidationError extends Error {
31
31
  code;
32
32
  constructor(code, message, options){
@@ -36,6 +36,21 @@ class AssetValidationError extends Error {
36
36
  if (options && "cause" in options) this.cause = options.cause;
37
37
  }
38
38
  }
39
+ class AssetSourceError extends Error {
40
+ code;
41
+ retryable;
42
+ status;
43
+ retryAfterMs;
44
+ constructor(code, message, options){
45
+ super(message);
46
+ this.name = "AssetSourceError";
47
+ this.code = code;
48
+ this.retryable = options?.retryable ?? false;
49
+ this.status = options?.status;
50
+ this.retryAfterMs = options?.retryAfterMs;
51
+ if (options && "cause" in options) this.cause = options.cause;
52
+ }
53
+ }
39
54
  class AssetResolutionError extends Error {
40
55
  assetId;
41
56
  code;
@@ -47,10 +62,17 @@ class AssetResolutionError extends Error {
47
62
  if (options && "cause" in options) this.cause = options.cause;
48
63
  }
49
64
  }
65
+ __webpack_require__.d(__webpack_exports__, {
66
+ AssetResolutionError: ()=>AssetResolutionError,
67
+ AssetSourceError: ()=>AssetSourceError,
68
+ AssetValidationError: ()=>AssetValidationError
69
+ });
50
70
  exports.AssetResolutionError = __webpack_exports__.AssetResolutionError;
71
+ exports.AssetSourceError = __webpack_exports__.AssetSourceError;
51
72
  exports.AssetValidationError = __webpack_exports__.AssetValidationError;
52
73
  for(var __rspack_i in __webpack_exports__)if (-1 === [
53
74
  "AssetResolutionError",
75
+ "AssetSourceError",
54
76
  "AssetValidationError"
55
77
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
56
78
  Object.defineProperty(exports, '__esModule', {
@@ -4,6 +4,33 @@ export declare class AssetValidationError extends Error {
4
4
  readonly cause?: unknown;
5
5
  });
6
6
  }
7
+ /**
8
+ * Failure codes raised by the async data-source / folder / external-provider
9
+ * surfaces (PRD 0002 §3.6). Distinct from {@link AssetValidationError}
10
+ * (upload validation) and {@link AssetResolutionError} (resolver domain) — in
11
+ * particular `ASSET_NOT_FOUND` belongs to the resolver, never here.
12
+ */
13
+ export type AssetSourceErrorCode = "DATA_SOURCE_UNAVAILABLE" | "DATA_SOURCE_TIMEOUT" | "ASSET_MUTATION_REJECTED" | "FOLDER_NOT_FOUND" | "FOLDER_CYCLE" | "FOLDER_NAME_CONFLICT" | "FOLDER_NOT_EMPTY" | "MOVE_REJECTED" | "PROVIDER_RATE_LIMITED" | "PROVIDER_UNAUTHORIZED" | "PROVIDER_NETWORK" | "PROVIDER_BAD_RESPONSE" | "READ_ONLY_SOURCE" | "OPTIMISTIC_ROLLBACK";
14
+ /**
15
+ * Error for async catalog operations: host `dataSource` failures, folder
16
+ * mutations, and external `AssetSourceProvider` calls (e.g. Unsplash). Carries
17
+ * retry metadata so callers can drive backoff (`./retry`) without re-deriving
18
+ * it: `retryable` gates whether a retry is attempted at all, `status` mirrors
19
+ * an HTTP status (429, 401, …), and `retryAfterMs` is sourced from a
20
+ * `Retry-After` / `X-Ratelimit-Reset` header when present.
21
+ */
22
+ export declare class AssetSourceError extends Error {
23
+ readonly code: AssetSourceErrorCode;
24
+ readonly retryable: boolean;
25
+ readonly status?: number;
26
+ readonly retryAfterMs?: number;
27
+ constructor(code: AssetSourceErrorCode, message: string, options?: {
28
+ readonly cause?: unknown;
29
+ readonly retryable?: boolean;
30
+ readonly status?: number;
31
+ readonly retryAfterMs?: number;
32
+ });
33
+ }
7
34
  export type AssetResolutionErrorCode = "ASSET_NOT_FOUND" | "ASSET_URL_REJECTED" | "ASSET_VALIDATION_FAILED";
8
35
  export declare class AssetResolutionError extends Error {
9
36
  readonly assetId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.cts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,oBAAqB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAGrB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAUvC;AAED,MAAM,MAAM,wBAAwB,GACjC,iBAAiB,GACjB,oBAAoB,GACpB,yBAAyB,CAAC;AAE7B,qBAAa,oBAAqB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;gBAGvC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,wBAA4C,EAClD,OAAO,SAAyC,EAChD,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAWvC"}
1
+ {"version":3,"file":"errors.d.cts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,oBAAqB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAGrB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAUvC;AAED;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAC7B,yBAAyB,GACzB,qBAAqB,GACrB,yBAAyB,GACzB,kBAAkB,GAClB,cAAc,GACd,sBAAsB,GACtB,kBAAkB,GAClB,eAAe,GACf,uBAAuB,GACvB,uBAAuB,GACvB,kBAAkB,GAClB,uBAAuB,GACvB,kBAAkB,GAClB,qBAAqB,CAAC;AAEzB;;;;;;;GAOG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;gBAG9B,IAAI,EAAE,oBAAoB,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACT,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;QAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;KAC/B;CAaF;AAED,MAAM,MAAM,wBAAwB,GACjC,iBAAiB,GACjB,oBAAoB,GACpB,yBAAyB,CAAC;AAE7B,qBAAa,oBAAqB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;gBAGvC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,wBAA4C,EAClD,OAAO,SAAyC,EAChD,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAWvC"}
@@ -4,6 +4,33 @@ export declare class AssetValidationError extends Error {
4
4
  readonly cause?: unknown;
5
5
  });
6
6
  }
7
+ /**
8
+ * Failure codes raised by the async data-source / folder / external-provider
9
+ * surfaces (PRD 0002 §3.6). Distinct from {@link AssetValidationError}
10
+ * (upload validation) and {@link AssetResolutionError} (resolver domain) — in
11
+ * particular `ASSET_NOT_FOUND` belongs to the resolver, never here.
12
+ */
13
+ export type AssetSourceErrorCode = "DATA_SOURCE_UNAVAILABLE" | "DATA_SOURCE_TIMEOUT" | "ASSET_MUTATION_REJECTED" | "FOLDER_NOT_FOUND" | "FOLDER_CYCLE" | "FOLDER_NAME_CONFLICT" | "FOLDER_NOT_EMPTY" | "MOVE_REJECTED" | "PROVIDER_RATE_LIMITED" | "PROVIDER_UNAUTHORIZED" | "PROVIDER_NETWORK" | "PROVIDER_BAD_RESPONSE" | "READ_ONLY_SOURCE" | "OPTIMISTIC_ROLLBACK";
14
+ /**
15
+ * Error for async catalog operations: host `dataSource` failures, folder
16
+ * mutations, and external `AssetSourceProvider` calls (e.g. Unsplash). Carries
17
+ * retry metadata so callers can drive backoff (`./retry`) without re-deriving
18
+ * it: `retryable` gates whether a retry is attempted at all, `status` mirrors
19
+ * an HTTP status (429, 401, …), and `retryAfterMs` is sourced from a
20
+ * `Retry-After` / `X-Ratelimit-Reset` header when present.
21
+ */
22
+ export declare class AssetSourceError extends Error {
23
+ readonly code: AssetSourceErrorCode;
24
+ readonly retryable: boolean;
25
+ readonly status?: number;
26
+ readonly retryAfterMs?: number;
27
+ constructor(code: AssetSourceErrorCode, message: string, options?: {
28
+ readonly cause?: unknown;
29
+ readonly retryable?: boolean;
30
+ readonly status?: number;
31
+ readonly retryAfterMs?: number;
32
+ });
33
+ }
7
34
  export type AssetResolutionErrorCode = "ASSET_NOT_FOUND" | "ASSET_URL_REJECTED" | "ASSET_VALIDATION_FAILED";
8
35
  export declare class AssetResolutionError extends Error {
9
36
  readonly assetId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,oBAAqB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAGrB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAUvC;AAED,MAAM,MAAM,wBAAwB,GACjC,iBAAiB,GACjB,oBAAoB,GACpB,yBAAyB,CAAC;AAE7B,qBAAa,oBAAqB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;gBAGvC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,wBAA4C,EAClD,OAAO,SAAyC,EAChD,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAWvC"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,oBAAqB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAGrB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAUvC;AAED;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAC7B,yBAAyB,GACzB,qBAAqB,GACrB,yBAAyB,GACzB,kBAAkB,GAClB,cAAc,GACd,sBAAsB,GACtB,kBAAkB,GAClB,eAAe,GACf,uBAAuB,GACvB,uBAAuB,GACvB,kBAAkB,GAClB,uBAAuB,GACvB,kBAAkB,GAClB,qBAAqB,CAAC;AAEzB;;;;;;;GAOG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;gBAG9B,IAAI,EAAE,oBAAoB,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACT,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;QAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;KAC/B;CAaF;AAED,MAAM,MAAM,wBAAwB,GACjC,iBAAiB,GACjB,oBAAoB,GACpB,yBAAyB,CAAC;AAE7B,qBAAa,oBAAqB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;gBAGvC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,wBAA4C,EAClD,OAAO,SAAyC,EAChD,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAWvC"}
@@ -7,6 +7,21 @@ class AssetValidationError extends Error {
7
7
  if (options && "cause" in options) this.cause = options.cause;
8
8
  }
9
9
  }
10
+ class AssetSourceError extends Error {
11
+ code;
12
+ retryable;
13
+ status;
14
+ retryAfterMs;
15
+ constructor(code, message, options){
16
+ super(message);
17
+ this.name = "AssetSourceError";
18
+ this.code = code;
19
+ this.retryable = options?.retryable ?? false;
20
+ this.status = options?.status;
21
+ this.retryAfterMs = options?.retryAfterMs;
22
+ if (options && "cause" in options) this.cause = options.cause;
23
+ }
24
+ }
10
25
  class AssetResolutionError extends Error {
11
26
  assetId;
12
27
  code;
@@ -18,4 +33,4 @@ class AssetResolutionError extends Error {
18
33
  if (options && "cause" in options) this.cause = options.cause;
19
34
  }
20
35
  }
21
- export { AssetResolutionError, AssetValidationError };
36
+ export { AssetResolutionError, AssetSourceError, AssetValidationError };