@happyvertical/smrt-assets 0.55.9 → 0.55.11
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/README.md +18 -0
- package/dist/asset-store.d.ts +4 -0
- package/dist/asset-store.d.ts.map +1 -1
- package/dist/chunks/{playground-CGd8_X0M.js → playground-Du1zCQu7.js} +19 -4
- package/dist/chunks/playground-Du1zCQu7.js.map +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +205 -1
- package/dist/playground.d.ts +1 -1
- package/dist/playground.d.ts.map +1 -1
- package/dist/playground.js +2 -2
- package/dist/recipes.d.ts +159 -0
- package/dist/recipes.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +207 -3
- package/dist/svelte/playground/AttachmentPanelPreview.svelte +2 -1
- package/dist/svelte/playground/AttachmentPanelPreview.svelte.d.ts.map +1 -1
- package/dist/svelte/playground.d.ts +38 -0
- package/dist/svelte/playground.d.ts.map +1 -1
- package/dist/svelte/playground.js +23 -2
- package/dist/workbench.js +1 -1
- package/package.json +8 -8
- package/dist/chunks/playground-CGd8_X0M.js.map +0 -1
package/dist/manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": "1.0.0",
|
|
3
3
|
"timestamp": 0,
|
|
4
4
|
"packageName": "@happyvertical/smrt-assets",
|
|
5
|
-
"packageVersion": "0.55.
|
|
5
|
+
"packageVersion": "0.55.11",
|
|
6
6
|
"objects": {
|
|
7
7
|
"@happyvertical/smrt-assets:AssetAssociation": {
|
|
8
8
|
"name": "assetassociation",
|
|
@@ -3151,6 +3151,210 @@
|
|
|
3151
3151
|
}
|
|
3152
3152
|
},
|
|
3153
3153
|
"moduleType": "smrt",
|
|
3154
|
+
"recipes": [
|
|
3155
|
+
{
|
|
3156
|
+
"id": "assets.attachments",
|
|
3157
|
+
"className": "AssetAttachmentsRecipe",
|
|
3158
|
+
"label": "Attachments",
|
|
3159
|
+
"summary": "Attach authorized files to records and retain their history.",
|
|
3160
|
+
"synonyms": [
|
|
3161
|
+
"file attachments",
|
|
3162
|
+
"record files",
|
|
3163
|
+
"supporting documents"
|
|
3164
|
+
],
|
|
3165
|
+
"models": [
|
|
3166
|
+
"@happyvertical/smrt-assets:Asset",
|
|
3167
|
+
"@happyvertical/smrt-assets:AssetAssociation"
|
|
3168
|
+
],
|
|
3169
|
+
"nav": [
|
|
3170
|
+
{
|
|
3171
|
+
"label": "Attachments",
|
|
3172
|
+
"model": "@happyvertical/smrt-assets:Asset",
|
|
3173
|
+
"icon": "fileText",
|
|
3174
|
+
"description": "Supporting files connected to the record you are viewing.",
|
|
3175
|
+
"noun": "attachment"
|
|
3176
|
+
}
|
|
3177
|
+
],
|
|
3178
|
+
"requires": [
|
|
3179
|
+
"assets.library"
|
|
3180
|
+
],
|
|
3181
|
+
"group": {
|
|
3182
|
+
"id": "assets",
|
|
3183
|
+
"label": "Files and media",
|
|
3184
|
+
"summary": "Organize files and media, then attach them to the records that need them."
|
|
3185
|
+
},
|
|
3186
|
+
"section": {
|
|
3187
|
+
"id": "assets",
|
|
3188
|
+
"label": "Assets",
|
|
3189
|
+
"icon": "folder",
|
|
3190
|
+
"description": "Files, media and attachments for your work."
|
|
3191
|
+
},
|
|
3192
|
+
"options": {
|
|
3193
|
+
"@happyvertical/smrt-assets:Asset": {
|
|
3194
|
+
"fields": {
|
|
3195
|
+
"name": {
|
|
3196
|
+
"label": "File name",
|
|
3197
|
+
"order": 1
|
|
3198
|
+
},
|
|
3199
|
+
"description": {
|
|
3200
|
+
"label": "Description",
|
|
3201
|
+
"order": 2
|
|
3202
|
+
},
|
|
3203
|
+
"mimeType": {
|
|
3204
|
+
"label": "File type",
|
|
3205
|
+
"order": 3
|
|
3206
|
+
}
|
|
3207
|
+
}
|
|
3208
|
+
},
|
|
3209
|
+
"@happyvertical/smrt-assets:AssetAssociation": {
|
|
3210
|
+
"fields": {
|
|
3211
|
+
"assetId": {
|
|
3212
|
+
"label": "Attachment",
|
|
3213
|
+
"order": 1
|
|
3214
|
+
},
|
|
3215
|
+
"role": {
|
|
3216
|
+
"label": "Role",
|
|
3217
|
+
"order": 2
|
|
3218
|
+
},
|
|
3219
|
+
"sortOrder": {
|
|
3220
|
+
"label": "Display order",
|
|
3221
|
+
"order": 3
|
|
3222
|
+
}
|
|
3223
|
+
}
|
|
3224
|
+
}
|
|
3225
|
+
},
|
|
3226
|
+
"help": {
|
|
3227
|
+
"markdown": "## Overview\n\nAttachments keep authorized supporting files connected to a record without making a public storage link. The application supplies the authorization and upload endpoint; this recipe records the asset and its relationship.\n\n## Tasks\n\n### Describe an attachment\n\n1. Use a clear {field:Asset.name} so people can identify the file.\n2. Add a {field:Asset.description} when the attachment needs context.\n3. Check the {field:Asset.mimeType} before offering the file to a viewer.\n\n### Link an attachment to a record\n\n1. Select the {field:AssetAssociation.assetId} to link.\n2. Set a {field:AssetAssociation.role} when the record uses more than one file.\n3. Adjust {field:AssetAssociation.sortOrder} to control display order.\n",
|
|
3228
|
+
"fieldRefs": [
|
|
3229
|
+
"Asset.description",
|
|
3230
|
+
"Asset.mimeType",
|
|
3231
|
+
"Asset.name",
|
|
3232
|
+
"AssetAssociation.assetId",
|
|
3233
|
+
"AssetAssociation.role",
|
|
3234
|
+
"AssetAssociation.sortOrder"
|
|
3235
|
+
]
|
|
3236
|
+
},
|
|
3237
|
+
"runtime": "both",
|
|
3238
|
+
"demoSeed": {
|
|
3239
|
+
"export": "@happyvertical/smrt-assets/playground#assetAttachmentMockAttachments"
|
|
3240
|
+
},
|
|
3241
|
+
"demo": {
|
|
3242
|
+
"mode": "server",
|
|
3243
|
+
"reasons": [
|
|
3244
|
+
"Needs a server because its package depends on @happyvertical/smrt-tenancy, which do not build for a browser (#3624)."
|
|
3245
|
+
]
|
|
3246
|
+
}
|
|
3247
|
+
},
|
|
3248
|
+
{
|
|
3249
|
+
"id": "assets.library",
|
|
3250
|
+
"className": "AssetLibraryRecipe",
|
|
3251
|
+
"label": "Asset Library",
|
|
3252
|
+
"summary": "Organize files and media with folders, types, and statuses.",
|
|
3253
|
+
"synonyms": [
|
|
3254
|
+
"media library",
|
|
3255
|
+
"file library",
|
|
3256
|
+
"digital assets"
|
|
3257
|
+
],
|
|
3258
|
+
"models": [
|
|
3259
|
+
"@happyvertical/smrt-assets:Asset",
|
|
3260
|
+
"@happyvertical/smrt-assets:Folder",
|
|
3261
|
+
"@happyvertical/smrt-assets:AssetType",
|
|
3262
|
+
"@happyvertical/smrt-assets:AssetStatus",
|
|
3263
|
+
"@happyvertical/smrt-assets:AssetMetafield"
|
|
3264
|
+
],
|
|
3265
|
+
"nav": [
|
|
3266
|
+
{
|
|
3267
|
+
"label": "Assets",
|
|
3268
|
+
"model": "@happyvertical/smrt-assets:Asset",
|
|
3269
|
+
"icon": "archive",
|
|
3270
|
+
"description": "Files and media you can organize, reuse and share.",
|
|
3271
|
+
"noun": "asset"
|
|
3272
|
+
},
|
|
3273
|
+
{
|
|
3274
|
+
"label": "Folders",
|
|
3275
|
+
"model": "@happyvertical/smrt-assets:Folder",
|
|
3276
|
+
"icon": "folder",
|
|
3277
|
+
"description": "Organize assets into clear, reusable groups.",
|
|
3278
|
+
"noun": "folder"
|
|
3279
|
+
}
|
|
3280
|
+
],
|
|
3281
|
+
"requires": [],
|
|
3282
|
+
"group": {
|
|
3283
|
+
"id": "assets",
|
|
3284
|
+
"label": "Files and media",
|
|
3285
|
+
"summary": "Organize files and media, then attach them to the records that need them."
|
|
3286
|
+
},
|
|
3287
|
+
"section": {
|
|
3288
|
+
"id": "assets",
|
|
3289
|
+
"label": "Assets",
|
|
3290
|
+
"icon": "folder",
|
|
3291
|
+
"description": "Files, media and attachments for your work."
|
|
3292
|
+
},
|
|
3293
|
+
"options": {
|
|
3294
|
+
"@happyvertical/smrt-assets:Asset": {
|
|
3295
|
+
"fields": {
|
|
3296
|
+
"name": {
|
|
3297
|
+
"label": "Name",
|
|
3298
|
+
"order": 1
|
|
3299
|
+
},
|
|
3300
|
+
"description": {
|
|
3301
|
+
"order": 2
|
|
3302
|
+
},
|
|
3303
|
+
"folderId": {
|
|
3304
|
+
"label": "Folder",
|
|
3305
|
+
"order": 3
|
|
3306
|
+
},
|
|
3307
|
+
"typeSlug": {
|
|
3308
|
+
"label": "Type",
|
|
3309
|
+
"order": 4
|
|
3310
|
+
},
|
|
3311
|
+
"statusSlug": {
|
|
3312
|
+
"label": "Status",
|
|
3313
|
+
"order": 5
|
|
3314
|
+
},
|
|
3315
|
+
"mimeType": {
|
|
3316
|
+
"label": "File type",
|
|
3317
|
+
"order": 6
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3320
|
+
},
|
|
3321
|
+
"@happyvertical/smrt-assets:Folder": {
|
|
3322
|
+
"fields": {
|
|
3323
|
+
"name": {
|
|
3324
|
+
"label": "Name",
|
|
3325
|
+
"order": 1
|
|
3326
|
+
},
|
|
3327
|
+
"description": {
|
|
3328
|
+
"order": 2
|
|
3329
|
+
}
|
|
3330
|
+
}
|
|
3331
|
+
}
|
|
3332
|
+
},
|
|
3333
|
+
"help": {
|
|
3334
|
+
"markdown": "## Overview\n\nThe Asset Library keeps files and media in one place. Organize assets into folders, classify them by type and status, and keep a clear description for people who need to find them later.\n\n## Tasks\n\n### Add an asset\n\n1. Give the asset a recognizable {field:Asset.name}.\n2. Add a {field:Asset.description} that explains how the file can be used.\n3. Select its {field:Asset.folderId}, {field:Asset.typeSlug}, and {field:Asset.statusSlug}.\n4. Confirm the {field:Asset.mimeType} matches the file you intend to manage.\n\n### Organize folders\n\n1. Create a folder with a descriptive {field:Folder.name}.\n2. Use the {field:Folder.description} to explain the folder's purpose.\n",
|
|
3335
|
+
"fieldRefs": [
|
|
3336
|
+
"Asset.description",
|
|
3337
|
+
"Asset.folderId",
|
|
3338
|
+
"Asset.mimeType",
|
|
3339
|
+
"Asset.name",
|
|
3340
|
+
"Asset.statusSlug",
|
|
3341
|
+
"Asset.typeSlug",
|
|
3342
|
+
"Folder.description",
|
|
3343
|
+
"Folder.name"
|
|
3344
|
+
]
|
|
3345
|
+
},
|
|
3346
|
+
"runtime": "both",
|
|
3347
|
+
"demoSeed": {
|
|
3348
|
+
"export": "@happyvertical/smrt-assets/playground#assetGridMockAssets"
|
|
3349
|
+
},
|
|
3350
|
+
"demo": {
|
|
3351
|
+
"mode": "server",
|
|
3352
|
+
"reasons": [
|
|
3353
|
+
"Needs a server because its package depends on @happyvertical/smrt-tenancy, which do not build for a browser (#3624)."
|
|
3354
|
+
]
|
|
3355
|
+
}
|
|
3356
|
+
}
|
|
3357
|
+
],
|
|
3154
3358
|
"smrtDependencies": [
|
|
3155
3359
|
"@happyvertical/smrt-core",
|
|
3156
3360
|
"@happyvertical/smrt-tags",
|
package/dist/playground.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default } from './svelte/playground.js';
|
|
1
|
+
export { assetAttachmentMockAttachments, assetGridMockAssets, default, } from './svelte/playground.js';
|
|
2
2
|
//# sourceMappingURL=playground.d.ts.map
|
package/dist/playground.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playground.d.ts","sourceRoot":"","sources":["../src/playground.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"playground.d.ts","sourceRoot":"","sources":["../src/playground.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,mBAAmB,EACnB,OAAO,GACR,MAAM,wBAAwB,CAAC"}
|
package/dist/playground.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { playground_default as default };
|
|
1
|
+
import { n as assetGridMockAssets, r as playground_default, t as assetAttachmentMockAttachments } from "./chunks/playground-Du1zCQu7.js";
|
|
2
|
+
export { assetAttachmentMockAttachments, assetGridMockAssets, playground_default as default };
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declared feature recipes for smrt-assets (#3725).
|
|
3
|
+
*
|
|
4
|
+
* The recipes describe the package's model-backed asset workflows and their
|
|
5
|
+
* public UI metadata. Storage remains application-owned, so no provider is
|
|
6
|
+
* declared here. The package's UI components require host persistence or
|
|
7
|
+
* record authorization context, so neither recipe declares a standalone
|
|
8
|
+
* placement.
|
|
9
|
+
*/
|
|
10
|
+
import { SmrtRecipe } from '@happyvertical/smrt-core';
|
|
11
|
+
import { Asset } from './asset.js';
|
|
12
|
+
import { AssetAssociation } from './asset-association.js';
|
|
13
|
+
import { AssetMetafield } from './asset-metafield.js';
|
|
14
|
+
import { AssetStatus } from './asset-status.js';
|
|
15
|
+
import { Folder } from './folder.js';
|
|
16
|
+
/** Organize, classify, and manage a library of files and media. */
|
|
17
|
+
export declare class AssetLibraryRecipe extends SmrtRecipe {
|
|
18
|
+
static id: string;
|
|
19
|
+
static help: string;
|
|
20
|
+
static label: string;
|
|
21
|
+
static summary: string;
|
|
22
|
+
static synonyms: string[];
|
|
23
|
+
static group: {
|
|
24
|
+
id: string;
|
|
25
|
+
label: string;
|
|
26
|
+
summary: string;
|
|
27
|
+
};
|
|
28
|
+
static section: {
|
|
29
|
+
id: string;
|
|
30
|
+
label: string;
|
|
31
|
+
icon: string;
|
|
32
|
+
description: string;
|
|
33
|
+
};
|
|
34
|
+
static models: (typeof AssetStatus | typeof AssetMetafield)[];
|
|
35
|
+
static runtime: "both";
|
|
36
|
+
static demoSeed: {
|
|
37
|
+
readonly export: "@happyvertical/smrt-assets/playground#assetGridMockAssets";
|
|
38
|
+
};
|
|
39
|
+
static nav: ({
|
|
40
|
+
label: string;
|
|
41
|
+
model: typeof Asset;
|
|
42
|
+
icon: string;
|
|
43
|
+
description: string;
|
|
44
|
+
noun: string;
|
|
45
|
+
} | {
|
|
46
|
+
label: string;
|
|
47
|
+
model: typeof Folder;
|
|
48
|
+
icon: string;
|
|
49
|
+
description: string;
|
|
50
|
+
noun: string;
|
|
51
|
+
})[];
|
|
52
|
+
static options: {
|
|
53
|
+
readonly Asset: {
|
|
54
|
+
readonly fields: {
|
|
55
|
+
readonly name: {
|
|
56
|
+
readonly label: "Name";
|
|
57
|
+
readonly order: 1;
|
|
58
|
+
};
|
|
59
|
+
readonly description: {
|
|
60
|
+
readonly order: 2;
|
|
61
|
+
};
|
|
62
|
+
readonly folderId: {
|
|
63
|
+
readonly label: "Folder";
|
|
64
|
+
readonly order: 3;
|
|
65
|
+
};
|
|
66
|
+
readonly typeSlug: {
|
|
67
|
+
readonly label: "Type";
|
|
68
|
+
readonly order: 4;
|
|
69
|
+
};
|
|
70
|
+
readonly statusSlug: {
|
|
71
|
+
readonly label: "Status";
|
|
72
|
+
readonly order: 5;
|
|
73
|
+
};
|
|
74
|
+
readonly mimeType: {
|
|
75
|
+
readonly label: "File type";
|
|
76
|
+
readonly order: 6;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
readonly Folder: {
|
|
81
|
+
readonly fields: {
|
|
82
|
+
readonly name: {
|
|
83
|
+
readonly label: "Name";
|
|
84
|
+
readonly order: 1;
|
|
85
|
+
};
|
|
86
|
+
readonly description: {
|
|
87
|
+
readonly order: 2;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/** Attach authorized files to records while retaining their provenance. */
|
|
94
|
+
export declare class AssetAttachmentsRecipe extends SmrtRecipe {
|
|
95
|
+
static id: string;
|
|
96
|
+
static help: string;
|
|
97
|
+
static label: string;
|
|
98
|
+
static summary: string;
|
|
99
|
+
static synonyms: string[];
|
|
100
|
+
static group: {
|
|
101
|
+
id: string;
|
|
102
|
+
label: string;
|
|
103
|
+
summary: string;
|
|
104
|
+
};
|
|
105
|
+
static section: {
|
|
106
|
+
id: string;
|
|
107
|
+
label: string;
|
|
108
|
+
icon: string;
|
|
109
|
+
description: string;
|
|
110
|
+
};
|
|
111
|
+
static models: (typeof AssetAssociation | typeof Asset)[];
|
|
112
|
+
static runtime: "both";
|
|
113
|
+
static demoSeed: {
|
|
114
|
+
readonly export: "@happyvertical/smrt-assets/playground#assetAttachmentMockAttachments";
|
|
115
|
+
};
|
|
116
|
+
static nav: {
|
|
117
|
+
label: string;
|
|
118
|
+
model: typeof Asset;
|
|
119
|
+
icon: string;
|
|
120
|
+
description: string;
|
|
121
|
+
noun: string;
|
|
122
|
+
}[];
|
|
123
|
+
static requires: string[];
|
|
124
|
+
static options: {
|
|
125
|
+
readonly Asset: {
|
|
126
|
+
readonly fields: {
|
|
127
|
+
readonly name: {
|
|
128
|
+
readonly label: "File name";
|
|
129
|
+
readonly order: 1;
|
|
130
|
+
};
|
|
131
|
+
readonly description: {
|
|
132
|
+
readonly label: "Description";
|
|
133
|
+
readonly order: 2;
|
|
134
|
+
};
|
|
135
|
+
readonly mimeType: {
|
|
136
|
+
readonly label: "File type";
|
|
137
|
+
readonly order: 3;
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
readonly AssetAssociation: {
|
|
142
|
+
readonly fields: {
|
|
143
|
+
readonly assetId: {
|
|
144
|
+
readonly label: "Attachment";
|
|
145
|
+
readonly order: 1;
|
|
146
|
+
};
|
|
147
|
+
readonly role: {
|
|
148
|
+
readonly label: "Role";
|
|
149
|
+
readonly order: 2;
|
|
150
|
+
};
|
|
151
|
+
readonly sortOrder: {
|
|
152
|
+
readonly label: "Display order";
|
|
153
|
+
readonly order: 3;
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=recipes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipes.d.ts","sourceRoot":"","sources":["../src/recipes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,mEAAmE;AACnE,qBAAa,kBAAmB,SAAQ,UAAU;IAChD,MAAM,CAAC,EAAE,SAAoB;IAC7B,MAAM,CAAC,IAAI,SAAgC;IAC3C,MAAM,CAAC,KAAK,SAAmB;IAC/B,MAAM,CAAC,OAAO,SACkD;IAChE,MAAM,CAAC,QAAQ,WAAuD;IACtE,MAAM,CAAC,KAAK;;;;MAKV;IACF,MAAM,CAAC,OAAO;;;;;MAKZ;IACF,MAAM,CAAC,MAAM,iDAA2D;IACxE,MAAM,CAAC,OAAO,EAAG,MAAM,CAAU;IACjC,MAAM,CAAC,QAAQ;;MAEJ;IACX,MAAM,CAAC,GAAG;;;;;;;;;;;;SAeR;IACF,MAAM,CAAC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAiBH;CACZ;AAED,2EAA2E;AAC3E,qBAAa,sBAAuB,SAAQ,UAAU;IACpD,MAAM,CAAC,EAAE,SAAwB;IACjC,MAAM,CAAC,IAAI,SAAoC;IAC/C,MAAM,CAAC,KAAK,SAAiB;IAC7B,MAAM,CAAC,OAAO,SACmD;IACjE,MAAM,CAAC,QAAQ,WAIb;IACF,MAAM,CAAC,KAAK;;;;MAKV;IACF,MAAM,CAAC,OAAO;;;;;MAKZ;IACF,MAAM,CAAC,MAAM,6CAA6B;IAC1C,MAAM,CAAC,OAAO,EAAG,MAAM,CAAU;IACjC,MAAM,CAAC,QAAQ;;MAGJ;IACX,MAAM,CAAC,GAAG;;;;;;QAQR;IACF,MAAM,CAAC,QAAQ,WAAsB;IACrC,MAAM,CAAC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAeH;CACZ"}
|
package/dist/smrt-knowledge.json
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
"sensitiveFieldsExcluded": true,
|
|
4
4
|
"generatedAt": "1970-01-01T00:00:00.000Z",
|
|
5
5
|
"packageName": "@happyvertical/smrt-assets",
|
|
6
|
-
"packageVersion": "0.55.
|
|
6
|
+
"packageVersion": "0.55.11",
|
|
7
7
|
"sourceManifestPath": "dist/manifest.json",
|
|
8
8
|
"agentDocPath": "AGENTS.md",
|
|
9
9
|
"sourceHashes": {
|
|
10
|
-
"manifest": "
|
|
11
|
-
"packageJson": "
|
|
10
|
+
"manifest": "5e8849091280bac925285ed65ecdea60bf1c67ace56e94e6e677ba56a61094b3",
|
|
11
|
+
"packageJson": "76aaf518dc7b815e8e846ec380433cb6b8967e47861bdb277c37e91291816922",
|
|
12
12
|
"agents": "4e84d65324e346f9c6072da7ccee6753289efb95ffb2faf5e999081502189737"
|
|
13
13
|
},
|
|
14
14
|
"exports": [
|
|
@@ -4346,6 +4346,210 @@
|
|
|
4346
4346
|
"uuidColumns": 40
|
|
4347
4347
|
},
|
|
4348
4348
|
"agentDoc": "# @happyvertical/smrt-assets\n\nProvider-agnostic asset management with versioning, type classification, and generic/provenance associations.\n\n## Models\n\n- **Asset** (STI base): versioning via `primaryVersionId` chain + `version` number. `ownerProfileId`, `typeSlug`, `statusSlug`, `mimeType`, `sourceUri`. Derivation chain via `sourceAssetId` (R3-D — was `parentId` before the rename; column `source_asset_id`).\n- **AssetType** / **AssetStatus**: lookup tables for classification and lifecycle.\n- **AssetMetafield**: custom metadata field definitions with JSON validation rules.\n- **Folder**: hierarchical container for assets. Own `SmrtHierarchical` model with its own `folders` table (R3-D — was an STI subclass of Asset before). `Asset.folderId` points to the folder.\n- **AssetAssociation**: generic/provenance polymorphic join — `assetId` + `metaType` + `metaId` + `role` + `sortOrder`. Use it when a relationship is not owned by a base/domain model join table like `content_assets`, `profile_assets`, `event_assets`, `place_assets`, or `product_assets`.\n\n## Key Patterns\n\n- **Versioning**: `createNewVersion()` increments version, chains via `primaryVersionId`. `findVersions()` to retrieve history.\n- **Tag integration**: `addTag()`/`removeTag()` use raw `db.upsert()` on `asset_tags` join table (not a SMRT model).\n- **AssetStore**: abstraction for provider-agnostic file I/O (S3, local, etc.).\n `planFile(asset, opts)` resolves a recoverable URI before bytes are written;\n persist it before `preserveFile(asset, bytes, opts)`. Preservation adopts equal\n existing bytes and rejects changed bytes, changed resolver targets and read\n failures other than not-found. The caller owns receipt fencing/serialization.\n `removeFile(asset)` removes only bytes for recovery cleanup, including an\n already-pruned owner record; `remove(asset)` also deletes the owner record.\n- **Ownership rule**: base/domain-owned asset relationships should live on noun join tables such as `content_assets`, `profile_assets`, `event_assets`, `place_assets`, and `product_assets`; keep `AssetAssociation` for generic/provenance links like image derivation.\n\n## Runtime surface\n\nApps and agents should depend on the public **asset runtime** rather than hand-wiring a collection + store per-package (#1128).\n\n- `createAssetRuntime({ db, storage })` → `AssetRuntime` bundling `AssetCollection`, `AssetAssociationCollection`, and an initialized `AssetStore`.\n- `AssetRuntime.storeSourceAsset(name, data, opts)` — create a new source asset (record + bytes).\n- `AssetRuntime.storeDerivedAsset(source, name, data, opts)` — create a derivative with `sourceAssetId` set and (by default) a provenance `AssetAssociation` under a chosen role.\n- `AssetRuntime.linkDerivation(source, derivative, { role })` — record provenance without touching bytes.\n- `AssetRuntime.setExtractionStatus(asset, status, { error?, extractedAt? })` — write canonical extraction metadata into the asset's description JSON sidecar. Non-destructive: if `description` is free-form prose or non-object JSON, the original value is preserved under the reserved `text` key instead of being overwritten. Existing JSON objects are merged into.\n\nAgents that need asset I/O should accept an `AssetRuntimeLike` in their options rather than asking callers to pass a store + collection separately.\n\n## Serving contract\n\n- `serveAsset({ runtime, asset, tenantId?, disposition?, canAccess?, headers?, remoteMode? })` → standard Web `Response`.\n - `404` when the id doesn't resolve; `403` when the tenant mismatches or `canAccess` denies; `302` when `remoteMode: 'redirect'` and the asset's `sourceUri` is `http(s)`; `502` when `remoteMode: 'proxy'` and the origin fetch fails; `500` on store read errors or unexpected failures; `200` otherwise with `Content-Type`, `Content-Length`, and `Content-Disposition` set.\n - Assets whose `sourceUri` is `http(s)` are supported via `remoteMode`: `'proxy'` (default, fetch and return bytes), `'redirect'` (302 to the origin), or `'error'` (treat as misconfiguration). Pass `fetchImpl` to swap the fetch client.\n - `Content-Disposition` uses an ASCII-safe quoted `filename` fallback and retains the Unicode download name in UTF-8 `filename*` ([RFC 6266](https://www.rfc-editor.org/rfc/rfc6266#section-4.3), [RFC 8187](https://www.rfc-editor.org/rfc/rfc8187#section-3.2.1)). Both names strip C0/DEL/C1 controls and replace `\"` / `\\` / `/` to prevent header injection; isolated UTF-16 surrogates become U+FFFD before encoding, while valid pairs are preserved.\n - The 500 body is a generic `'Internal error serving asset'`; the underlying error is logged via `console.error` so operators can debug without leaking paths/bucket names to clients.\n - Works in SvelteKit `+server.ts` endpoints, Hono, and any runtime with a global `Response` (Node 18+). Pass `responseCtor` for older runtimes.\n- `resolveAssetForServing(options)` → `{ asset, data, contentType, filename, size }` when callers want to render their own framework response. Throws `AssetServeError(status)` on the same failure modes.\n\n## Source/derived vocabulary\n\nThe following roles are exported as `ASSET_ROLES` and should be preferred over ad-hoc strings when apps want cross-package tooling (serving, UI pickers) to agree on meaning:\n\n| Role | Use |\n|------|-----|\n| `source_document` | original upstream document (agenda PDF, minutes) |\n| `document_image` | page/extracted image derived from a source document |\n| `thumbnail` | preview rendition of another asset |\n| `proof` | non-canonical evidence asset backing a fact |\n| `derivation_source` | \"came from\" link on generated media |\n| `attachment` | generic owner-join link |\n| `hero` | primary/featured asset on an owner |\n\nCanonical metadata keys are exported as `ASSET_METADATA_KEYS`: `extractionStatus`, `extractionError`, `extractedAt`, `sourceUrl`, `sourceHash`, `pageNumber`. Extraction status values live in `ASSET_EXTRACTION_STATUS` (`pending | running | succeeded | failed`).\n\n## UI Registry\n\nThe `./ui` subpath exports `ASSETS_MODULE_META` and `ASSETS_UI_SLOTS` so registry-driven hosts (smrt-chat, dynamic admin shells) can discover the package's Svelte components without a hard import.\n\n```ts\nimport { ASSETS_MODULE_META, ASSETS_UI_SLOTS } from '@happyvertical/smrt-assets/ui';\nimport '@happyvertical/smrt-assets/svelte'; // side-effect: ModuleUIRegistry.register(...)\nimport { ModuleUIRegistry } from '@happyvertical/smrt-ui/registry';\n\nconst AssetManager = ModuleUIRegistry.get('@happyvertical/smrt-assets', 'asset-manager');\n```\n\nRegistered slots: `asset-manager` (admin), `asset-grid` / `asset-list` (list), `asset-detail` (detail), `asset-toolbar` / `asset-action-bar` (action), `asset-create-modal` (form). Slot IDs are stable contracts — host apps reference them by string.\n\n## Gotchas\n\n- **Files SDK is a lazy boundary (#1979)**: `AssetStore` loads `@happyvertical/files` through `src/files-runtime.ts` (bundler-invisible), because smrt-assets is reachable from provider-neutral consumer graphs via profiles. Node/tsx/vite-dev runtimes resolve it on first file operation; fully-bundled deployments import `@happyvertical/smrt-assets/filesystem` at startup. Never import the files SDK statically from modules reachable from `src/index.ts`.\n- **Version history manual**: `findVersions()` chaining required — no ORM shortcut\n- **Tag management uses raw SQL**: `asset_tags` is a join table, not an SMRT model\n- **Folder tree traversal**: via `SmrtHierarchical` (`getParent`/`getChildren`/`getAncestors`/`getDescendants`/`getHierarchy`/`moveTo`); `FolderCollection.getTree(rootId?)` and `getPath(folderId)` wrap these for convenience\n- **AssetAssociation polymorphic FK**: requires manual `metaType` string matching\n- **Optional tenancy**: assets can be global (tenantId=null) or tenant-scoped\n",
|
|
4349
|
+
"recipes": [
|
|
4350
|
+
{
|
|
4351
|
+
"id": "assets.attachments",
|
|
4352
|
+
"className": "AssetAttachmentsRecipe",
|
|
4353
|
+
"label": "Attachments",
|
|
4354
|
+
"summary": "Attach authorized files to records and retain their history.",
|
|
4355
|
+
"synonyms": [
|
|
4356
|
+
"file attachments",
|
|
4357
|
+
"record files",
|
|
4358
|
+
"supporting documents"
|
|
4359
|
+
],
|
|
4360
|
+
"models": [
|
|
4361
|
+
"@happyvertical/smrt-assets:Asset",
|
|
4362
|
+
"@happyvertical/smrt-assets:AssetAssociation"
|
|
4363
|
+
],
|
|
4364
|
+
"nav": [
|
|
4365
|
+
{
|
|
4366
|
+
"label": "Attachments",
|
|
4367
|
+
"model": "@happyvertical/smrt-assets:Asset",
|
|
4368
|
+
"icon": "fileText",
|
|
4369
|
+
"description": "Supporting files connected to the record you are viewing.",
|
|
4370
|
+
"noun": "attachment"
|
|
4371
|
+
}
|
|
4372
|
+
],
|
|
4373
|
+
"requires": [
|
|
4374
|
+
"assets.library"
|
|
4375
|
+
],
|
|
4376
|
+
"group": {
|
|
4377
|
+
"id": "assets",
|
|
4378
|
+
"label": "Files and media",
|
|
4379
|
+
"summary": "Organize files and media, then attach them to the records that need them."
|
|
4380
|
+
},
|
|
4381
|
+
"section": {
|
|
4382
|
+
"id": "assets",
|
|
4383
|
+
"label": "Assets",
|
|
4384
|
+
"icon": "folder",
|
|
4385
|
+
"description": "Files, media and attachments for your work."
|
|
4386
|
+
},
|
|
4387
|
+
"options": {
|
|
4388
|
+
"@happyvertical/smrt-assets:Asset": {
|
|
4389
|
+
"fields": {
|
|
4390
|
+
"name": {
|
|
4391
|
+
"label": "File name",
|
|
4392
|
+
"order": 1
|
|
4393
|
+
},
|
|
4394
|
+
"description": {
|
|
4395
|
+
"label": "Description",
|
|
4396
|
+
"order": 2
|
|
4397
|
+
},
|
|
4398
|
+
"mimeType": {
|
|
4399
|
+
"label": "File type",
|
|
4400
|
+
"order": 3
|
|
4401
|
+
}
|
|
4402
|
+
}
|
|
4403
|
+
},
|
|
4404
|
+
"@happyvertical/smrt-assets:AssetAssociation": {
|
|
4405
|
+
"fields": {
|
|
4406
|
+
"assetId": {
|
|
4407
|
+
"label": "Attachment",
|
|
4408
|
+
"order": 1
|
|
4409
|
+
},
|
|
4410
|
+
"role": {
|
|
4411
|
+
"label": "Role",
|
|
4412
|
+
"order": 2
|
|
4413
|
+
},
|
|
4414
|
+
"sortOrder": {
|
|
4415
|
+
"label": "Display order",
|
|
4416
|
+
"order": 3
|
|
4417
|
+
}
|
|
4418
|
+
}
|
|
4419
|
+
}
|
|
4420
|
+
},
|
|
4421
|
+
"help": {
|
|
4422
|
+
"markdown": "## Overview\n\nAttachments keep authorized supporting files connected to a record without making a public storage link. The application supplies the authorization and upload endpoint; this recipe records the asset and its relationship.\n\n## Tasks\n\n### Describe an attachment\n\n1. Use a clear {field:Asset.name} so people can identify the file.\n2. Add a {field:Asset.description} when the attachment needs context.\n3. Check the {field:Asset.mimeType} before offering the file to a viewer.\n\n### Link an attachment to a record\n\n1. Select the {field:AssetAssociation.assetId} to link.\n2. Set a {field:AssetAssociation.role} when the record uses more than one file.\n3. Adjust {field:AssetAssociation.sortOrder} to control display order.\n",
|
|
4423
|
+
"fieldRefs": [
|
|
4424
|
+
"Asset.description",
|
|
4425
|
+
"Asset.mimeType",
|
|
4426
|
+
"Asset.name",
|
|
4427
|
+
"AssetAssociation.assetId",
|
|
4428
|
+
"AssetAssociation.role",
|
|
4429
|
+
"AssetAssociation.sortOrder"
|
|
4430
|
+
]
|
|
4431
|
+
},
|
|
4432
|
+
"runtime": "both",
|
|
4433
|
+
"demoSeed": {
|
|
4434
|
+
"export": "@happyvertical/smrt-assets/playground#assetAttachmentMockAttachments"
|
|
4435
|
+
},
|
|
4436
|
+
"demo": {
|
|
4437
|
+
"mode": "server",
|
|
4438
|
+
"reasons": [
|
|
4439
|
+
"Needs a server because its package depends on @happyvertical/smrt-tenancy, which do not build for a browser (#3624)."
|
|
4440
|
+
]
|
|
4441
|
+
}
|
|
4442
|
+
},
|
|
4443
|
+
{
|
|
4444
|
+
"id": "assets.library",
|
|
4445
|
+
"className": "AssetLibraryRecipe",
|
|
4446
|
+
"label": "Asset Library",
|
|
4447
|
+
"summary": "Organize files and media with folders, types, and statuses.",
|
|
4448
|
+
"synonyms": [
|
|
4449
|
+
"media library",
|
|
4450
|
+
"file library",
|
|
4451
|
+
"digital assets"
|
|
4452
|
+
],
|
|
4453
|
+
"models": [
|
|
4454
|
+
"@happyvertical/smrt-assets:Asset",
|
|
4455
|
+
"@happyvertical/smrt-assets:Folder",
|
|
4456
|
+
"@happyvertical/smrt-assets:AssetType",
|
|
4457
|
+
"@happyvertical/smrt-assets:AssetStatus",
|
|
4458
|
+
"@happyvertical/smrt-assets:AssetMetafield"
|
|
4459
|
+
],
|
|
4460
|
+
"nav": [
|
|
4461
|
+
{
|
|
4462
|
+
"label": "Assets",
|
|
4463
|
+
"model": "@happyvertical/smrt-assets:Asset",
|
|
4464
|
+
"icon": "archive",
|
|
4465
|
+
"description": "Files and media you can organize, reuse and share.",
|
|
4466
|
+
"noun": "asset"
|
|
4467
|
+
},
|
|
4468
|
+
{
|
|
4469
|
+
"label": "Folders",
|
|
4470
|
+
"model": "@happyvertical/smrt-assets:Folder",
|
|
4471
|
+
"icon": "folder",
|
|
4472
|
+
"description": "Organize assets into clear, reusable groups.",
|
|
4473
|
+
"noun": "folder"
|
|
4474
|
+
}
|
|
4475
|
+
],
|
|
4476
|
+
"requires": [],
|
|
4477
|
+
"group": {
|
|
4478
|
+
"id": "assets",
|
|
4479
|
+
"label": "Files and media",
|
|
4480
|
+
"summary": "Organize files and media, then attach them to the records that need them."
|
|
4481
|
+
},
|
|
4482
|
+
"section": {
|
|
4483
|
+
"id": "assets",
|
|
4484
|
+
"label": "Assets",
|
|
4485
|
+
"icon": "folder",
|
|
4486
|
+
"description": "Files, media and attachments for your work."
|
|
4487
|
+
},
|
|
4488
|
+
"options": {
|
|
4489
|
+
"@happyvertical/smrt-assets:Asset": {
|
|
4490
|
+
"fields": {
|
|
4491
|
+
"name": {
|
|
4492
|
+
"label": "Name",
|
|
4493
|
+
"order": 1
|
|
4494
|
+
},
|
|
4495
|
+
"description": {
|
|
4496
|
+
"order": 2
|
|
4497
|
+
},
|
|
4498
|
+
"folderId": {
|
|
4499
|
+
"label": "Folder",
|
|
4500
|
+
"order": 3
|
|
4501
|
+
},
|
|
4502
|
+
"typeSlug": {
|
|
4503
|
+
"label": "Type",
|
|
4504
|
+
"order": 4
|
|
4505
|
+
},
|
|
4506
|
+
"statusSlug": {
|
|
4507
|
+
"label": "Status",
|
|
4508
|
+
"order": 5
|
|
4509
|
+
},
|
|
4510
|
+
"mimeType": {
|
|
4511
|
+
"label": "File type",
|
|
4512
|
+
"order": 6
|
|
4513
|
+
}
|
|
4514
|
+
}
|
|
4515
|
+
},
|
|
4516
|
+
"@happyvertical/smrt-assets:Folder": {
|
|
4517
|
+
"fields": {
|
|
4518
|
+
"name": {
|
|
4519
|
+
"label": "Name",
|
|
4520
|
+
"order": 1
|
|
4521
|
+
},
|
|
4522
|
+
"description": {
|
|
4523
|
+
"order": 2
|
|
4524
|
+
}
|
|
4525
|
+
}
|
|
4526
|
+
}
|
|
4527
|
+
},
|
|
4528
|
+
"help": {
|
|
4529
|
+
"markdown": "## Overview\n\nThe Asset Library keeps files and media in one place. Organize assets into folders, classify them by type and status, and keep a clear description for people who need to find them later.\n\n## Tasks\n\n### Add an asset\n\n1. Give the asset a recognizable {field:Asset.name}.\n2. Add a {field:Asset.description} that explains how the file can be used.\n3. Select its {field:Asset.folderId}, {field:Asset.typeSlug}, and {field:Asset.statusSlug}.\n4. Confirm the {field:Asset.mimeType} matches the file you intend to manage.\n\n### Organize folders\n\n1. Create a folder with a descriptive {field:Folder.name}.\n2. Use the {field:Folder.description} to explain the folder's purpose.\n",
|
|
4530
|
+
"fieldRefs": [
|
|
4531
|
+
"Asset.description",
|
|
4532
|
+
"Asset.folderId",
|
|
4533
|
+
"Asset.mimeType",
|
|
4534
|
+
"Asset.name",
|
|
4535
|
+
"Asset.statusSlug",
|
|
4536
|
+
"Asset.typeSlug",
|
|
4537
|
+
"Folder.description",
|
|
4538
|
+
"Folder.name"
|
|
4539
|
+
]
|
|
4540
|
+
},
|
|
4541
|
+
"runtime": "both",
|
|
4542
|
+
"demoSeed": {
|
|
4543
|
+
"export": "@happyvertical/smrt-assets/playground#assetGridMockAssets"
|
|
4544
|
+
},
|
|
4545
|
+
"demo": {
|
|
4546
|
+
"mode": "server",
|
|
4547
|
+
"reasons": [
|
|
4548
|
+
"Needs a server because its package depends on @happyvertical/smrt-tenancy, which do not build for a browser (#3624)."
|
|
4549
|
+
]
|
|
4550
|
+
}
|
|
4551
|
+
}
|
|
4552
|
+
],
|
|
4349
4553
|
"browser": {
|
|
4350
4554
|
"status": "server-only",
|
|
4351
4555
|
"issues": [
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { Checkbox } from '@happyvertical/smrt-ui/forms';
|
|
3
3
|
import AttachmentPanel from '../components/AttachmentPanel.svelte';
|
|
4
|
+
import { assetAttachmentMockAttachments } from '../playground.js';
|
|
4
5
|
|
|
5
6
|
let canUpload = $state(true);
|
|
6
7
|
let description = $state('Supporting document for review');
|
|
@@ -15,7 +16,7 @@ function submit(event: SubmitEvent & { currentTarget: HTMLFormElement }) {
|
|
|
15
16
|
</script>
|
|
16
17
|
<div class="preview">
|
|
17
18
|
<Checkbox label="May upload attachments" bind:checked={canUpload} />
|
|
18
|
-
<AttachmentPanel attachments={
|
|
19
|
+
<AttachmentPanel attachments={assetAttachmentMockAttachments}
|
|
19
20
|
upload={{ action: '', canUpload, description, message, help: 'Preview accepts a local file but never sends it.', hiddenFields: [{ name: 'requestId', value: 'preview-request-retained' }], onsubmit: submit }} />
|
|
20
21
|
</div>
|
|
21
22
|
<style>.preview { display: grid; gap: var(--smrt-spacing-4); }</style>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttachmentPanelPreview.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/playground/AttachmentPanelPreview.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AttachmentPanelPreview.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/playground/AttachmentPanelPreview.svelte.ts"],"names":[],"mappings":"AA+BA,QAAA,MAAM,sBAAsB,2DAAwC,CAAC;AACrE,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACxE,eAAe,sBAAsB,CAAC"}
|