@endora-commerce/mod-assets-library 0.0.0-stage → 0.100.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +61 -2
- package/dist/admin/api/assets-library-client.d.ts +29 -0
- package/dist/admin/api/assets-library-client.d.ts.map +1 -0
- package/dist/admin/api/assets-library-client.js +70 -0
- package/dist/admin/api/assets-library-client.js.map +1 -0
- package/dist/admin/components/AssetDetailDrawer.d.ts +8 -0
- package/dist/admin/components/AssetDetailDrawer.d.ts.map +1 -0
- package/dist/admin/components/AssetDetailDrawer.js +96 -0
- package/dist/admin/components/AssetDetailDrawer.js.map +1 -0
- package/dist/admin/components/FolderTree.d.ts +13 -0
- package/dist/admin/components/FolderTree.d.ts.map +1 -0
- package/dist/admin/components/FolderTree.js +71 -0
- package/dist/admin/components/FolderTree.js.map +1 -0
- package/dist/admin/index.d.ts +44 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +46 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/pages/LibraryPage.d.ts +9 -0
- package/dist/admin/pages/LibraryPage.d.ts.map +1 -0
- package/dist/admin/pages/LibraryPage.js +163 -0
- package/dist/admin/pages/LibraryPage.js.map +1 -0
- package/dist/backend/entities/asset-folder.entity.d.ts +16 -0
- package/dist/backend/entities/asset-folder.entity.d.ts.map +1 -0
- package/dist/backend/entities/asset-folder.entity.js +57 -0
- package/dist/backend/entities/asset-folder.entity.js.map +1 -0
- package/dist/backend/entities/asset.entity.d.ts +38 -0
- package/dist/backend/entities/asset.entity.d.ts.map +1 -0
- package/dist/backend/entities/asset.entity.js +128 -0
- package/dist/backend/entities/asset.entity.js.map +1 -0
- package/dist/backend/index.d.ts +57 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +150 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/jobs/hard-delete-asset.job.d.ts +18 -0
- package/dist/backend/jobs/hard-delete-asset.job.d.ts.map +1 -0
- package/dist/backend/jobs/hard-delete-asset.job.js +91 -0
- package/dist/backend/jobs/hard-delete-asset.job.js.map +1 -0
- package/dist/backend/plugin.d.ts +47 -0
- package/dist/backend/plugin.d.ts.map +1 -0
- package/dist/backend/plugin.js +96 -0
- package/dist/backend/plugin.js.map +1 -0
- package/dist/backend/routes.admin.d.ts +15 -0
- package/dist/backend/routes.admin.d.ts.map +1 -0
- package/dist/backend/routes.admin.js +189 -0
- package/dist/backend/routes.admin.js.map +1 -0
- package/dist/backend/routes.public.d.ts +14 -0
- package/dist/backend/routes.public.d.ts.map +1 -0
- package/dist/backend/routes.public.js +99 -0
- package/dist/backend/routes.public.js.map +1 -0
- package/dist/backend/services/asset-read-port.d.ts +103 -0
- package/dist/backend/services/asset-read-port.d.ts.map +1 -0
- package/dist/backend/services/asset-read-port.js +167 -0
- package/dist/backend/services/asset-read-port.js.map +1 -0
- package/dist/backend/services/assets-library.service.d.ts +76 -0
- package/dist/backend/services/assets-library.service.d.ts.map +1 -0
- package/dist/backend/services/assets-library.service.js +261 -0
- package/dist/backend/services/assets-library.service.js.map +1 -0
- package/dist/backend/services/cms-body-resolver.d.ts +6 -0
- package/dist/backend/services/cms-body-resolver.d.ts.map +1 -0
- package/dist/backend/services/cms-body-resolver.js +44 -0
- package/dist/backend/services/cms-body-resolver.js.map +1 -0
- package/dist/backend/services/folders.service.d.ts +29 -0
- package/dist/backend/services/folders.service.d.ts.map +1 -0
- package/dist/backend/services/folders.service.js +231 -0
- package/dist/backend/services/folders.service.js.map +1 -0
- package/dist/backend/services/hmac.d.ts +28 -0
- package/dist/backend/services/hmac.d.ts.map +1 -0
- package/dist/backend/services/hmac.js +50 -0
- package/dist/backend/services/hmac.js.map +1 -0
- package/dist/backend/services/reference-registry.d.ts +36 -0
- package/dist/backend/services/reference-registry.d.ts.map +1 -0
- package/dist/backend/services/reference-registry.js +63 -0
- package/dist/backend/services/reference-registry.js.map +1 -0
- package/dist/backend/services/storage/adapter-registry.d.ts +77 -0
- package/dist/backend/services/storage/adapter-registry.d.ts.map +1 -0
- package/dist/backend/services/storage/adapter-registry.js +95 -0
- package/dist/backend/services/storage/adapter-registry.js.map +1 -0
- package/dist/backend/services/storage/errors.d.ts +18 -0
- package/dist/backend/services/storage/errors.d.ts.map +1 -0
- package/dist/backend/services/storage/errors.js +30 -0
- package/dist/backend/services/storage/errors.js.map +1 -0
- package/dist/backend/services/storage/gcs-adapter.d.ts +42 -0
- package/dist/backend/services/storage/gcs-adapter.d.ts.map +1 -0
- package/dist/backend/services/storage/gcs-adapter.js +106 -0
- package/dist/backend/services/storage/gcs-adapter.js.map +1 -0
- package/dist/backend/services/storage/legacy-resolver.d.ts +15 -0
- package/dist/backend/services/storage/legacy-resolver.d.ts.map +1 -0
- package/dist/backend/services/storage/legacy-resolver.js +32 -0
- package/dist/backend/services/storage/legacy-resolver.js.map +1 -0
- package/dist/backend/services/storage/local-fs-adapter.d.ts +59 -0
- package/dist/backend/services/storage/local-fs-adapter.d.ts.map +1 -0
- package/dist/backend/services/storage/local-fs-adapter.js +153 -0
- package/dist/backend/services/storage/local-fs-adapter.js.map +1 -0
- package/dist/backend/services/storage/locator.d.ts +5 -0
- package/dist/backend/services/storage/locator.d.ts.map +1 -0
- package/dist/backend/services/storage/locator.js +16 -0
- package/dist/backend/services/storage/locator.js.map +1 -0
- package/dist/backend/services/storage/object-storage-port.d.ts +46 -0
- package/dist/backend/services/storage/object-storage-port.d.ts.map +1 -0
- package/dist/backend/services/storage/object-storage-port.js +78 -0
- package/dist/backend/services/storage/object-storage-port.js.map +1 -0
- package/dist/backend/services/storage/public-url-base.d.ts +50 -0
- package/dist/backend/services/storage/public-url-base.d.ts.map +1 -0
- package/dist/backend/services/storage/public-url-base.js +70 -0
- package/dist/backend/services/storage/public-url-base.js.map +1 -0
- package/dist/backend/services/storage/s3-adapter.d.ts +50 -0
- package/dist/backend/services/storage/s3-adapter.d.ts.map +1 -0
- package/dist/backend/services/storage/s3-adapter.js +110 -0
- package/dist/backend/services/storage/s3-adapter.js.map +1 -0
- package/dist/backend/services/storage/settings-view.d.ts +4 -0
- package/dist/backend/services/storage/settings-view.d.ts.map +1 -0
- package/dist/backend/services/storage/settings-view.js +73 -0
- package/dist/backend/services/storage/settings-view.js.map +1 -0
- package/dist/backend/services/storage/storage-adapter.d.ts +62 -0
- package/dist/backend/services/storage/storage-adapter.d.ts.map +1 -0
- package/dist/backend/services/storage/storage-adapter.js +10 -0
- package/dist/backend/services/storage/storage-adapter.js.map +1 -0
- package/dist/backend/services/upload-pipeline.d.ts +41 -0
- package/dist/backend/services/upload-pipeline.d.ts.map +1 -0
- package/dist/backend/services/upload-pipeline.js +231 -0
- package/dist/backend/services/upload-pipeline.js.map +1 -0
- package/dist/manifest.d.ts +185 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +229 -0
- package/dist/manifest.js.map +1 -0
- package/dist/migrations/20260505T102206_assets_library_init.d.ts +35 -0
- package/dist/migrations/20260505T102206_assets_library_init.d.ts.map +1 -0
- package/dist/migrations/20260505T102206_assets_library_init.js +132 -0
- package/dist/migrations/20260505T102206_assets_library_init.js.map +1 -0
- package/dist/migrations/index.d.ts +27 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +29 -0
- package/dist/migrations/index.js.map +1 -0
- package/docs/assets-library/index.md +125 -0
- package/i18n/en.json +54 -0
- package/i18n/pl.json +54 -0
- package/package.json +99 -3
- package/tailwind.css +14 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Library page — feature 013 / US2 / T069.
|
|
3
|
+
// Three-pane Magento-2-Media-Gallery–style layout: folder tree + asset grid
|
|
4
|
+
// + per-asset detail drawer. Inline upload affordance per current folder.
|
|
5
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
6
|
+
import { Alert, AlertDescription, Button, Card, CardContent, CardHeader, CardTitle, Input, PageHeader } from '@endora-commerce/admin-kit/ui';
|
|
7
|
+
import { useTranslation } from '@endora-commerce/admin-kit/i18n';
|
|
8
|
+
import { AssetUploader } from '@endora-commerce/admin-kit/components';
|
|
9
|
+
import { toAbsoluteAssetUrl } from '@endora-commerce/admin-kit/lib';
|
|
10
|
+
import { FolderTree } from '../components/FolderTree.js';
|
|
11
|
+
import { AssetDetailDrawer } from '../components/AssetDetailDrawer.js';
|
|
12
|
+
import { assetsLibraryClient, } from '../api/assets-library-client.js';
|
|
13
|
+
export function LibraryPage() {
|
|
14
|
+
const t = useTranslation('assets_library');
|
|
15
|
+
const [folders, setFolders] = useState([]);
|
|
16
|
+
const [folderId, setFolderId] = useState(null); // null = Unsorted (root)
|
|
17
|
+
const [items, setItems] = useState([]);
|
|
18
|
+
const [q, setQ] = useState('');
|
|
19
|
+
const [debouncedQ, setDebouncedQ] = useState('');
|
|
20
|
+
const [cursor, setCursor] = useState(null);
|
|
21
|
+
const [hasMore, setHasMore] = useState(false);
|
|
22
|
+
const [error, setError] = useState(null);
|
|
23
|
+
const [info, setInfo] = useState(null);
|
|
24
|
+
const [loading, setLoading] = useState(true);
|
|
25
|
+
const [loadingMore, setLoadingMore] = useState(false);
|
|
26
|
+
const [selected, setSelected] = useState(null);
|
|
27
|
+
const PAGE_SIZE = 60;
|
|
28
|
+
const loadFolders = useCallback(async () => {
|
|
29
|
+
try {
|
|
30
|
+
setFolders(await assetsLibraryClient.listFolders());
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
34
|
+
}
|
|
35
|
+
}, []);
|
|
36
|
+
// Debounce the search box so each keystroke does not fire a request; the
|
|
37
|
+
// actual filtering is done server-side (see loadFirstPage), so the search
|
|
38
|
+
// covers every asset in the folder, not only the ones already loaded.
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
const h = setTimeout(() => setDebouncedQ(q), 300);
|
|
41
|
+
return () => clearTimeout(h);
|
|
42
|
+
}, [q]);
|
|
43
|
+
// First page — replaces the list. Runs on folder change or a new search.
|
|
44
|
+
const loadFirstPage = useCallback(async () => {
|
|
45
|
+
setLoading(true);
|
|
46
|
+
setError(null);
|
|
47
|
+
try {
|
|
48
|
+
const out = await assetsLibraryClient.listAssets({
|
|
49
|
+
folderId,
|
|
50
|
+
...(debouncedQ ? { q: debouncedQ } : {}),
|
|
51
|
+
limit: PAGE_SIZE,
|
|
52
|
+
});
|
|
53
|
+
setItems(out.data);
|
|
54
|
+
setCursor(out.nextCursor);
|
|
55
|
+
setHasMore(out.nextCursor !== null);
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
setLoading(false);
|
|
62
|
+
}
|
|
63
|
+
}, [folderId, debouncedQ]);
|
|
64
|
+
// Next page — appends, keyed off the server cursor.
|
|
65
|
+
const loadMore = useCallback(async () => {
|
|
66
|
+
if (!cursor || loadingMore)
|
|
67
|
+
return;
|
|
68
|
+
setLoadingMore(true);
|
|
69
|
+
setError(null);
|
|
70
|
+
try {
|
|
71
|
+
const out = await assetsLibraryClient.listAssets({
|
|
72
|
+
folderId,
|
|
73
|
+
...(debouncedQ ? { q: debouncedQ } : {}),
|
|
74
|
+
cursor,
|
|
75
|
+
limit: PAGE_SIZE,
|
|
76
|
+
});
|
|
77
|
+
setItems((prev) => [...prev, ...out.data]);
|
|
78
|
+
setCursor(out.nextCursor);
|
|
79
|
+
setHasMore(out.nextCursor !== null);
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
setLoadingMore(false);
|
|
86
|
+
}
|
|
87
|
+
}, [folderId, debouncedQ, cursor, loadingMore]);
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
void loadFolders();
|
|
90
|
+
}, [loadFolders]);
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
void loadFirstPage();
|
|
93
|
+
}, [loadFirstPage]);
|
|
94
|
+
// Infinite scroll — auto-load the next page when the sentinel scrolls into
|
|
95
|
+
// view. The "Load more" button remains as an explicit fallback.
|
|
96
|
+
const sentinelRef = useRef(null);
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
const node = sentinelRef.current;
|
|
99
|
+
if (!node || !hasMore)
|
|
100
|
+
return undefined;
|
|
101
|
+
const observer = new IntersectionObserver((entries) => {
|
|
102
|
+
if (entries[0]?.isIntersecting)
|
|
103
|
+
void loadMore();
|
|
104
|
+
});
|
|
105
|
+
observer.observe(node);
|
|
106
|
+
return () => observer.disconnect();
|
|
107
|
+
}, [hasMore, loadMore]);
|
|
108
|
+
// Backwards-compatible alias — child callbacks call loadItems() to refresh.
|
|
109
|
+
const loadItems = loadFirstPage;
|
|
110
|
+
const onCreateFolder = async (parentId, name) => {
|
|
111
|
+
try {
|
|
112
|
+
await assetsLibraryClient.createFolder({ parentId, name });
|
|
113
|
+
await loadFolders();
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const onRenameFolder = async (id, name) => {
|
|
120
|
+
try {
|
|
121
|
+
await assetsLibraryClient.patchFolder(id, { name });
|
|
122
|
+
await loadFolders();
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
const onDeleteFolder = async (id) => {
|
|
129
|
+
try {
|
|
130
|
+
const choice = window.confirm(t('folders.deleteConfirm'));
|
|
131
|
+
if (!choice)
|
|
132
|
+
return;
|
|
133
|
+
const out = await assetsLibraryClient.deleteFolder(id, {
|
|
134
|
+
ifNonEmpty: 'moveContentsToParent',
|
|
135
|
+
});
|
|
136
|
+
setInfo(t('folders.removed', { id: out.deletedFolderId }));
|
|
137
|
+
if (folderId === id)
|
|
138
|
+
setFolderId(null);
|
|
139
|
+
await loadFolders();
|
|
140
|
+
await loadItems();
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsx(PageHeader, { title: t('page.title'), description: t('page.description') }), error ? (_jsx(Alert, { variant: "destructive", children: _jsx(AlertDescription, { children: error }) })) : null, info ? (_jsx(Alert, { children: _jsx(AlertDescription, { children: info }) })) : null, _jsxs("div", { className: "grid grid-cols-12 gap-4", children: [_jsxs(Card, { className: "col-span-3", children: [_jsx(CardHeader, { children: _jsx(CardTitle, { className: "text-base", children: t('folders.title') }) }), _jsx(CardContent, { children: _jsx(FolderTree, { folders: folders, selectedId: folderId, onSelect: setFolderId, onCreate: onCreateFolder, onRename: onRenameFolder, onDelete: onDeleteFolder }) })] }), _jsxs(Card, { className: selected ? 'col-span-6' : 'col-span-9', children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [_jsx(CardTitle, { className: "text-base", children: t('assets.title') }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { value: q, onChange: (e) => setQ(e.target.value), onKeyDown: (e) => {
|
|
147
|
+
if (e.key === 'Enter')
|
|
148
|
+
setDebouncedQ(q);
|
|
149
|
+
}, placeholder: t('assets.searchPlaceholder'), className: "w-64" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setDebouncedQ(q), children: t('common.search') })] })] }), _jsxs(CardContent, { className: "space-y-4", children: [_jsx(AssetUploader, { defaults: { folderId }, triggerLabel: t('uploader.triggerCurrentFolder'), onUploaded: () => {
|
|
150
|
+
void loadItems();
|
|
151
|
+
} }), loading ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('common.loading') })) : items.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('assets.emptyFolder') })) : (_jsx("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5", children: items.map((a) => (_jsxs("button", { type: "button", className: `group overflow-hidden rounded-md border bg-muted/30 p-2 text-left transition hover:border-primary ${selected === a.id ? 'border-primary ring-2 ring-primary/30' : ''}`, onClick: () => setSelected(a.id), children: [a.mimeType.startsWith('image/') ? (
|
|
152
|
+
// eslint-disable-next-line jsx-a11y/alt-text
|
|
153
|
+
_jsx("img", { src: toAbsoluteAssetUrl(a.url), loading: "lazy", className: "aspect-square w-full rounded object-cover" })) : (_jsx("div", { className: "flex aspect-square w-full items-center justify-center rounded bg-muted text-xs text-muted-foreground", children: a.mimeType })), _jsx("div", { className: "mt-1 truncate text-xs", children: a.label ?? a.filename }), _jsxs("div", { className: "truncate text-[10px] text-muted-foreground", children: [a.visibility, " \u00B7 ", Number(a.sizeBytes), "B"] })] }, a.id))) })), !loading && hasMore ? (_jsx("div", { ref: sentinelRef, className: "flex justify-center pt-2", children: _jsx(Button, { type: "button", variant: "outline", size: "sm", disabled: loadingMore, onClick: () => void loadMore(), children: loadingMore ? t('common.loading') : t('assets.loadMore') }) })) : null] })] }), selected ? (_jsx("div", { className: "col-span-3", children: _jsx(AssetDetailDrawer, { assetId: selected, onChanged: () => {
|
|
154
|
+
void loadItems();
|
|
155
|
+
}, onClose: () => setSelected(null) }) })) : null] })] }));
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* The registry loads a route component through a dynamic-import factory and
|
|
159
|
+
* reads its default export (feature 091, FR-013). The named export stays: it is
|
|
160
|
+
* the spelling this module's own code and its tests use.
|
|
161
|
+
*/
|
|
162
|
+
export default LibraryPage;
|
|
163
|
+
//# sourceMappingURL=LibraryPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LibraryPage.js","sourceRoot":"","sources":["../../../src/admin/pages/LibraryPage.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { OptionalProps } from '@mikro-orm/core';
|
|
2
|
+
/**
|
|
3
|
+
* AssetFolder — organisational tree node for the Assets Library page.
|
|
4
|
+
* Folders are pure metadata; moving an asset between folders is a metadata
|
|
5
|
+
* update only, never a physical file move (research R11, FR-008).
|
|
6
|
+
*/
|
|
7
|
+
export declare class AssetFolder {
|
|
8
|
+
[OptionalProps]?: 'id' | 'createdAt' | 'updatedAt' | 'parentId' | 'position';
|
|
9
|
+
id: string;
|
|
10
|
+
parentId?: string | null;
|
|
11
|
+
name: string;
|
|
12
|
+
position: number;
|
|
13
|
+
createdAt: Date;
|
|
14
|
+
updatedAt: Date;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=asset-folder.entity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-folder.entity.d.ts","sourceRoot":"","sources":["../../../src/backend/entities/asset-folder.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,aAAa,EAAwB,MAAM,iBAAiB,CAAC;AAIrF;;;;GAIG;AACH,qBAEa,WAAW;IACtB,CAAC,aAAa,CAAC,CAAC,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,UAAU,CAAC;IAG7E,EAAE,EAAE,MAAM,CAAgB;IAI1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGzB,IAAI,EAAG,MAAM,CAAC;IAGd,QAAQ,EAAE,MAAM,CAAK;IAGrB,SAAS,EAAE,IAAI,CAAc;IAG7B,SAAS,EAAE,IAAI,CAAc;CAC9B"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Entity, Index, OptionalProps, PrimaryKey, Property } from '@mikro-orm/core';
|
|
11
|
+
import { GlobalEntity } from '@endora-commerce/platform/tenancy';
|
|
12
|
+
import { randomUUID } from 'crypto';
|
|
13
|
+
/**
|
|
14
|
+
* AssetFolder — organisational tree node for the Assets Library page.
|
|
15
|
+
* Folders are pure metadata; moving an asset between folders is a metadata
|
|
16
|
+
* update only, never a physical file move (research R11, FR-008).
|
|
17
|
+
*/
|
|
18
|
+
let AssetFolder = class AssetFolder {
|
|
19
|
+
[OptionalProps];
|
|
20
|
+
id = randomUUID();
|
|
21
|
+
parentId;
|
|
22
|
+
name;
|
|
23
|
+
position = 0;
|
|
24
|
+
createdAt = new Date();
|
|
25
|
+
updatedAt = new Date();
|
|
26
|
+
};
|
|
27
|
+
__decorate([
|
|
28
|
+
PrimaryKey({ type: 'uuid' }),
|
|
29
|
+
__metadata("design:type", String)
|
|
30
|
+
], AssetFolder.prototype, "id", void 0);
|
|
31
|
+
__decorate([
|
|
32
|
+
Property({ type: 'uuid', nullable: true }),
|
|
33
|
+
Index(),
|
|
34
|
+
__metadata("design:type", Object)
|
|
35
|
+
], AssetFolder.prototype, "parentId", void 0);
|
|
36
|
+
__decorate([
|
|
37
|
+
Property({ type: 'string', length: 160 }),
|
|
38
|
+
__metadata("design:type", String)
|
|
39
|
+
], AssetFolder.prototype, "name", void 0);
|
|
40
|
+
__decorate([
|
|
41
|
+
Property({ type: 'integer' }),
|
|
42
|
+
__metadata("design:type", Number)
|
|
43
|
+
], AssetFolder.prototype, "position", void 0);
|
|
44
|
+
__decorate([
|
|
45
|
+
Property({ type: 'datetime', onCreate: () => new Date() }),
|
|
46
|
+
__metadata("design:type", Date)
|
|
47
|
+
], AssetFolder.prototype, "createdAt", void 0);
|
|
48
|
+
__decorate([
|
|
49
|
+
Property({ type: 'datetime', onUpdate: () => new Date() }),
|
|
50
|
+
__metadata("design:type", Date)
|
|
51
|
+
], AssetFolder.prototype, "updatedAt", void 0);
|
|
52
|
+
AssetFolder = __decorate([
|
|
53
|
+
GlobalEntity(),
|
|
54
|
+
Entity({ tableName: 'asset_folders' })
|
|
55
|
+
], AssetFolder);
|
|
56
|
+
export { AssetFolder };
|
|
57
|
+
//# sourceMappingURL=asset-folder.entity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-folder.entity.js","sourceRoot":"","sources":["../../../src/backend/entities/asset-folder.entity.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC;;;;GAIG;AAGI,IAAM,WAAW,GAAjB,MAAM,WAAW;IACtB,CAAC,aAAa,CAAC,CAA8D;IAG7E,EAAE,GAAW,UAAU,EAAE,CAAC;IAI1B,QAAQ,CAAiB;IAGzB,IAAI,CAAU;IAGd,QAAQ,GAAW,CAAC,CAAC;IAGrB,SAAS,GAAS,IAAI,IAAI,EAAE,CAAC;IAG7B,SAAS,GAAS,IAAI,IAAI,EAAE,CAAC;CAC9B,CAAA;AAjBC;IADC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;uCACH;AAI1B;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1C,KAAK,EAAE;;6CACiB;AAGzB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;;yCAC5B;AAGd;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;6CACT;AAGrB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;8BAChD,IAAI;8CAAc;AAG7B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;8BAChD,IAAI;8CAAc;AApBlB,WAAW;IAFvB,YAAY,EAAE;IACd,MAAM,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;GAC1B,WAAW,CAqBvB"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { OptionalProps } from '@mikro-orm/core';
|
|
2
|
+
/**
|
|
3
|
+
* Asset — file managed by the Assets Library (feature 013). Replaces the
|
|
4
|
+
* pre-013 `assets` module entity. Existing FK references from Catalog
|
|
5
|
+
* (gallery_items.asset_id, product_attachments.asset_id, products.download_asset_id)
|
|
6
|
+
* and the new categories.main_image_asset_id continue to point here.
|
|
7
|
+
*
|
|
8
|
+
* Visibility, storage backend, and folder are introduced in feature 013;
|
|
9
|
+
* `storageUrl` is retained for one release as a read-only legacy escape hatch
|
|
10
|
+
* and is no longer written by new code (research R11 / FR-034).
|
|
11
|
+
*/
|
|
12
|
+
export declare class Asset {
|
|
13
|
+
[OptionalProps]?: 'id' | 'createdAt' | 'updatedAt' | 'altText' | 'deletedAt' | 'folderId' | 'visibility' | 'label' | 'storageBackend' | 'storageLocator' | 'pendingCleanup' | 'purgeAfterAt' | 'mimeTypeOverridden';
|
|
14
|
+
id: string;
|
|
15
|
+
kind: 'image' | 'video' | 'pdf' | 'certificate' | 'other';
|
|
16
|
+
filename: string;
|
|
17
|
+
mimeType: string;
|
|
18
|
+
sizeBytes: string;
|
|
19
|
+
/**
|
|
20
|
+
* @deprecated Use `storageLocator` + `storageBackend` instead. Retained
|
|
21
|
+
* for one release for the legacy-decomp escape hatch (research R11);
|
|
22
|
+
* removed in a follow-up cleanup PR.
|
|
23
|
+
*/
|
|
24
|
+
storageUrl: string;
|
|
25
|
+
altText?: Record<string, string> | null;
|
|
26
|
+
folderId?: string | null;
|
|
27
|
+
visibility: 'public' | 'private';
|
|
28
|
+
label?: string | null;
|
|
29
|
+
storageBackend: 'local' | 's3' | 'gcs' | 'legacy';
|
|
30
|
+
storageLocator: string;
|
|
31
|
+
pendingCleanup: boolean;
|
|
32
|
+
purgeAfterAt?: Date | null;
|
|
33
|
+
mimeTypeOverridden: boolean;
|
|
34
|
+
createdAt: Date;
|
|
35
|
+
updatedAt: Date;
|
|
36
|
+
deletedAt?: Date | null;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=asset.entity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset.entity.d.ts","sourceRoot":"","sources":["../../../src/backend/entities/asset.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,aAAa,EAAwB,MAAM,iBAAiB,CAAC;AAIrF;;;;;;;;;GASG;AACH,qBAEa,KAAK;IAChB,CAAC,aAAa,CAAC,CAAC,EACZ,IAAI,GACJ,WAAW,GACX,WAAW,GACX,SAAS,GACT,WAAW,GACX,UAAU,GACV,YAAY,GACZ,OAAO,GACP,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,GAChB,cAAc,GACd,oBAAoB,CAAC;IAGzB,EAAE,EAAE,MAAM,CAAgB;IAI1B,IAAI,EAAG,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,aAAa,GAAG,OAAO,CAAC;IAG3D,QAAQ,EAAG,MAAM,CAAC;IAGlB,QAAQ,EAAG,MAAM,CAAC;IAGlB,SAAS,EAAG,MAAM,CAAC;IAEnB;;;;OAIG;IAEH,UAAU,EAAG,MAAM,CAAC;IAGpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAIxC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGzB,UAAU,EAAE,QAAQ,GAAG,SAAS,CAAY;IAG5C,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGtB,cAAc,EAAE,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,QAAQ,CAAW;IAG5D,cAAc,EAAE,MAAM,CAAM;IAG5B,cAAc,EAAE,OAAO,CAAS;IAGhC,YAAY,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAG3B,kBAAkB,EAAE,OAAO,CAAS;IAGpC,SAAS,EAAE,IAAI,CAAc;IAG7B,SAAS,EAAE,IAAI,CAAc;IAG7B,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACzB"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Entity, Index, OptionalProps, PrimaryKey, Property } from '@mikro-orm/core';
|
|
11
|
+
import { GlobalEntity } from '@endora-commerce/platform/tenancy';
|
|
12
|
+
import { randomUUID } from 'crypto';
|
|
13
|
+
/**
|
|
14
|
+
* Asset — file managed by the Assets Library (feature 013). Replaces the
|
|
15
|
+
* pre-013 `assets` module entity. Existing FK references from Catalog
|
|
16
|
+
* (gallery_items.asset_id, product_attachments.asset_id, products.download_asset_id)
|
|
17
|
+
* and the new categories.main_image_asset_id continue to point here.
|
|
18
|
+
*
|
|
19
|
+
* Visibility, storage backend, and folder are introduced in feature 013;
|
|
20
|
+
* `storageUrl` is retained for one release as a read-only legacy escape hatch
|
|
21
|
+
* and is no longer written by new code (research R11 / FR-034).
|
|
22
|
+
*/
|
|
23
|
+
let Asset = class Asset {
|
|
24
|
+
[OptionalProps];
|
|
25
|
+
id = randomUUID();
|
|
26
|
+
kind;
|
|
27
|
+
filename;
|
|
28
|
+
mimeType;
|
|
29
|
+
sizeBytes;
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated Use `storageLocator` + `storageBackend` instead. Retained
|
|
32
|
+
* for one release for the legacy-decomp escape hatch (research R11);
|
|
33
|
+
* removed in a follow-up cleanup PR.
|
|
34
|
+
*/
|
|
35
|
+
storageUrl;
|
|
36
|
+
altText;
|
|
37
|
+
folderId;
|
|
38
|
+
visibility = 'public';
|
|
39
|
+
label;
|
|
40
|
+
storageBackend = 'local';
|
|
41
|
+
storageLocator = '';
|
|
42
|
+
pendingCleanup = false;
|
|
43
|
+
purgeAfterAt;
|
|
44
|
+
mimeTypeOverridden = false;
|
|
45
|
+
createdAt = new Date();
|
|
46
|
+
updatedAt = new Date();
|
|
47
|
+
deletedAt;
|
|
48
|
+
};
|
|
49
|
+
__decorate([
|
|
50
|
+
PrimaryKey({ type: 'uuid' }),
|
|
51
|
+
__metadata("design:type", String)
|
|
52
|
+
], Asset.prototype, "id", void 0);
|
|
53
|
+
__decorate([
|
|
54
|
+
Property({ type: 'string', length: 16 }),
|
|
55
|
+
Index(),
|
|
56
|
+
__metadata("design:type", String)
|
|
57
|
+
], Asset.prototype, "kind", void 0);
|
|
58
|
+
__decorate([
|
|
59
|
+
Property({ type: 'string', length: 255 }),
|
|
60
|
+
__metadata("design:type", String)
|
|
61
|
+
], Asset.prototype, "filename", void 0);
|
|
62
|
+
__decorate([
|
|
63
|
+
Property({ type: 'string', length: 127 }),
|
|
64
|
+
__metadata("design:type", String)
|
|
65
|
+
], Asset.prototype, "mimeType", void 0);
|
|
66
|
+
__decorate([
|
|
67
|
+
Property({ type: 'bigint' }),
|
|
68
|
+
__metadata("design:type", String)
|
|
69
|
+
], Asset.prototype, "sizeBytes", void 0);
|
|
70
|
+
__decorate([
|
|
71
|
+
Property({ type: 'string', length: 2048 }),
|
|
72
|
+
__metadata("design:type", String)
|
|
73
|
+
], Asset.prototype, "storageUrl", void 0);
|
|
74
|
+
__decorate([
|
|
75
|
+
Property({ type: 'json', nullable: true }),
|
|
76
|
+
__metadata("design:type", Object)
|
|
77
|
+
], Asset.prototype, "altText", void 0);
|
|
78
|
+
__decorate([
|
|
79
|
+
Property({ type: 'uuid', nullable: true }),
|
|
80
|
+
Index(),
|
|
81
|
+
__metadata("design:type", Object)
|
|
82
|
+
], Asset.prototype, "folderId", void 0);
|
|
83
|
+
__decorate([
|
|
84
|
+
Property({ type: 'string', length: 7 }),
|
|
85
|
+
__metadata("design:type", String)
|
|
86
|
+
], Asset.prototype, "visibility", void 0);
|
|
87
|
+
__decorate([
|
|
88
|
+
Property({ type: 'text', nullable: true }),
|
|
89
|
+
__metadata("design:type", Object)
|
|
90
|
+
], Asset.prototype, "label", void 0);
|
|
91
|
+
__decorate([
|
|
92
|
+
Property({ type: 'string', length: 8 }),
|
|
93
|
+
__metadata("design:type", String)
|
|
94
|
+
], Asset.prototype, "storageBackend", void 0);
|
|
95
|
+
__decorate([
|
|
96
|
+
Property({ type: 'string', length: 2048 }),
|
|
97
|
+
__metadata("design:type", String)
|
|
98
|
+
], Asset.prototype, "storageLocator", void 0);
|
|
99
|
+
__decorate([
|
|
100
|
+
Property({ type: 'boolean' }),
|
|
101
|
+
__metadata("design:type", Boolean)
|
|
102
|
+
], Asset.prototype, "pendingCleanup", void 0);
|
|
103
|
+
__decorate([
|
|
104
|
+
Property({ type: 'datetime', nullable: true }),
|
|
105
|
+
__metadata("design:type", Object)
|
|
106
|
+
], Asset.prototype, "purgeAfterAt", void 0);
|
|
107
|
+
__decorate([
|
|
108
|
+
Property({ type: 'boolean' }),
|
|
109
|
+
__metadata("design:type", Boolean)
|
|
110
|
+
], Asset.prototype, "mimeTypeOverridden", void 0);
|
|
111
|
+
__decorate([
|
|
112
|
+
Property({ type: 'datetime', onCreate: () => new Date() }),
|
|
113
|
+
__metadata("design:type", Date)
|
|
114
|
+
], Asset.prototype, "createdAt", void 0);
|
|
115
|
+
__decorate([
|
|
116
|
+
Property({ type: 'datetime', onUpdate: () => new Date() }),
|
|
117
|
+
__metadata("design:type", Date)
|
|
118
|
+
], Asset.prototype, "updatedAt", void 0);
|
|
119
|
+
__decorate([
|
|
120
|
+
Property({ type: 'datetime', nullable: true }),
|
|
121
|
+
__metadata("design:type", Object)
|
|
122
|
+
], Asset.prototype, "deletedAt", void 0);
|
|
123
|
+
Asset = __decorate([
|
|
124
|
+
GlobalEntity(),
|
|
125
|
+
Entity({ tableName: 'assets' })
|
|
126
|
+
], Asset);
|
|
127
|
+
export { Asset };
|
|
128
|
+
//# sourceMappingURL=asset.entity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset.entity.js","sourceRoot":"","sources":["../../../src/backend/entities/asset.entity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { EntityManager } from '@mikro-orm/postgresql';
|
|
2
|
+
import type { AuditPort } from '@endora-commerce/platform/kernel';
|
|
3
|
+
import type { ModuleContext } from '@endora-commerce/platform/kernel';
|
|
4
|
+
import type { RequireAdminFactory } from '@endora-commerce/platform/kernel';
|
|
5
|
+
import { assetsLibraryModule } from './plugin.js';
|
|
6
|
+
import { AssetFolder } from './entities/asset-folder.entity.js';
|
|
7
|
+
import { Asset } from './entities/asset.entity.js';
|
|
8
|
+
/**
|
|
9
|
+
* `assets_library` — the module whose permission gate defaulted to open
|
|
10
|
+
* (feature 072, wave 1, T092).
|
|
11
|
+
*
|
|
12
|
+
* The conversion is otherwise unremarkable: one construction site per root, one
|
|
13
|
+
* plugin, a registry three other modules register their reference resolvers
|
|
14
|
+
* into. What is worth stopping on is the option shape it had:
|
|
15
|
+
*
|
|
16
|
+
* // Permission gate factory. When omitted, a permissive no-op is used.
|
|
17
|
+
* requireAdmin?: RequireAdminFactory;
|
|
18
|
+
*
|
|
19
|
+
* Both roots do pass one, so nothing was open in production. But a **security
|
|
20
|
+
* gate that defaults to permissive** is the class of latent defect this wave has
|
|
21
|
+
* now removed three times over — `addresses`' unvalidated writes,
|
|
22
|
+
* `customer_accounts`' MFA-less auth service, `orders`' unarmed address service.
|
|
23
|
+
* An optional argument whose omission is silent, whose default is the unsafe
|
|
24
|
+
* direction, and which no test notices because the safe path is the one
|
|
25
|
+
* exercised. Resolving `requireAdmin` from the container removes the option
|
|
26
|
+
* entirely: there is no omission left to be silent about.
|
|
27
|
+
*
|
|
28
|
+
* **One registration holds the whole module result**, plugin and handle
|
|
29
|
+
* together. Registering them separately would mean two `assetsLibraryModule`
|
|
30
|
+
* calls per composition — the routes serving one `AssetsLibraryService` and one
|
|
31
|
+
* `AssetReferenceRegistry` while `catalog`, `cms` and `megamenu` registered
|
|
32
|
+
* their resolvers into a different pair. That is exactly the multi-instance
|
|
33
|
+
* defect this wave keeps removing, and it is easy to write by accident here,
|
|
34
|
+
* because the factory returns two things that look independent.
|
|
35
|
+
*/
|
|
36
|
+
type AssetsLibraryResult = ReturnType<typeof assetsLibraryModule>;
|
|
37
|
+
export interface AssetsLibraryCradle {
|
|
38
|
+
readonly emFactory: () => EntityManager;
|
|
39
|
+
readonly auditLogService: AuditPort;
|
|
40
|
+
readonly requireAdmin: RequireAdminFactory;
|
|
41
|
+
readonly assetsLibrary: AssetsLibraryResult;
|
|
42
|
+
}
|
|
43
|
+
export declare function registerModule(ctx: ModuleContext): void;
|
|
44
|
+
/**
|
|
45
|
+
* The module's persisted entity classes, on the `./backend` subpath, as one
|
|
46
|
+
* array and **no named class export** (D-168).
|
|
47
|
+
*
|
|
48
|
+
* This is the shape the platform reads when the package is *installed*: the
|
|
49
|
+
* boot-time loader (`src/packages/package-runtime.ts`, `exported['entities']`)
|
|
50
|
+
* and the static declaration reader (`scripts/lib/package-declarations.ts`),
|
|
51
|
+
* which is the third source of `check:module-boundary`'s `table→owner` map and
|
|
52
|
+
* the package pass of `check-entity-tenant-classification`. A missing array is
|
|
53
|
+
* answered with `[]` — zero entities registered, no error anywhere.
|
|
54
|
+
*/
|
|
55
|
+
export declare const entities: (typeof Asset | typeof AssetFolder)[];
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAM3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAElE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,KAAK,mBAAmB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAElE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,aAAa,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,SAAS,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAC3C,QAAQ,CAAC,aAAa,EAAE,mBAAmB,CAAC;CAC7C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAsJvD;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,uCAGpB,CAAC"}
|