storyloco 1.15.2 → 2.0.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/README.md +81 -13
- package/package.json +27 -15
- package/packages/asset/r2.ts +217 -0
- package/packages/asset/types.ts +1 -1
- package/packages/hubspot_form/types.ts +4 -0
- package/packages/mux/types.ts +65 -2
- package/packages/shared/dist/components/ui/textarea/textarea.svelte +1 -2
- package/packages/shared/dist/global.css +1 -1
- package/packages/vite/dist/hooks.d.ts +8 -0
- package/packages/vite/dist/hooks.js +11 -0
- package/packages/vite/dist/schema/plugin.js +26 -2
- package/packages/vite/dist/server.d.ts +51 -0
- package/packages/vite/dist/server.js +76 -0
- package/packages/vite/dist/storyblok.svelte.d.ts +125 -9
- package/packages/vite/dist/storyblok.svelte.js +133 -23
- package/packages/shared/dist/components/ui/dropdown-menu/index.d.ts +0 -25
- package/packages/vite/dist/components.schema.d.ts +0 -475
- package/packages/vite/dist/components.schema.js +0 -6
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ A collection of slick Storyblok field plugins built with Svelte 5, TypeScript, a
|
|
|
24
24
|
### Storyblok Client
|
|
25
25
|
|
|
26
26
|
- **🎯 StoryblokClient** - Reactive wrapper for Storyblok with Svelte 5 integration
|
|
27
|
-
- **🔧 Utilities** -
|
|
27
|
+
- **🔧 Utilities** - `attrs` for wiring a block to the visual editor, plus re-exported `editable`, `Block`, and `richtext` functions
|
|
28
28
|
|
|
29
29
|
### Shared Components
|
|
30
30
|
|
|
@@ -68,18 +68,20 @@ import type { Video, Heading, Link, Input, Asset, SEO } from 'storyloco'
|
|
|
68
68
|
import { StoryblokClient } from 'storyloco'
|
|
69
69
|
import { PUBLIC_STORYBLOK_ACCESS_TOKEN } from '$env/static/public'
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
export const client = new StoryblokClient({
|
|
72
|
+
token: PUBLIC_STORYBLOK_ACCESS_TOKEN,
|
|
73
|
+
relations: ['shared.items'],
|
|
74
|
+
components: import.meta.glob(['$blocks/**/*.svelte', '$templates/*.svelte'])
|
|
75
|
+
})
|
|
76
|
+
```
|
|
73
77
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
)
|
|
78
|
+
Everything is configured here rather than by subclassing, and `init()` runs on its own — the
|
|
79
|
+
API methods await it, so you never call it on the server. `components` takes the result of
|
|
80
|
+
`import.meta.glob`: Vite has to see the literal pattern to rewrite it, so the glob has to stay
|
|
81
|
+
at your call site rather than move into the client.
|
|
79
82
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
+
`client.handle_error` is on the instance, so `.catch(client.handle_error)` works without
|
|
84
|
+
wrapping anything.
|
|
83
85
|
|
|
84
86
|
#### 2. Use in your Svelte components
|
|
85
87
|
|
|
@@ -108,7 +110,7 @@ export const client = new StoryblokClient(PUBLIC_STORYBLOK_ACCESS_TOKEN, import.
|
|
|
108
110
|
|
|
109
111
|
```svelte
|
|
110
112
|
<script lang="ts">
|
|
111
|
-
import {
|
|
113
|
+
import { attrs } from 'storyloco'
|
|
112
114
|
|
|
113
115
|
// This is auto-generated by the Storyblok Schema plugin
|
|
114
116
|
import type { Blok, Hero } from '$lib/components.schema.js'
|
|
@@ -120,12 +122,78 @@ export const client = new StoryblokClient(PUBLIC_STORYBLOK_ACCESS_TOKEN, import.
|
|
|
120
122
|
let { blok } = $props()
|
|
121
123
|
</script>
|
|
122
124
|
|
|
123
|
-
<section
|
|
125
|
+
<section {...attrs(blok)}>
|
|
124
126
|
<h1>{blok.headline}</h1>
|
|
125
127
|
<p>{blok.subheadline}</p>
|
|
126
128
|
</section>
|
|
127
129
|
```
|
|
128
130
|
|
|
131
|
+
`attrs` makes the block editable in the visual editor and gives it a stable `id` — the
|
|
132
|
+
block's `anchor` field when it has one, so sections can be linked to, otherwise its `_uid`.
|
|
133
|
+
|
|
134
|
+
Prefer it to `use:editable`. Being an attachment rather than an action it spreads, so the
|
|
135
|
+
element keeps its own attributes, and you can wrap it to add project-specific ones in one
|
|
136
|
+
place rather than repeating them in every block:
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
// Mapping section fields onto CSS custom properties is left to you — the field names and
|
|
140
|
+
// the design tokens are yours. Wrap `attrs` rather than reaching past it:
|
|
141
|
+
//
|
|
142
|
+
// export function section<T extends SectionFields>(blok: Blok<T>) {
|
|
143
|
+
// let style = ''
|
|
144
|
+
// if (blok.theme) style += `--theme: var(--c-${blok.theme});`
|
|
145
|
+
// if (blok.pad_top) style += `--pt: var(--s-${blok.pad_top});`
|
|
146
|
+
// return { ...attrs(blok), style }
|
|
147
|
+
// }
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`editable` is still exported for anything `attrs` doesn't cover.
|
|
151
|
+
|
|
152
|
+
### Read Content on the Server
|
|
153
|
+
|
|
154
|
+
`storyloco/server` binds a client to the current request, so reads carry the version from
|
|
155
|
+
the `version` hook and the resolve options you'd otherwise repeat everywhere. Server-only,
|
|
156
|
+
since it reads the active request.
|
|
157
|
+
|
|
158
|
+
**`$lib/storyblok.server.ts`:**
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
import { setup } from 'storyloco/server'
|
|
162
|
+
import { client } from './storyblok.js'
|
|
163
|
+
|
|
164
|
+
export const storyblok = setup(client)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Then anywhere on the server:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { storyblok } from '$lib/storyblok.server.js'
|
|
171
|
+
|
|
172
|
+
// A single story, with the client's `relations` resolved
|
|
173
|
+
await storyblok.story('layout')
|
|
174
|
+
|
|
175
|
+
// A list. `total` is the unpaged count, for "showing n of m"
|
|
176
|
+
const { stories, total } = await storyblok.stories({ content_type: 'blog', per_page: 2 })
|
|
177
|
+
|
|
178
|
+
// The link tree, flattened — Storyblok returns it keyed by uuid
|
|
179
|
+
const links = await storyblok.links({ starts_with: 'blog/' })
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Your params are spread last, so any default can be overridden:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
await storyblok.story('layout', { resolve_assets: 0 })
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
It's callable too, for anything the methods don't cover:
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
const { client, version } = storyblok()
|
|
192
|
+
await client.get('cdn/datasource_entries', { version })
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Errors go through `handle_error`, so a missing story is a 404 and anything else a 500.
|
|
196
|
+
|
|
129
197
|
### Use Shared Components
|
|
130
198
|
|
|
131
199
|
```typescript
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "storyloco",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A collection of slick Storyblok field plugins built with Svelte 5, TypeScript, and Tailwind CSS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"storyblok",
|
|
@@ -25,13 +25,15 @@
|
|
|
25
25
|
"packages/plans/types.ts",
|
|
26
26
|
"packages/link/types.ts",
|
|
27
27
|
"packages/asset/types.ts",
|
|
28
|
+
"packages/asset/r2.ts",
|
|
28
29
|
"packages/theme/types.ts",
|
|
29
30
|
"packages/shared/dist",
|
|
30
31
|
"packages/vite/dist",
|
|
31
32
|
"packages/ticketsource/types.ts",
|
|
32
33
|
"packages/input/types.ts",
|
|
33
34
|
"packages/time/types.ts",
|
|
34
|
-
"packages/seo/types.ts"
|
|
35
|
+
"packages/seo/types.ts",
|
|
36
|
+
"packages/hubspot_form/types.ts"
|
|
35
37
|
],
|
|
36
38
|
"exports": {
|
|
37
39
|
".": {
|
|
@@ -77,27 +79,38 @@
|
|
|
77
79
|
"types": "./packages/vite/dist/hooks.d.ts",
|
|
78
80
|
"import": "./packages/vite/dist/hooks.js"
|
|
79
81
|
},
|
|
82
|
+
"./server": {
|
|
83
|
+
"types": "./packages/vite/dist/server.d.ts",
|
|
84
|
+
"import": "./packages/vite/dist/server.js"
|
|
85
|
+
},
|
|
80
86
|
"./time": {
|
|
81
87
|
"types": "./packages/time/types.ts",
|
|
82
88
|
"svelte": "./packages/time/src/app.svelte.ts"
|
|
83
89
|
},
|
|
84
90
|
"./seo": {
|
|
85
91
|
"types": "./packages/seo/types.ts"
|
|
92
|
+
},
|
|
93
|
+
"./hubspot_form": {
|
|
94
|
+
"types": "./packages/hubspot_form/types.ts",
|
|
95
|
+
"svelte": "./packages/hubspot_form/src/app.svelte.ts"
|
|
86
96
|
}
|
|
87
97
|
},
|
|
88
98
|
"devDependencies": {
|
|
89
|
-
"@types/node": "
|
|
90
|
-
"@typescript-eslint/eslint-plugin": "8.
|
|
91
|
-
"@typescript-eslint/parser": "8.
|
|
92
|
-
"eslint": "
|
|
93
|
-
"kitto": "1.
|
|
94
|
-
"
|
|
95
|
-
"
|
|
99
|
+
"@types/node": "26.1.1",
|
|
100
|
+
"@typescript-eslint/eslint-plugin": "8.65.0",
|
|
101
|
+
"@typescript-eslint/parser": "8.65.0",
|
|
102
|
+
"eslint": "10.7.0",
|
|
103
|
+
"kitto": "1.6.0",
|
|
104
|
+
"oxfmt": "0.59.0",
|
|
105
|
+
"typescript": "6.0.3",
|
|
106
|
+
"vite": "8.1.5"
|
|
96
107
|
},
|
|
97
108
|
"peerDependencies": {
|
|
98
|
-
"@storyblok/svelte": "
|
|
99
|
-
"@storyblok/field-plugin": "^1.
|
|
100
|
-
"svelte": "^5.0.0"
|
|
109
|
+
"@storyblok/svelte": "7.2.2",
|
|
110
|
+
"@storyblok/field-plugin": "^1.7.1",
|
|
111
|
+
"svelte": "^5.0.0",
|
|
112
|
+
"@sveltejs/kit": "^2.0.0",
|
|
113
|
+
"storyblok-js-client": "^7.0.0"
|
|
101
114
|
},
|
|
102
115
|
"scripts": {
|
|
103
116
|
"add-plugin": "npx @storyblok/field-plugin-cli@latest add --dir \"./packages\" --structure monorepo",
|
|
@@ -110,8 +123,7 @@
|
|
|
110
123
|
"packages/*"
|
|
111
124
|
],
|
|
112
125
|
"dependencies": {
|
|
113
|
-
"ora": "9.
|
|
114
|
-
"
|
|
115
|
-
"path-to-regexp": "8.3.0"
|
|
126
|
+
"ora": "9.4.1",
|
|
127
|
+
"path-to-regexp": "8.4.2"
|
|
116
128
|
}
|
|
117
129
|
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored subset of the `moxyloco/r2` types.
|
|
3
|
+
*
|
|
4
|
+
* These are hand-copied from the moxy R2 OpenAPI client so storyloco consumers
|
|
5
|
+
* don't need `moxyloco` (and its `openapi-client-axios` dependency) installed
|
|
6
|
+
* just to read the asset field-plugin types. Only the schemas and operations the
|
|
7
|
+
* plugin actually uses are modelled here.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/* Asset resource in JSON:API format */
|
|
11
|
+
export interface R2Asset {
|
|
12
|
+
/* Resource type */
|
|
13
|
+
type: 'asset'
|
|
14
|
+
|
|
15
|
+
/* Unique asset identifier (uuid) */
|
|
16
|
+
id: string
|
|
17
|
+
|
|
18
|
+
attributes: R2AssetAttributes
|
|
19
|
+
|
|
20
|
+
links?: {
|
|
21
|
+
/* URL to this asset */
|
|
22
|
+
self?: string
|
|
23
|
+
|
|
24
|
+
/* Public URL for accessing the asset */
|
|
25
|
+
public?: string
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* Asset attributes */
|
|
30
|
+
export interface R2AssetAttributes {
|
|
31
|
+
/* Original filename */
|
|
32
|
+
filename: string
|
|
33
|
+
|
|
34
|
+
/* Display name for the asset (can be different from filename) */
|
|
35
|
+
name?: string
|
|
36
|
+
|
|
37
|
+
/* File size in bytes */
|
|
38
|
+
size_bytes: number
|
|
39
|
+
|
|
40
|
+
/* MIME type of the file */
|
|
41
|
+
content_type?: string
|
|
42
|
+
|
|
43
|
+
/* Detected file format (e.g. "jpeg", "png") */
|
|
44
|
+
format?: string
|
|
45
|
+
|
|
46
|
+
/* Image width in pixels (for images) */
|
|
47
|
+
width?: number
|
|
48
|
+
|
|
49
|
+
/* Image height in pixels (for images) */
|
|
50
|
+
height?: number
|
|
51
|
+
|
|
52
|
+
/* When the asset was uploaded (date-time) */
|
|
53
|
+
created_at: string
|
|
54
|
+
|
|
55
|
+
/* Title for the asset */
|
|
56
|
+
title?: string
|
|
57
|
+
|
|
58
|
+
/* Alt text for accessibility */
|
|
59
|
+
alt?: string
|
|
60
|
+
|
|
61
|
+
/* Source attribution */
|
|
62
|
+
source?: string
|
|
63
|
+
|
|
64
|
+
/* Copyright information */
|
|
65
|
+
copyright?: string
|
|
66
|
+
|
|
67
|
+
/* Focus point for image cropping */
|
|
68
|
+
focus?: string
|
|
69
|
+
|
|
70
|
+
/* Whether the asset is soft-deleted */
|
|
71
|
+
deleted?: boolean
|
|
72
|
+
|
|
73
|
+
/* When the asset was deleted, if applicable (date-time) */
|
|
74
|
+
deleted_at?: string | null
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* Folder resource in JSON:API format */
|
|
78
|
+
export interface R2Folder {
|
|
79
|
+
/* Resource type */
|
|
80
|
+
type: 'folder'
|
|
81
|
+
|
|
82
|
+
/* Unique folder identifier (uuid) */
|
|
83
|
+
id: string
|
|
84
|
+
|
|
85
|
+
attributes: R2FolderAttributes
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* Folder attributes */
|
|
89
|
+
export interface R2FolderAttributes {
|
|
90
|
+
/* Folder name */
|
|
91
|
+
name: string
|
|
92
|
+
|
|
93
|
+
/* UUID of parent folder (null for root folders) */
|
|
94
|
+
parent_id?: string | null
|
|
95
|
+
|
|
96
|
+
/* Number of assets in this folder */
|
|
97
|
+
asset_count: number
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* Structured folder tree format with unlimited nesting */
|
|
101
|
+
export interface R2FolderTree {
|
|
102
|
+
/* Folder name */
|
|
103
|
+
name: string
|
|
104
|
+
|
|
105
|
+
/* Folder UUID */
|
|
106
|
+
id: string
|
|
107
|
+
|
|
108
|
+
/* UUID of parent folder (null for root folders) */
|
|
109
|
+
parent_id?: string | null
|
|
110
|
+
|
|
111
|
+
/* Number of assets in this folder */
|
|
112
|
+
asset_count: number
|
|
113
|
+
|
|
114
|
+
/* Child folders (recursive) */
|
|
115
|
+
children: Array<R2FolderTree>
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* Request/response shapes for the R2 operations the plugin calls */
|
|
119
|
+
export namespace Paths {
|
|
120
|
+
export namespace ListAssets {
|
|
121
|
+
export namespace Responses {
|
|
122
|
+
export interface $200 {
|
|
123
|
+
data?: Array<R2Asset>
|
|
124
|
+
included?: Array<R2Folder>
|
|
125
|
+
meta?: {
|
|
126
|
+
page?: number
|
|
127
|
+
limit?: number
|
|
128
|
+
total?: number
|
|
129
|
+
total_pages?: number
|
|
130
|
+
}
|
|
131
|
+
links?: {
|
|
132
|
+
self?: string
|
|
133
|
+
next?: string
|
|
134
|
+
prev?: string
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export namespace UpdateAssetsBulk {
|
|
141
|
+
export interface RequestBody {
|
|
142
|
+
/* Array of asset UUIDs to update */
|
|
143
|
+
assets: Array<string>
|
|
144
|
+
metadata: {
|
|
145
|
+
name?: string
|
|
146
|
+
alt?: string
|
|
147
|
+
title?: string
|
|
148
|
+
source?: string
|
|
149
|
+
copyright?: string
|
|
150
|
+
focus?: string
|
|
151
|
+
/* UUID of the folder to move the assets to (null for no folder) */
|
|
152
|
+
folder_id?: string | null
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export namespace Responses {
|
|
157
|
+
export type $204 = Record<string, never>
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export namespace UpdateAssetMetadata {
|
|
162
|
+
export interface RequestBody {
|
|
163
|
+
name?: string
|
|
164
|
+
alt?: string
|
|
165
|
+
title?: string
|
|
166
|
+
source?: string
|
|
167
|
+
copyright?: string
|
|
168
|
+
focus?: string
|
|
169
|
+
/* UUID of the folder to move the asset to (null for no folder) */
|
|
170
|
+
folder_id?: string | null
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export namespace Responses {
|
|
174
|
+
export interface $200 {
|
|
175
|
+
data?: R2Asset
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export namespace CreateFolder {
|
|
181
|
+
export interface RequestBody {
|
|
182
|
+
/* Folder name */
|
|
183
|
+
name: string
|
|
184
|
+
|
|
185
|
+
/* UUID of parent folder (null for root folders) */
|
|
186
|
+
parent_id?: string | null
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export namespace Responses {
|
|
190
|
+
export interface $201 {
|
|
191
|
+
data?: R2Folder
|
|
192
|
+
meta?: {
|
|
193
|
+
/* Indicates the folder was created */
|
|
194
|
+
created?: boolean
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export namespace ListFolders {
|
|
201
|
+
export namespace Responses {
|
|
202
|
+
export interface $200 {
|
|
203
|
+
data?: {
|
|
204
|
+
/* JSON:API format folder list */
|
|
205
|
+
list?: Array<R2Folder>
|
|
206
|
+
|
|
207
|
+
/* Structured tree format for easier frontend consumption */
|
|
208
|
+
structured?: Array<R2FolderTree>
|
|
209
|
+
}
|
|
210
|
+
meta?: {
|
|
211
|
+
/* Total number of folders */
|
|
212
|
+
total?: number
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
package/packages/asset/types.ts
CHANGED
package/packages/mux/types.ts
CHANGED
|
@@ -1,7 +1,70 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Vendored subset of the Mux `Asset` type (previously from `@mux/mux-node`).
|
|
3
|
+
* Kept self-contained so consumers don't need the Mux SDK installed just to read
|
|
4
|
+
* these types. Only the fields the plugin actually touches are modelled — the real
|
|
5
|
+
* SDK `Asset` remains structurally assignable to this.
|
|
6
|
+
*/
|
|
7
|
+
export interface MuxPlaybackID {
|
|
8
|
+
/* Unique identifier for the PlaybackID */
|
|
9
|
+
id: string
|
|
10
|
+
|
|
11
|
+
/* How the playback ID is secured */
|
|
12
|
+
policy: 'public' | 'signed' | 'drm'
|
|
13
|
+
|
|
14
|
+
/* DRM configuration used by this playback ID (only when `policy` is `drm`) */
|
|
15
|
+
drm_configuration_id?: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface MuxAssetErrors {
|
|
19
|
+
/* Error messages with more details */
|
|
20
|
+
messages?: Array<string>
|
|
21
|
+
|
|
22
|
+
/* The type of error that occurred for this asset */
|
|
23
|
+
type?: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface MuxAssetMeta {
|
|
27
|
+
/* Identifier for the creator of the asset */
|
|
28
|
+
creator_id?: string
|
|
29
|
+
|
|
30
|
+
/* Identifier linking the asset to your own data */
|
|
31
|
+
external_id?: string
|
|
32
|
+
|
|
33
|
+
/* The asset title */
|
|
34
|
+
title?: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface MuxAsset {
|
|
38
|
+
/* Unique identifier for the Asset */
|
|
39
|
+
id: string
|
|
40
|
+
|
|
41
|
+
/* Time the Asset was created (Unix timestamp, seconds since epoch) */
|
|
42
|
+
created_at: string
|
|
43
|
+
|
|
44
|
+
/* The status of the asset */
|
|
45
|
+
status: 'preparing' | 'ready' | 'errored'
|
|
46
|
+
|
|
47
|
+
/* Object describing any errors that happened when processing this asset */
|
|
48
|
+
errors?: MuxAssetErrors
|
|
49
|
+
|
|
50
|
+
/* The aspect ratio of the asset in the form `width:height` (e.g. `16:9`) */
|
|
51
|
+
aspect_ratio?: string
|
|
52
|
+
|
|
53
|
+
/* The duration of the asset in seconds */
|
|
54
|
+
duration?: number
|
|
55
|
+
|
|
56
|
+
/* Playback ID objects used to build HLS playback URLs */
|
|
57
|
+
playback_ids?: Array<MuxPlaybackID>
|
|
58
|
+
|
|
59
|
+
/* Customer provided metadata about this asset */
|
|
60
|
+
meta?: MuxAssetMeta
|
|
61
|
+
|
|
62
|
+
/* Arbitrary passthrough value included in the asset details and webhooks */
|
|
63
|
+
passthrough?: string
|
|
64
|
+
}
|
|
2
65
|
|
|
3
66
|
export interface Video {
|
|
4
|
-
mux_video?:
|
|
67
|
+
mux_video?: MuxAsset
|
|
5
68
|
playback_id?: string
|
|
6
69
|
m3u8_url?: string
|
|
7
70
|
title?: string
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
|
|
55
55
|
[data-theme='dark'] {
|
|
56
56
|
--teal-muted: oklch(74.591% 0.11569 187.182);
|
|
57
|
-
--background:
|
|
57
|
+
--background: #333338;
|
|
58
58
|
--foreground: oklch(0.984 0.003 247.858);
|
|
59
59
|
--card: oklch(26.239% 0.00928 285.704);
|
|
60
60
|
--card-foreground: oklch(0.984 0.003 247.858);
|
|
@@ -1 +1,9 @@
|
|
|
1
|
+
import type { Handle } from "@sveltejs/kit";
|
|
1
2
|
export { handle_redirects as redirects } from "./redirects/handle.js";
|
|
3
|
+
/**
|
|
4
|
+
* Put the Storyblok content version on `event.locals.version` — draft while developing and
|
|
5
|
+
* inside the visual editor (`?_storyblok`), published everywhere else.
|
|
6
|
+
*
|
|
7
|
+
* Declare it on `App.Locals` as `version: import("storyloco").Version`.
|
|
8
|
+
*/
|
|
9
|
+
export declare const version: Handle;
|
|
@@ -1 +1,12 @@
|
|
|
1
|
+
import { dev } from "$app/environment";
|
|
1
2
|
export { handle_redirects as redirects } from "./redirects/handle.js";
|
|
3
|
+
/**
|
|
4
|
+
* Put the Storyblok content version on `event.locals.version` — draft while developing and
|
|
5
|
+
* inside the visual editor (`?_storyblok`), published everywhere else.
|
|
6
|
+
*
|
|
7
|
+
* Declare it on `App.Locals` as `version: import("storyloco").Version`.
|
|
8
|
+
*/
|
|
9
|
+
export const version = async ({ event, resolve }) => {
|
|
10
|
+
event.locals.version = dev || event.url.searchParams.has("_storyblok") ? "draft" : "published";
|
|
11
|
+
return await resolve(event);
|
|
12
|
+
};
|
|
@@ -4,9 +4,33 @@ import path from "node:path";
|
|
|
4
4
|
import { $ } from "../shared/shell.js";
|
|
5
5
|
import exec from "../shared/x.js";
|
|
6
6
|
import { Logger } from "../shared/logger.js";
|
|
7
|
-
import { format } from "oxfmt";
|
|
8
7
|
const name = "vite-storyblok-schema";
|
|
9
8
|
const logger = new Logger(name);
|
|
9
|
+
/**
|
|
10
|
+
* Formats generated code as a nicety, not a necessity. Prefers oxfmt if it's
|
|
11
|
+
* installed, falls back to prettier if that happens to be around, and otherwise
|
|
12
|
+
* leaves the code untouched. Never throws — formatting is entirely optional and
|
|
13
|
+
* these tools are intentionally not hard dependencies.
|
|
14
|
+
*/
|
|
15
|
+
async function format_code(filename, content) {
|
|
16
|
+
try {
|
|
17
|
+
const oxfmt = await import("oxfmt");
|
|
18
|
+
const { code } = await oxfmt.format(filename, content);
|
|
19
|
+
return code;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
/* oxfmt not available — try the next option */
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const specifier = "prettier";
|
|
26
|
+
const prettier = await import(specifier);
|
|
27
|
+
return await prettier.format(content, { filepath: filename });
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
/* prettier not available either — leave the code as-is */
|
|
31
|
+
}
|
|
32
|
+
return content;
|
|
33
|
+
}
|
|
10
34
|
/**
|
|
11
35
|
* @remarks
|
|
12
36
|
* Vite plugin that automatically regenerates Storyblok component types at regular intervals
|
|
@@ -176,7 +200,7 @@ import type { ISbStoryData } from '@storyblok/js';`, "");
|
|
|
176
200
|
content = content.replace(/any\[]/g, "unknown[]");
|
|
177
201
|
// Make _uid and component optional (helps us reuse Storyblok types for non-storyblok components)
|
|
178
202
|
content = content.replace(/^([a-zA-Z0-9_]+):/gm, "$1?:");
|
|
179
|
-
const
|
|
203
|
+
const formatted = await format_code(path.basename(schema_ts_file), content);
|
|
180
204
|
// Write the final file
|
|
181
205
|
logger.start("Finalising schema file...");
|
|
182
206
|
await writeFile(schema_ts_file, formatted);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ISbStoriesParams, ISbStoryData, ISbStoryParams } from "@storyblok/svelte";
|
|
2
|
+
import type { ISbLink, ISbLinksParams } from "storyblok-js-client";
|
|
3
|
+
import { type StoryblokClient, type Version } from "./storyblok.svelte.js";
|
|
4
|
+
/** The content version for the current request, as set by the `version` hook. */
|
|
5
|
+
export declare function version(): Version;
|
|
6
|
+
/**
|
|
7
|
+
* Bind a client to the current request.
|
|
8
|
+
*
|
|
9
|
+
* Returns a callable: call it for the client and version to reach anything the methods
|
|
10
|
+
* don't cover, or use `.story` / `.stories` for the common reads. Those carry the
|
|
11
|
+
* request's version and the resolve options a Storyblok read almost always wants; the
|
|
12
|
+
* caller's params are spread last, so every default can be overridden. `resolve_links`
|
|
13
|
+
* is on because `href` depends on it.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* // $lib/storyblok.server.ts
|
|
18
|
+
* export const storyblok = setup(client)
|
|
19
|
+
*
|
|
20
|
+
* // anywhere on the server
|
|
21
|
+
* await storyblok.story("layout")
|
|
22
|
+
* await storyblok.stories<Blog>({ content_type: "blog", per_page: 2 })
|
|
23
|
+
*
|
|
24
|
+
* const { client, version } = storyblok()
|
|
25
|
+
* await client.get("cdn/links", { version })
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function setup(client: StoryblokClient): (() => {
|
|
29
|
+
client: StoryblokClient;
|
|
30
|
+
version: Version;
|
|
31
|
+
}) & {
|
|
32
|
+
/**
|
|
33
|
+
* A single story by full slug. Resolves the client's `relations`, unlike `stories`.
|
|
34
|
+
*
|
|
35
|
+
* `T` is the story's content type; it defaults to the SDK's permissive one, so an
|
|
36
|
+
* unparameterised call behaves as before.
|
|
37
|
+
*/
|
|
38
|
+
story<T = import("storyblok-js-client").ISbComponentType<string> & {
|
|
39
|
+
[index: string]: any;
|
|
40
|
+
}>(slug: string, params?: ISbStoryParams): Promise<ISbStoryData<T>>;
|
|
41
|
+
/**
|
|
42
|
+
* The link tree as a flat array — Storyblok returns it keyed by uuid, which is
|
|
43
|
+
* almost never what you want. Filtering and ordering are left to the caller.
|
|
44
|
+
*/
|
|
45
|
+
links(params?: ISbLinksParams): Promise<ISbLink[]>;
|
|
46
|
+
/** A list of stories. `total` is the unpaged count, for "showing n of m". */
|
|
47
|
+
stories<T>(params?: ISbStoriesParams): Promise<{
|
|
48
|
+
stories: Array<ISbStoryData<T>>;
|
|
49
|
+
total: number;
|
|
50
|
+
}>;
|
|
51
|
+
};
|