@bagelink/vue 1.15.668 → 1.17.2
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/dist/assetTransport.d.ts +50 -0
- package/dist/assetTransport.d.ts.map +1 -0
- package/dist/assetTransport.test.d.ts +2 -0
- package/dist/assetTransport.test.d.ts.map +1 -0
- package/dist/assets.d.ts +46 -0
- package/dist/assets.d.ts.map +1 -0
- package/dist/assets.test.d.ts +2 -0
- package/dist/assets.test.d.ts.map +1 -0
- package/dist/components/Image.vue.d.ts +7 -1
- package/dist/components/Image.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/Upload/AssetUploadInput.vue.d.ts +11 -0
- package/dist/components/form/inputs/Upload/AssetUploadInput.vue.d.ts.map +1 -0
- package/dist/components/form/inputs/Upload/UploadInput.vue.d.ts +2 -2
- package/dist/components/form/inputs/Upload/UploadInput.vue.d.ts.map +1 -1
- package/dist/components/lightbox/AssetPreview.vue.d.ts +9 -0
- package/dist/components/lightbox/AssetPreview.vue.d.ts.map +1 -0
- package/dist/components/lightbox/Lightbox.vue.d.ts.map +1 -1
- package/dist/components/lightbox/LightboxImage.vue.d.ts +2 -1
- package/dist/components/lightbox/LightboxImage.vue.d.ts.map +1 -1
- package/dist/components/lightbox/index.d.ts.map +1 -1
- package/dist/components/lightbox/lightbox.types.d.ts +7 -0
- package/dist/components/lightbox/lightbox.types.d.ts.map +1 -1
- package/dist/composables/useImageSrc.d.ts +8 -4
- package/dist/composables/useImageSrc.d.ts.map +1 -1
- package/dist/core.css +1 -1
- package/dist/form-flow/FormFlowPlayer.vue.d.ts +3 -3
- package/dist/form-flow/FormFlowPlayer.vue.d.ts.map +1 -1
- package/dist/form-flow/form-flow.d.ts +11 -6
- package/dist/form-flow/form-flow.d.ts.map +1 -1
- package/dist/form-flow/schema-fields.d.ts +3 -0
- package/dist/form-flow/schema-fields.d.ts.map +1 -1
- package/dist/index.cjs +62 -62
- package/dist/index.css +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +19554 -18982
- package/dist/style.css +1 -1
- package/dist/types/BagelForm.d.ts +3 -1
- package/dist/types/BagelForm.d.ts.map +1 -1
- package/package.json +104 -105
- package/src/assetTransport.test.ts +125 -0
- package/src/assetTransport.ts +164 -0
- package/src/assets.test.ts +123 -0
- package/src/assets.ts +245 -0
- package/src/components/Image.vue +19 -3
- package/src/components/form/inputs/Upload/AssetUploadInput.vue +67 -0
- package/src/components/form/inputs/Upload/UploadInput.vue +5 -1
- package/src/components/lightbox/AssetPreview.vue +16 -0
- package/src/components/lightbox/Lightbox.vue +8 -3
- package/src/components/lightbox/LightboxImage.vue +4 -3
- package/src/components/lightbox/index.ts +29 -4
- package/src/components/lightbox/lightbox.types.ts +5 -1
- package/src/composables/useImageSrc.ts +47 -37
- package/src/form-flow/form-flow.ts +26 -7
- package/src/form-flow/schema-fields.ts +23 -1
- package/src/index.ts +3 -0
- package/src/types/BagelForm.ts +3 -1
|
@@ -98,6 +98,8 @@ export interface UploadInputValueObject {
|
|
|
98
98
|
src?: string;
|
|
99
99
|
}
|
|
100
100
|
export interface UploadInputProps extends BagelInputShellProps {
|
|
101
|
+
/** Opt-in stable reference output; defaults to legacy path-key behavior. */
|
|
102
|
+
assetMode?: boolean;
|
|
101
103
|
id?: string;
|
|
102
104
|
name?: string;
|
|
103
105
|
label?: string;
|
|
@@ -106,7 +108,7 @@ export interface UploadInputProps extends BagelInputShellProps {
|
|
|
106
108
|
* Path-key string(s). Legacy/migrated records may also provide an image object
|
|
107
109
|
* (e.g. `{ imageURL, imageName, extension, altText }`); it is normalized internally.
|
|
108
110
|
*/
|
|
109
|
-
modelValue?: string | string[] | UploadInputValueObject | (string | UploadInputValueObject)[];
|
|
111
|
+
modelValue?: string | string[] | UploadInputValueObject | import('../assets').AssetReference | (string | UploadInputValueObject | import('../assets').AssetReference)[];
|
|
110
112
|
/** Optional upload handler. When omitted, the shared file-storage uploader is used. */
|
|
111
113
|
upload?: (file: File) => Promise<string>;
|
|
112
114
|
width?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BagelForm.d.ts","sourceRoot":"","sources":["../../src/types/BagelForm.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"BagelForm.d.ts","sourceRoot":"","sources":["../../src/types/BagelForm.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,106 +1,105 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
2
|
+
"name": "@bagelink/vue",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "1.17.2",
|
|
5
|
+
"description": "Bagel core sdk packages",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Bagel Studio",
|
|
8
|
+
"email": "hi@bagelstudio.co.il"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"homepage": "https://github.com/bageldb/bagelink/tree/master/packages/vue#readme",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/bageldb/bagelink.git",
|
|
15
|
+
"directory": "packages/vue"
|
|
16
|
+
},
|
|
17
|
+
"bugs": "https://github.com/bageldb/bagelink/issues",
|
|
18
|
+
"keywords": [],
|
|
19
|
+
"sideEffects": [
|
|
20
|
+
"**/*.css"
|
|
21
|
+
],
|
|
22
|
+
"exports": {
|
|
23
|
+
"./tsconfig.json": "./tsconfig.json",
|
|
24
|
+
"./package.json": "./package.json",
|
|
25
|
+
"./src": "./src/index.ts",
|
|
26
|
+
"./src/components": "./src/components/index.ts",
|
|
27
|
+
"./src/utils": "./src/utils/index.ts",
|
|
28
|
+
"./src/types": "./src/types/index.ts",
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"require": "./dist/index.cjs",
|
|
32
|
+
"import": "./dist/index.mjs"
|
|
33
|
+
},
|
|
34
|
+
"./style.css": "./dist/style.css",
|
|
35
|
+
"./styles/core.css": "./dist/core.css",
|
|
36
|
+
"./styles/admin.css": "./dist/style.css",
|
|
37
|
+
"./styles/fonts/admin.css": "./dist/admin.css",
|
|
38
|
+
"./styles/fonts/ploni.css": "./dist/ploni.css",
|
|
39
|
+
"./*": "./*"
|
|
40
|
+
},
|
|
41
|
+
"main": "./dist/index.cjs",
|
|
42
|
+
"module": "./dist/index.mjs",
|
|
43
|
+
"types": "./dist/index.d.ts",
|
|
44
|
+
"typesVersions": {
|
|
45
|
+
"*": {
|
|
46
|
+
"*": [
|
|
47
|
+
"./dist/*",
|
|
48
|
+
"./dist/index.d.ts"
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"bin": {
|
|
53
|
+
"experimentalGenTypedRoutes": "./bin/experimentalGenTypedRoutes.ts"
|
|
54
|
+
},
|
|
55
|
+
"files": [
|
|
56
|
+
"dist",
|
|
57
|
+
"src",
|
|
58
|
+
"./vite.config.ts",
|
|
59
|
+
"bin/experimentalGenTypedRoutes.ts"
|
|
60
|
+
],
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/leaflet": "^1.9.22",
|
|
63
|
+
"@types/signature_pad": "^4.0.0",
|
|
64
|
+
"vue": "^3.5.43",
|
|
65
|
+
"vue-component-type-helpers": "^2.2.12"
|
|
66
|
+
},
|
|
67
|
+
"peerDependencies": {
|
|
68
|
+
"@bagelink/sdk": "*",
|
|
69
|
+
"type-fest": "^4",
|
|
70
|
+
"vue": "*",
|
|
71
|
+
"vue-component-type-helpers": ">=2.2.10",
|
|
72
|
+
"vue-draggable-next": "^2.2.1",
|
|
73
|
+
"vue-router": "*"
|
|
74
|
+
},
|
|
75
|
+
"peerDependenciesMeta": {
|
|
76
|
+
"vue-draggable-next": {
|
|
77
|
+
"optional": true
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"publishConfig": {
|
|
81
|
+
"access": "public"
|
|
82
|
+
},
|
|
83
|
+
"dependencies": {
|
|
84
|
+
"@floating-ui/dom": "^1.8.0",
|
|
85
|
+
"@oddbird/popover-polyfill": "^0.6.1",
|
|
86
|
+
"@vueuse/core": "^13.9.0",
|
|
87
|
+
"@zxcvbn-ts/core": "^3.0.4",
|
|
88
|
+
"axios": "^1.20.0",
|
|
89
|
+
"floating-vue": "^5.4.0",
|
|
90
|
+
"libphonenumber-js": "^1.13.14",
|
|
91
|
+
"page-flip": "^2.0.7",
|
|
92
|
+
"pdfjs-dist": "^6.3.289",
|
|
93
|
+
"signature_pad": "^5.1.4",
|
|
94
|
+
"swiper": "^12.2.0",
|
|
95
|
+
"vue-i18n": "^11.4.12",
|
|
96
|
+
"vue-toastification": "^2.0.0-rc.5"
|
|
97
|
+
},
|
|
98
|
+
"scripts": {
|
|
99
|
+
"dev": "tsx watch src/index.ts",
|
|
100
|
+
"build": "vite build && pnpm verify:css",
|
|
101
|
+
"verify:css": "tsx scripts/verify-css-build.ts",
|
|
102
|
+
"gen:cheatsheet": "tsx scripts/gen-cheatsheet.ts",
|
|
103
|
+
"start": "tsx src/index.ts"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import { configureAssetClient, createAssetHttpTransport, type AssetFetch } from './assetTransport'
|
|
3
|
+
import { createAssetClient } from './assets'
|
|
4
|
+
import type { ApiTransport } from '@bagelink/sdk'
|
|
5
|
+
import { createApp, ref } from 'vue'
|
|
6
|
+
|
|
7
|
+
const session = { asset_id: 'a', version_id: 'v', upload_id: 'u', status: 'ready' }
|
|
8
|
+
const json = (value: unknown, status = 200) => new Response(JSON.stringify(value), { status })
|
|
9
|
+
const signal = () => new AbortController().signal
|
|
10
|
+
|
|
11
|
+
describe('asset REST transport', () => {
|
|
12
|
+
it('reuses authenticated transport and synchronously invalidates on tenant changes', async () => {
|
|
13
|
+
const request = vi.fn().mockImplementation(() => new Promise(() => {}))
|
|
14
|
+
const transport = { axios: { defaults: { baseURL: 'https://api.example/api' }, request } } as unknown as ApiTransport
|
|
15
|
+
const sessionKey = ref('account:tenant-a')
|
|
16
|
+
const assets = configureAssetClient({ transport, sessionKey })
|
|
17
|
+
createApp({}).use(assets)
|
|
18
|
+
const result = assets.client.resolve({ asset_id: 'a', representation: 'website' })
|
|
19
|
+
const rejected = expect(result).rejects.toMatchObject({ name: 'AbortError' })
|
|
20
|
+
await Promise.resolve()
|
|
21
|
+
expect(request.mock.calls[0]![0].url).toBe('assets/resolve')
|
|
22
|
+
expect(JSON.parse(request.mock.calls[0]![0].data).references[0].representation).toBe('website')
|
|
23
|
+
sessionKey.value = 'account:tenant-b'
|
|
24
|
+
await rejected
|
|
25
|
+
expect(request.mock.calls[0]![0].signal.aborted).toBe(true)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('publishes only explicit image purposes with stable version-pinned URLs', async () => {
|
|
29
|
+
const fetcher = vi.fn<AssetFetch>().mockResolvedValue(json({
|
|
30
|
+
asset_id: 'a', version_id: 'v', published: true, name: 'photo',
|
|
31
|
+
representations: ['website', 'social'].map(representation => ({
|
|
32
|
+
representation, url: `/assets/a/public/v/${representation}`, media_type: 'image/jpeg', size: 42,
|
|
33
|
+
})),
|
|
34
|
+
}))
|
|
35
|
+
const transport = createAssetHttpTransport({ baseURL: 'https://api.example', fetch: fetcher })
|
|
36
|
+
const result = await transport.publish({ asset_id: 'a', version_id: 'v' })
|
|
37
|
+
expect(JSON.parse(String(fetcher.mock.calls[0]![1]?.body))).toEqual({
|
|
38
|
+
published: true, version_id: 'v', representations: ['website', 'social'],
|
|
39
|
+
})
|
|
40
|
+
expect(result.representations[1]?.url).toBe('https://api.example/assets/a/public/v/social')
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('rejects private grant URLs returned by publication', async () => {
|
|
44
|
+
const fetcher = vi.fn<AssetFetch>().mockResolvedValue(json({
|
|
45
|
+
asset_id: 'a', version_id: 'v', published: true,
|
|
46
|
+
representations: [{ representation: 'website', url: '/assets/a/content?token=secret' }],
|
|
47
|
+
}))
|
|
48
|
+
await expect(createAssetHttpTransport({ baseURL: 'https://api.example', fetch: fetcher })
|
|
49
|
+
.publish({ asset_id: 'a', version_id: 'v' })).rejects.toThrow('Invalid public')
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('starts a session and sends unchanged raw bytes, returning pinned references', async () => {
|
|
53
|
+
const fetcher = vi.fn<AssetFetch>().mockResolvedValueOnce(json(session)).mockResolvedValueOnce(json(session))
|
|
54
|
+
const transport = createAssetHttpTransport({ baseURL: 'https://api.example/api', fetch: fetcher })
|
|
55
|
+
const file = new File(['original'], 'test.heic')
|
|
56
|
+
expect(await transport.upload(file, signal())).toEqual({ asset_id: 'a', version_id: 'v' })
|
|
57
|
+
expect(String(fetcher.mock.calls[0]![0])).toBe('https://api.example/api/assets/uploads')
|
|
58
|
+
expect(fetcher.mock.calls[0]![1]?.body).toBe('{"name":"test.heic"}')
|
|
59
|
+
expect(fetcher.mock.calls[1]![1]?.body).toBe(file)
|
|
60
|
+
expect(new Headers(fetcher.mock.calls[1]![1]?.headers).get('Content-Type')).toBe('application/octet-stream')
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('fails closed for rejected completion and HTTP errors', async () => {
|
|
64
|
+
const fetcher = vi.fn<AssetFetch>().mockResolvedValueOnce(json(session))
|
|
65
|
+
.mockResolvedValueOnce(json({ ...session, status: 'rejected' })).mockResolvedValueOnce(json({}, 403))
|
|
66
|
+
const transport = createAssetHttpTransport({ baseURL: 'https://api.example', fetch: fetcher })
|
|
67
|
+
await expect(transport.upload(new File(['x'], 'x'), signal())).rejects.toThrow('not ready')
|
|
68
|
+
await expect(transport.resolve([{ asset_id: 'a' }], signal())).rejects.toThrow('(403)')
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('chunks 101 references and resolves relative URLs against the API origin', async () => {
|
|
72
|
+
const fetcher = vi.fn<AssetFetch>(async (_url, init) => {
|
|
73
|
+
const { references } = JSON.parse(String(init?.body)) as { references: { asset_id: string }[] }
|
|
74
|
+
return json({ items: references.map(reference => ({
|
|
75
|
+
...reference, version_id: 'v', representation: 'original',
|
|
76
|
+
url: '/assets/content?token=secret', expires_at: new Date(Date.now() + 60000).toISOString(),
|
|
77
|
+
})) })
|
|
78
|
+
})
|
|
79
|
+
const transport = createAssetHttpTransport({ baseURL: 'https://api.example', fetch: fetcher })
|
|
80
|
+
const items = await transport.resolve(Array.from({ length: 101 }, (_, i) => ({ asset_id: String(i) })), signal())
|
|
81
|
+
expect(fetcher.mock.calls.map(call => JSON.parse(String(call[1]?.body)).references.length)).toEqual([50, 50, 1])
|
|
82
|
+
expect(items).toHaveLength(101)
|
|
83
|
+
expect(items[0]?.url).toBe('https://api.example/assets/content?token=secret')
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('rejects untrusted delivery origins', async () => {
|
|
87
|
+
const fetcher = vi.fn<AssetFetch>().mockResolvedValue(json({ items: [{
|
|
88
|
+
asset_id: 'a', version_id: 'v', representation: 'original', url: '//evil.example/file',
|
|
89
|
+
}] }))
|
|
90
|
+
await expect(createAssetHttpTransport({ baseURL: 'https://api.example', fetch: fetcher })
|
|
91
|
+
.resolve([{ asset_id: 'a' }], signal())).rejects.toThrow('Untrusted')
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('does not PUT if session creation fails', async () => {
|
|
95
|
+
const fetcher = vi.fn<AssetFetch>().mockResolvedValueOnce(json({}, 503))
|
|
96
|
+
const transport = createAssetHttpTransport({ baseURL: 'https://api.example', fetch: fetcher })
|
|
97
|
+
await expect(transport.upload(new File(['x'], 'x'), signal())).rejects.toThrow('(503)')
|
|
98
|
+
expect(fetcher).toHaveBeenCalledTimes(1)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('does not complete an upload after session cancellation', async () => {
|
|
102
|
+
let finish!: (response: Response) => void
|
|
103
|
+
const fetcher = vi.fn<AssetFetch>().mockImplementationOnce(() => new Promise(resolve => { finish = resolve }))
|
|
104
|
+
const client = createAssetClient(createAssetHttpTransport({ baseURL: 'https://api.example', fetch: fetcher }))
|
|
105
|
+
const promise = client.upload(new File(['x'], 'x'))
|
|
106
|
+
client.clearSession()
|
|
107
|
+
finish(json(session))
|
|
108
|
+
await expect(promise).rejects.toMatchObject({ name: 'AbortError' })
|
|
109
|
+
expect(fetcher).toHaveBeenCalledTimes(1)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it('session cleanup aborts the HTTP request', async () => {
|
|
113
|
+
let requestSignal: AbortSignal | null | undefined
|
|
114
|
+
const fetcher = vi.fn<AssetFetch>((_url, init) => {
|
|
115
|
+
requestSignal = init?.signal
|
|
116
|
+
return new Promise((_resolve, reject) => requestSignal?.addEventListener('abort', () => reject(requestSignal?.reason)))
|
|
117
|
+
})
|
|
118
|
+
const client = createAssetClient(createAssetHttpTransport({ baseURL: 'https://api.example', fetch: fetcher }))
|
|
119
|
+
const promise = client.resolve({ asset_id: 'a' })
|
|
120
|
+
await Promise.resolve()
|
|
121
|
+
client.clearSession()
|
|
122
|
+
await expect(promise).rejects.toMatchObject({ name: 'AbortError' })
|
|
123
|
+
expect(requestSignal?.aborted).toBe(true)
|
|
124
|
+
})
|
|
125
|
+
})
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { createAssetClient, ASSET_CLIENT_KEY, type AssetDelivery, type AssetTransport, type AssetReference, type AssetPurpose } from './assets'
|
|
2
|
+
import type { ApiTransport } from '@bagelink/sdk'
|
|
3
|
+
import { watch, toValue, type App, type MaybeRefOrGetter } from 'vue'
|
|
4
|
+
|
|
5
|
+
export type AssetFetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>
|
|
6
|
+
|
|
7
|
+
export interface AssetHttpOptions {
|
|
8
|
+
/** Absolute API base, optionally with a path prefix. */
|
|
9
|
+
baseURL: string
|
|
10
|
+
headers?: () => HeadersInit
|
|
11
|
+
fetch?: AssetFetch
|
|
12
|
+
credentials?: RequestCredentials
|
|
13
|
+
/** Explicitly trusted delivery origins besides the API origin. */
|
|
14
|
+
deliveryOrigins?: string[]
|
|
15
|
+
/** Reuse the app's authenticated axios instance, including tenant interceptors. */
|
|
16
|
+
apiTransport?: ApiTransport
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface UploadResponse {
|
|
20
|
+
asset_id: string
|
|
21
|
+
version_id: string
|
|
22
|
+
upload_id: string
|
|
23
|
+
status: string
|
|
24
|
+
}
|
|
25
|
+
interface DeliveryResponse extends AssetDelivery {
|
|
26
|
+
asset_id: string
|
|
27
|
+
representation: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Concrete REST adapter, separate from generated SDK namespaces. */
|
|
31
|
+
export function createAssetHttpTransport(options: AssetHttpOptions): AssetTransport & {
|
|
32
|
+
publish(reference: Required<AssetReference>, signal?: AbortSignal): Promise<AssetPublication>
|
|
33
|
+
} {
|
|
34
|
+
const base = new URL(options.baseURL.endsWith('/') ? options.baseURL : `${options.baseURL}/`)
|
|
35
|
+
if (!['http:', 'https:'].includes(base.protocol) || base.username || base.password) throw new Error('Invalid API base')
|
|
36
|
+
const trusted = new Set([base.origin, ...(options.deliveryOrigins ?? []).map(origin => new URL(origin).origin)])
|
|
37
|
+
const request = options.fetch ?? globalThis.fetch
|
|
38
|
+
async function send<T>(path: string, init: RequestInit, signal: AbortSignal): Promise<T> {
|
|
39
|
+
signal.throwIfAborted()
|
|
40
|
+
const headers = new Headers(options.headers?.())
|
|
41
|
+
new Headers(init.headers).forEach((value, key) => headers.set(key, value))
|
|
42
|
+
if (options.apiTransport) {
|
|
43
|
+
const requestHeaders: Record<string, string> = {}
|
|
44
|
+
headers.forEach((value, key) => { requestHeaders[key] = value })
|
|
45
|
+
const response = await options.apiTransport.axios.request<T>({
|
|
46
|
+
url: `assets/${path}`, method: init.method, data: init.body,
|
|
47
|
+
headers: requestHeaders, signal,
|
|
48
|
+
})
|
|
49
|
+
signal.throwIfAborted()
|
|
50
|
+
return response.data
|
|
51
|
+
}
|
|
52
|
+
const response = await request(new URL(`assets/${path}`, base), {
|
|
53
|
+
...init, headers, signal, credentials: options.credentials ?? 'include', cache: 'no-store', redirect: 'error',
|
|
54
|
+
})
|
|
55
|
+
signal.throwIfAborted()
|
|
56
|
+
if (!response.ok) throw new Error(`Asset request failed (${response.status})`)
|
|
57
|
+
return await response.json() as T
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
async publish(reference: Required<AssetReference>, signal = new AbortController().signal): Promise<AssetPublication> {
|
|
61
|
+
const result = await send<AssetPublication>(`${encodeURIComponent(reference.asset_id)}/publication`, {
|
|
62
|
+
method: 'PUT', headers: { 'Content-Type': 'application/json' },
|
|
63
|
+
body: JSON.stringify({ published: true, version_id: reference.version_id, representations: ['website', 'social'] }),
|
|
64
|
+
}, signal)
|
|
65
|
+
if (result.asset_id !== reference.asset_id || result.version_id !== reference.version_id || !result.published) {
|
|
66
|
+
throw new Error('Mismatched asset publication')
|
|
67
|
+
}
|
|
68
|
+
for (const purpose of ['website', 'social'] as const) {
|
|
69
|
+
const item = result.representations.find(item => item.representation === purpose)
|
|
70
|
+
if (!item) throw new Error('Incomplete asset publication')
|
|
71
|
+
const url = new URL(item.url, base)
|
|
72
|
+
const suffix = `/assets/${encodeURIComponent(reference.asset_id)}/public/${encodeURIComponent(reference.version_id)}/${purpose}`
|
|
73
|
+
if (!trusted.has(url.origin) || !['http:', 'https:'].includes(url.protocol)
|
|
74
|
+
|| url.username || url.password || url.search || url.hash || !url.pathname.endsWith(suffix)) {
|
|
75
|
+
throw new Error('Invalid public asset URL')
|
|
76
|
+
}
|
|
77
|
+
item.url = url.href
|
|
78
|
+
}
|
|
79
|
+
return result
|
|
80
|
+
},
|
|
81
|
+
async upload(file, signal) {
|
|
82
|
+
const started = await send<UploadResponse>('uploads', {
|
|
83
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: file.name }),
|
|
84
|
+
}, signal)
|
|
85
|
+
if (!started.upload_id || !started.asset_id || !started.version_id) throw new Error('Invalid upload session')
|
|
86
|
+
const completed = await send<UploadResponse>(`uploads/${encodeURIComponent(started.upload_id)}`, {
|
|
87
|
+
method: 'PUT', headers: { 'Content-Type': 'application/octet-stream' }, body: file,
|
|
88
|
+
}, signal)
|
|
89
|
+
if (completed.status !== 'ready' || completed.asset_id !== started.asset_id
|
|
90
|
+
|| completed.version_id !== started.version_id || completed.upload_id !== started.upload_id) {
|
|
91
|
+
throw new Error('Asset upload is not ready')
|
|
92
|
+
}
|
|
93
|
+
return { asset_id: completed.asset_id, version_id: completed.version_id }
|
|
94
|
+
},
|
|
95
|
+
async resolve(references, signal) {
|
|
96
|
+
const result: AssetDelivery[] = []
|
|
97
|
+
for (let offset = 0; offset < references.length; offset += 50) {
|
|
98
|
+
const chunk = references.slice(offset, offset + 50)
|
|
99
|
+
const response = await send<{ items: DeliveryResponse[] }>('resolve', {
|
|
100
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ references: chunk }),
|
|
101
|
+
}, signal)
|
|
102
|
+
if (!Array.isArray(response.items) || response.items.length !== chunk.length) throw new Error('Incomplete delivery response')
|
|
103
|
+
for (const reference of chunk) {
|
|
104
|
+
const item = response.items.find(candidate => candidate.asset_id === reference.asset_id
|
|
105
|
+
&& (!reference.version_id || candidate.version_id === reference.version_id)
|
|
106
|
+
&& candidate.representation === (reference.representation ?? 'original'))
|
|
107
|
+
if (!item) throw new Error('Mismatched delivery response')
|
|
108
|
+
const url = new URL(item.url, base)
|
|
109
|
+
if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password
|
|
110
|
+
|| !trusted.has(url.origin)) throw new Error('Untrusted asset delivery URL')
|
|
111
|
+
result.push({ url: url.href, version_id: item.version_id, expires_at: item.expires_at })
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return result
|
|
115
|
+
},
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Public URLs are deliberately separate from expiring private deliveries. */
|
|
120
|
+
export interface AssetPublication {
|
|
121
|
+
asset_id: string
|
|
122
|
+
name: string
|
|
123
|
+
version_id: string
|
|
124
|
+
published: boolean
|
|
125
|
+
representations: { representation: AssetPurpose; url: string; media_type: string; size: number }[]
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface ConfigureAssetClientOptions {
|
|
129
|
+
transport: ApiTransport
|
|
130
|
+
/** Existing reactive identity/session + tenant key. Never inferred from auth globals. */
|
|
131
|
+
sessionKey: MaybeRefOrGetter<string | undefined>
|
|
132
|
+
deliveryOrigins?: string[]
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Vue plugin; owns its session watcher and clears on app teardown. */
|
|
136
|
+
export function configureAssetClient(options: ConfigureAssetClientOptions) {
|
|
137
|
+
const baseURL = options.transport.axios.defaults.baseURL
|
|
138
|
+
if (!baseURL) throw new Error('Asset transport needs an API baseURL')
|
|
139
|
+
const transport = createAssetHttpTransport({
|
|
140
|
+
baseURL: new URL(baseURL, typeof location === 'undefined' ? undefined : location.origin).href,
|
|
141
|
+
apiTransport: options.transport, deliveryOrigins: options.deliveryOrigins,
|
|
142
|
+
})
|
|
143
|
+
const client = createAssetClient(transport)
|
|
144
|
+
const publications = new Set<AbortController>()
|
|
145
|
+
const clearSession = () => {
|
|
146
|
+
client.clearSession()
|
|
147
|
+
for (const controller of publications) controller.abort()
|
|
148
|
+
publications.clear()
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
client,
|
|
152
|
+
async publish(reference: Required<AssetReference>) {
|
|
153
|
+
const controller = new AbortController()
|
|
154
|
+
publications.add(controller)
|
|
155
|
+
try { return await transport.publish(reference, controller.signal) }
|
|
156
|
+
finally { publications.delete(controller) }
|
|
157
|
+
},
|
|
158
|
+
install(app: App) {
|
|
159
|
+
app.provide(ASSET_CLIENT_KEY, client)
|
|
160
|
+
const stop = watch(() => toValue(options.sessionKey), clearSession, { flush: 'sync' })
|
|
161
|
+
app.onUnmount(() => { stop(); clearSession() })
|
|
162
|
+
},
|
|
163
|
+
}
|
|
164
|
+
}
|