@se-studio/core-data-types 0.1.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 ADDED
@@ -0,0 +1,137 @@
1
+ # @se-studio/core-data-types
2
+
3
+ Core TypeScript type definitions for SE Studio content models and shared types across the monorepo.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # pnpm
9
+ pnpm add @se-studio/core-data-types
10
+
11
+ # npm
12
+ npm install @se-studio/core-data-types
13
+
14
+ # yarn
15
+ yarn add @se-studio/core-data-types
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ ```typescript
21
+ import type { IPage, ISeoMetadata, IAsset, DeepPartial } from '@se-studio/core-data-types';
22
+
23
+ // Use the page interface
24
+ const page: IPage = {
25
+ id: 'page-123',
26
+ slug: 'about-us',
27
+ title: 'About Us',
28
+ seo: {
29
+ title: 'About Us - SE Studio',
30
+ description: 'Learn more about SE Studio',
31
+ },
32
+ };
33
+
34
+ // Use utility types
35
+ type PartialPage = DeepPartial<IPage>;
36
+ ```
37
+
38
+ ## API Overview
39
+
40
+ ### Page Types
41
+
42
+ - **`IPage`** - Base interface for page content models
43
+ - `id: string` - Unique identifier
44
+ - `slug: string` - URL-friendly slug
45
+ - `title: string` - Page title
46
+ - `seo?: ISeoMetadata` - Optional SEO metadata
47
+ - `publishedAt?: string` - Publication date
48
+ - `updatedAt?: string` - Last updated date
49
+ - `locale?: string` - Content locale
50
+ - `sections?: unknown[]` - Content sections (to be defined)
51
+
52
+ - **`IPageMetadata`** - Page metadata without content sections
53
+
54
+ ### Common Types
55
+
56
+ - **`ISeoMetadata`** - SEO metadata structure
57
+ - `title?: string`
58
+ - `description?: string`
59
+ - `keywords?: string[]`
60
+ - `ogImage?: string`
61
+ - `noIndex?: boolean`
62
+ - `canonicalUrl?: string`
63
+
64
+ - **`IAsset`** - Image/media asset structure
65
+ - `url: string`
66
+ - `title?: string`
67
+ - `description?: string`
68
+ - `width?: number`
69
+ - `height?: number`
70
+ - `contentType?: string`
71
+
72
+ - **`ILink`** - Link/reference structure
73
+ - `text: string`
74
+ - `url: string`
75
+ - `target?: '_blank' | '_self'`
76
+ - `ariaLabel?: string`
77
+
78
+ ### Utility Types
79
+
80
+ - **`DeepPartial<T>`** - Makes all nested properties optional
81
+ - **`Prettify<T>`** - Improves type readability in IDE tooltips
82
+
83
+ ## Development
84
+
85
+ This package is part of the SE Studio monorepo. To work on this package:
86
+
87
+ ```bash
88
+ # Install dependencies
89
+ pnpm install
90
+
91
+ # Build the package
92
+ pnpm build
93
+
94
+ # Run tests
95
+ pnpm test
96
+
97
+ # Type check
98
+ pnpm type-check
99
+
100
+ # Run linting
101
+ pnpm lint
102
+ ```
103
+
104
+ ## Extending Types
105
+
106
+ These types serve as a foundation and should be extended based on your actual Contentful content model:
107
+
108
+ ```typescript
109
+ import type { IPage } from '@se-studio/core-data-types';
110
+
111
+ // Extend the base page type with your custom fields
112
+ interface ICustomPage extends IPage {
113
+ hero: {
114
+ title: string;
115
+ image: IAsset;
116
+ };
117
+ content: RichTextContent;
118
+ }
119
+ ```
120
+
121
+ ## Future Additions
122
+
123
+ This package currently contains placeholder types. As the content model evolves, additional types will be added for:
124
+
125
+ - Component types (Hero, CTA, etc.)
126
+ - Rich text content structures
127
+ - Navigation structures
128
+ - Blog/Article types
129
+ - And more...
130
+
131
+ ## License
132
+
133
+ MIT
134
+
135
+ ## Repository
136
+
137
+ [https://github.com/Something-Else-Studio/se-core-product](https://github.com/Something-Else-Studio/se-core-product)
@@ -0,0 +1,357 @@
1
+ import { VideoTypeData } from '@extractus/oembed-extractor';
2
+
3
+ interface IPage<TConfig extends BaseCmsConfig> extends IBaseModel<TConfig> {
4
+ type: 'Page';
5
+ isHomePage: boolean;
6
+ structuredData?: ReadonlyArray<unknown>;
7
+ contents?: ReadonlyArray<PageContent<TConfig>>;
8
+ tags?: ReadonlyArray<IInternalLink<TConfig>>;
9
+ }
10
+ type PageLink<TConfig extends BaseCmsConfig> = Omit<IPage<TConfig>, BaseModelLinkOmissions | 'structuredData' | 'contents'>;
11
+ declare function isPage<TConfig extends BaseCmsConfig>(content: IBaseModel<TConfig>): content is IPage<TConfig>;
12
+
13
+ interface ITag<TConfig extends BaseCmsConfig> extends IBaseModel<TConfig> {
14
+ type: 'Tag';
15
+ tagType?: string | null;
16
+ contents?: ReadonlyArray<PageContent<TConfig>>;
17
+ }
18
+ type TagLink<TConfig extends BaseCmsConfig> = Omit<ITag<TConfig>, BaseModelLinkOmissions | 'contents'>;
19
+ declare function isTag<TConfig extends BaseCmsConfig>(content: IBaseModel<TConfig>): content is ITag<TConfig>;
20
+ interface ITags<TConfig extends BaseCmsConfig> extends IBaseModel<TConfig> {
21
+ type: 'Tags';
22
+ }
23
+ declare function isTags<TConfig extends BaseCmsConfig>(content: IBaseModel<TConfig>): content is ITags<TConfig>;
24
+
25
+ type Vertical = 'Top' | 'Middle' | 'Bottom';
26
+ type Horizontal = 'Left' | 'Middle' | 'Right';
27
+ interface IInternalBreakpoint {
28
+ maxWidth: number;
29
+ proportion: number;
30
+ pixels: number;
31
+ size: string;
32
+ }
33
+ type IBreakpoint = Pick<IInternalBreakpoint, 'maxWidth'> & Partial<Omit<IInternalBreakpoint, 'maxWidth'>>;
34
+ interface IVisualSizes {
35
+ defaultSize?: string;
36
+ defaultPixels?: number;
37
+ breakpoints?: IBreakpoint[];
38
+ }
39
+ declare function processSizes({ defaultSize, defaultPixels, breakpoints }: IVisualSizes): {
40
+ defaultSize: string | undefined;
41
+ defaultPixels: number | undefined;
42
+ breakpoints: IInternalBreakpoint[] | undefined;
43
+ };
44
+ interface IVisualCommon {
45
+ type: string;
46
+ id: string;
47
+ name: string;
48
+ description?: string | null;
49
+ nameAsCaption?: boolean | null;
50
+ dontCrop?: boolean | null;
51
+ horizontalCropPosition?: Horizontal | null;
52
+ verticalCropPosition?: Vertical | null;
53
+ horizontalPosition?: Horizontal | null;
54
+ widthPercent?: number | null;
55
+ }
56
+ interface IOptimisedSvg {
57
+ data: string;
58
+ width: number;
59
+ height: number;
60
+ }
61
+ interface IImageCommon extends IVisualCommon {
62
+ mimeType: string;
63
+ }
64
+ interface IPicture extends IImageCommon {
65
+ type: 'Picture';
66
+ src: string;
67
+ width: number;
68
+ height: number;
69
+ size: number;
70
+ }
71
+ interface ISvgImage extends IImageCommon {
72
+ type: 'Svg image';
73
+ size: number;
74
+ svgSrc: string;
75
+ width: number;
76
+ height: number;
77
+ }
78
+ interface ISvgData extends IImageCommon {
79
+ type: 'Svg data';
80
+ data: string;
81
+ width: number;
82
+ height: number;
83
+ }
84
+ type IImage = IPicture | ISvgImage | ISvgData;
85
+ declare function isPicture(obj: IVisualCommon | undefined | null): obj is IPicture;
86
+ declare function isSvgImage(obj: IVisualCommon | undefined | null): obj is ISvgImage;
87
+ declare function isSvgData(obj: IVisualCommon | undefined | null): obj is ISvgData;
88
+ declare function isImage(obj: IVisualCommon | undefined | null): obj is IImage;
89
+ interface IVideoDetails {
90
+ id: string;
91
+ videoUrl: string;
92
+ mimeType: string;
93
+ fileName: string;
94
+ size: number;
95
+ }
96
+ interface IVideoCommon extends IVisualCommon {
97
+ poster?: string;
98
+ loop?: boolean | null;
99
+ autoPlay?: boolean | null;
100
+ width?: number;
101
+ height?: number;
102
+ hideControls?: boolean | null;
103
+ }
104
+ interface ILocalVideo extends IVideoCommon {
105
+ type: 'Local video';
106
+ preview: IVideoDetails;
107
+ }
108
+ interface IFullVideo extends IVideoCommon {
109
+ type: 'Full video';
110
+ preview?: IVideoDetails;
111
+ full: IVideoDetails;
112
+ }
113
+ interface IExternalVideo extends IVideoCommon {
114
+ type: 'External video';
115
+ preview?: IVideoDetails;
116
+ external: string;
117
+ embed?: VideoTypeData;
118
+ }
119
+ type IVideo = ILocalVideo | IFullVideo | IExternalVideo;
120
+ declare function isLocalVideo(obj: IVisualCommon | undefined | null): obj is ILocalVideo;
121
+ declare function isFullVideo(obj: IVisualCommon | undefined | null): obj is IFullVideo;
122
+ declare function isExternalVideo(obj: IVisualCommon | undefined | null): obj is IExternalVideo;
123
+ declare function isVideo(obj: IVisualCommon | undefined | null): obj is IVideo;
124
+ interface IAnimation extends IVisualCommon {
125
+ type: 'Animation';
126
+ optimised?: IOptimisedSvg;
127
+ animationSrc: string;
128
+ loop?: boolean | null;
129
+ loopDelay?: number | null;
130
+ autoPlay?: boolean | null;
131
+ }
132
+ declare function isAnimation(obj: IVisualCommon | undefined | null): boolean;
133
+ interface IVisual {
134
+ type: 'Visual';
135
+ id: string;
136
+ image?: IImage;
137
+ video?: IVideo;
138
+ animation?: IAnimation;
139
+ }
140
+ declare function isVisualVideo(visual: IVisual | undefined | null): boolean;
141
+ declare function isVisualImage(visual: IVisual | undefined | null): boolean;
142
+ declare function isVisualAnimation(visual: IVisual | undefined | null): boolean;
143
+ interface IResponsiveVisual {
144
+ visual: IVisual;
145
+ hideVisual?: boolean;
146
+ mobileVisual?: IVisual;
147
+ hideMobileVisual?: boolean;
148
+ visualCustomSize?: number | null;
149
+ }
150
+
151
+ type BaseModelType = 'Page' | 'Article' | 'Tag' | 'Article type' | 'Tags' | 'Person' | 'People' | 'Custom type';
152
+ type BaseContentType = 'Component' | 'Collection' | 'Internal link' | 'Visual' | 'External component';
153
+ type Brand<T, U> = T & {
154
+ __brand: U;
155
+ };
156
+ type ColourName<T extends string = string> = Brand<T, 'ColourName'>;
157
+ type GradientName<T extends string = string> = Brand<T, 'GradientName'>;
158
+ type ModelType<T extends string = string> = Brand<T, 'ModelType'>;
159
+ type ContentType<T extends string = string> = Brand<T, 'ContentType'>;
160
+ type IconName<T extends string = string> = Brand<T, 'IconName'>;
161
+ type ButtonVariant<T extends string = string> = Brand<T, 'ButtonVariant'>;
162
+ type ButtonSize<T extends string = string> = Brand<T, 'ButtonSize'>;
163
+ type ComponentType<T extends string = string> = Brand<T, 'ComponentType'>;
164
+ type CollectionType<T extends string = string> = Brand<T, 'CollectionType'>;
165
+ type ExternalComponentType<T extends string = string> = Brand<T, 'ExternalComponentType'>;
166
+ interface IPageContext<TConfig extends BaseCmsConfig> {
167
+ articleLink?: ArticleLink<TConfig>;
168
+ articleTypeLink?: ArticleTypeLink<TConfig>;
169
+ personLink?: PersonLink<TConfig>;
170
+ pageLink?: PageLink<TConfig>;
171
+ tagLink?: TagLink<TConfig>;
172
+ }
173
+ interface IContentContext<TConfig extends BaseCmsConfig> {
174
+ analyticsContext?: IAnalyticsContext;
175
+ pageContext: IPageContext<TConfig>;
176
+ current: PageContent<TConfig>;
177
+ previousContent?: PageContent<TConfig>;
178
+ nextContent?: PageContent<TConfig>;
179
+ }
180
+ interface IAnalyticsContext {
181
+ slug: string;
182
+ title?: string;
183
+ type?: string;
184
+ }
185
+ interface IRichTextOptions {
186
+ cmsLabel?: string | null;
187
+ analytics?: IAnalyticsContext;
188
+ embedded?: boolean;
189
+ parentId: string;
190
+ parentIndex: number;
191
+ }
192
+ type BaseCmsConfig = {
193
+ RichText: unknown;
194
+ ColourName: ColourName<string>;
195
+ GradientName: GradientName<string>;
196
+ ModelType: ModelType<string>;
197
+ ContentType: ContentType<string>;
198
+ CollectionType: CollectionType<string>;
199
+ ComponentType: ComponentType<string>;
200
+ ExternalComponentType: ExternalComponentType<string>;
201
+ ButtonVariant: ButtonVariant<string>;
202
+ ButtonSize: ButtonSize<string>;
203
+ PageContext: IPageContext<BaseCmsConfig>;
204
+ Component: IBaseComponent<BaseCmsConfig>;
205
+ Collection: IBaseCollection<BaseCmsConfig>;
206
+ ExternalComponent: IBaseExternalComponent<BaseCmsConfig>;
207
+ RichTextOptions: IRichTextOptions;
208
+ PageContent: PageContent<BaseCmsConfig>;
209
+ };
210
+ interface ILinkProps<TConfig extends BaseCmsConfig> {
211
+ parentId?: string;
212
+ parentFieldId?: string;
213
+ id: string;
214
+ useName?: boolean | null;
215
+ name: string;
216
+ text?: string | null;
217
+ icon?: IVisual;
218
+ visual?: IVisual;
219
+ href?: string | null;
220
+ click?: () => void;
221
+ type: 'Blank link' | 'External link' | 'Internal link' | 'Download link';
222
+ backgroundColour?: TConfig['ColourName'] | TConfig['GradientName'] | null;
223
+ textColour?: TConfig['ColourName'] | null;
224
+ variant?: TConfig['ButtonVariant'];
225
+ size?: TConfig['ButtonSize'];
226
+ }
227
+ interface IBLankLink<TConfig extends BaseCmsConfig> extends ILinkProps<TConfig> {
228
+ type: 'Blank link';
229
+ }
230
+ interface IExternalLink<TConfig extends BaseCmsConfig> extends ILinkProps<TConfig> {
231
+ type: 'External link';
232
+ }
233
+ interface IInternalLink<TConfig extends BaseCmsConfig> extends ILinkProps<TConfig> {
234
+ type: 'Internal link';
235
+ slug: string;
236
+ indexed?: boolean | null;
237
+ hidden?: boolean | null;
238
+ tags?: ReadonlyArray<IInternalLink<TConfig>>;
239
+ }
240
+ interface IDownloadLink<TConfig extends BaseCmsConfig> extends ILinkProps<TConfig> {
241
+ type: 'Download link';
242
+ }
243
+ interface INavigation<TConfig extends BaseCmsConfig> {
244
+ id: string;
245
+ name: string;
246
+ entries: ReadonlyArray<INavigationItem<TConfig>>;
247
+ textColour?: TConfig['ColourName'];
248
+ backgroundColour?: TConfig['ColourName'] | TConfig['GradientName'];
249
+ }
250
+ interface INavigationItem<TConfig extends BaseCmsConfig> {
251
+ id: string;
252
+ link?: ILinkProps<TConfig>;
253
+ entries?: ReadonlyArray<INavigationItem<TConfig>>;
254
+ longText: TConfig['RichText'] | string | null;
255
+ }
256
+ interface IBaseModel<TConfig extends BaseCmsConfig> {
257
+ type: BaseModelType | TConfig['ModelType'];
258
+ id: string;
259
+ slug: string;
260
+ title: string;
261
+ description: string;
262
+ featuredImage?: IVisual;
263
+ link?: string;
264
+ indexed?: boolean | null;
265
+ hidden?: boolean | null;
266
+ lastUpdated?: string | Date;
267
+ textColour?: TConfig['ColourName'];
268
+ backgroundColour?: TConfig['ColourName'] | TConfig['GradientName'];
269
+ menu?: INavigation<TConfig>;
270
+ footer?: INavigation<TConfig>;
271
+ }
272
+ type BaseModelLinkOmissions = 'menu' | 'footer';
273
+ interface IBaseContent<TConfig extends BaseCmsConfig> {
274
+ type: BaseContentType | TConfig['ContentType'];
275
+ index: number;
276
+ isFirst: boolean;
277
+ isLast: boolean;
278
+ indexOfType: number;
279
+ id: string;
280
+ name: string;
281
+ anchor?: string | null;
282
+ cmsLabel: string | null;
283
+ backgroundColour?: TConfig['ColourName'] | TConfig['GradientName'];
284
+ textColour?: TConfig['ColourName'];
285
+ hexColor?: string | null;
286
+ backgroundVisual?: IResponsiveVisual;
287
+ backgroundOverlayOpacity?: number | null;
288
+ visual?: IResponsiveVisual;
289
+ parentId?: string;
290
+ parentFieldId?: string;
291
+ }
292
+ interface IBaseComponent<TConfig extends BaseCmsConfig> extends IBaseContent<TConfig> {
293
+ type: 'Component';
294
+ componentType: TConfig['ComponentType'];
295
+ preHeading?: string | null;
296
+ heading?: string | null;
297
+ postHeading?: string | null;
298
+ body?: TConfig['RichText'] | string;
299
+ icon?: IVisual;
300
+ links?: ReadonlyArray<ILinkProps<TConfig>>;
301
+ additionalCopy?: TConfig['RichText'] | string;
302
+ }
303
+ declare function isComponent<TConfig extends BaseCmsConfig>(obj: unknown): obj is TConfig['Component'];
304
+ type CollectionContent<TConfig extends BaseCmsConfig> = IBaseComponent<TConfig> | IBaseCollection<TConfig>;
305
+ interface IBaseCollection<TConfig extends BaseCmsConfig> extends IBaseContent<TConfig> {
306
+ type: 'Collection';
307
+ collectionType: TConfig['CollectionType'];
308
+ anchor?: string | null;
309
+ preHeading?: string | null;
310
+ heading?: string | null;
311
+ postHeading?: string | null;
312
+ body?: TConfig['RichText'] | string;
313
+ icon?: IVisual;
314
+ links?: ReadonlyArray<ILinkProps<TConfig>>;
315
+ additionalCopy?: TConfig['RichText'] | string;
316
+ contents?: ReadonlyArray<CollectionContent<TConfig>>;
317
+ }
318
+ declare function isCollection<TConfig extends BaseCmsConfig>(obj: unknown): obj is TConfig['Collection'];
319
+ interface IBaseExternalComponent<TConfig extends BaseCmsConfig> extends IBaseContent<TConfig> {
320
+ type: 'External component';
321
+ externalType: TConfig['ExternalComponentType'];
322
+ data: unknown | null;
323
+ }
324
+ interface IPerson<TConfig extends BaseCmsConfig> extends IBaseModel<TConfig> {
325
+ type: 'Person';
326
+ jobTitle?: string | null;
327
+ phoneNumber: string | null;
328
+ emailAddress: string | null;
329
+ location: string | null;
330
+ linkedIn: string | null;
331
+ bio: TConfig['RichText'] | null | undefined;
332
+ href: string | undefined;
333
+ structuredData?: ReadonlyArray<unknown>;
334
+ contents?: ReadonlyArray<PageContent<TConfig>>;
335
+ }
336
+ type PersonLink<TConfig extends BaseCmsConfig> = Omit<IPerson<TConfig>, BaseModelLinkOmissions | 'structuredData' | 'contents'>;
337
+ type PageContent<TConfig extends BaseCmsConfig> = IBaseComponent<TConfig> | IBaseCollection<TConfig> | IBaseExternalComponent<TConfig> | IVisual | IInternalLink<TConfig>;
338
+
339
+ interface IArticle<TConfig extends BaseCmsConfig> extends IBaseModel<TConfig> {
340
+ type: 'Article';
341
+ articleType?: IInternalLink<TConfig>;
342
+ structuredData?: ReadonlyArray<unknown>;
343
+ contents?: ReadonlyArray<PageContent<TConfig>>;
344
+ tags?: ReadonlyArray<IInternalLink<TConfig>>;
345
+ }
346
+ type ArticleLink<TConfig extends BaseCmsConfig> = Omit<IArticle<TConfig>, BaseModelLinkOmissions | 'structuredData' | 'contents' | 'tags'> & {
347
+ tags?: ReadonlyArray<TagLink<TConfig>>;
348
+ };
349
+ declare function isArticle<TConfig extends BaseCmsConfig>(content: IBaseModel<TConfig>): content is IArticle<TConfig>;
350
+ interface IArticleType<TConfig extends BaseCmsConfig> extends IBaseModel<TConfig> {
351
+ type: 'Article type';
352
+ indexPageContent?: ReadonlyArray<PageContent<TConfig>>;
353
+ searchPageContent?: ReadonlyArray<PageContent<TConfig>>;
354
+ }
355
+ type ArticleTypeLink<TConfig extends BaseCmsConfig> = Omit<IArticleType<TConfig>, BaseModelLinkOmissions | 'indexPageContent' | 'searchPageContent'>;
356
+
357
+ export { type BaseCmsConfig, type BaseContentType, type BaseModelType, type ButtonSize, type ButtonVariant, type CollectionContent, type CollectionType, type ColourName, type ComponentType, type ContentType, type ExternalComponentType, type GradientName, type Horizontal, type IAnalyticsContext, type IAnimation, type IArticle, type IBLankLink, type IBaseCollection, type IBaseComponent, type IBaseContent, type IBaseExternalComponent, type IBaseModel, type IContentContext, type IDownloadLink, type IExternalLink, type IExternalVideo, type IFullVideo, type IImage, type IInternalLink, type ILinkProps, type ILocalVideo, type INavigation, type INavigationItem, type IPage, type IPageContext, type IPerson, type IPicture, type IResponsiveVisual, type ISvgData, type ISvgImage, type ITag, type ITags, type IVideo, type IVideoDetails, type IVisual, type IVisualCommon, type IVisualSizes, type IconName, type ModelType, type PageContent, type PersonLink, type Vertical, isAnimation, isArticle, isCollection, isComponent, isExternalVideo, isFullVideo, isImage, isLocalVideo, isPage, isPicture, isSvgData, isSvgImage, isTag, isTags, isVideo, isVisualAnimation, isVisualImage, isVisualVideo, processSizes };
package/dist/index.js ADDED
@@ -0,0 +1,108 @@
1
+ // src/types/article.ts
2
+ function isArticle(content) {
3
+ return content.type === "Article";
4
+ }
5
+
6
+ // src/types/common.ts
7
+ function isComponent(obj) {
8
+ if (typeof obj !== "object" || obj === null) {
9
+ return false;
10
+ }
11
+ if (obj.type !== "Component") {
12
+ return false;
13
+ }
14
+ return true;
15
+ }
16
+ function isCollection(obj) {
17
+ if (typeof obj !== "object" || obj === null) {
18
+ return false;
19
+ }
20
+ if (obj.type !== "Collection") {
21
+ return false;
22
+ }
23
+ return true;
24
+ }
25
+
26
+ // src/types/page.ts
27
+ function isPage(content) {
28
+ return content.type === "Page";
29
+ }
30
+
31
+ // src/types/tag.ts
32
+ function isTag(content) {
33
+ return content.type === "Tag";
34
+ }
35
+ function isTags(content) {
36
+ return content.type === "Tags";
37
+ }
38
+
39
+ // src/types/visual.ts
40
+ function fillInBreakpoints(breakpoints) {
41
+ return breakpoints?.map(({ maxWidth, proportion, pixels, size }) => {
42
+ if (proportion) {
43
+ return {
44
+ maxWidth,
45
+ proportion,
46
+ pixels: Math.round(maxWidth * proportion),
47
+ size: `${Math.round(100 * proportion)}vw`
48
+ };
49
+ }
50
+ if (pixels) {
51
+ const proportion2 = Math.round(maxWidth / pixels);
52
+ return {
53
+ maxWidth,
54
+ proportion: proportion2,
55
+ pixels,
56
+ size: size ?? `${Math.round(100 * proportion2)}vw`
57
+ };
58
+ }
59
+ return { maxWidth, proportion: 1, pixels: maxWidth, size: size ?? `100vw` };
60
+ });
61
+ }
62
+ function processSizes({ defaultSize, defaultPixels, breakpoints }) {
63
+ return {
64
+ defaultSize,
65
+ defaultPixels,
66
+ breakpoints: fillInBreakpoints(breakpoints)
67
+ };
68
+ }
69
+ function isPicture(obj) {
70
+ return obj?.type === "Picture";
71
+ }
72
+ function isSvgImage(obj) {
73
+ return obj?.type === "Svg image";
74
+ }
75
+ function isSvgData(obj) {
76
+ return obj?.type === "Svg data";
77
+ }
78
+ function isImage(obj) {
79
+ return isPicture(obj) || isSvgImage(obj) || isSvgData(obj);
80
+ }
81
+ function isLocalVideo(obj) {
82
+ return obj?.type === "Local video";
83
+ }
84
+ function isFullVideo(obj) {
85
+ return obj?.type === "Full video";
86
+ }
87
+ function isExternalVideo(obj) {
88
+ return obj?.type === "External video";
89
+ }
90
+ function isVideo(obj) {
91
+ return isLocalVideo(obj) || isFullVideo(obj) || isExternalVideo(obj);
92
+ }
93
+ function isAnimation(obj) {
94
+ return obj?.type === "Animation";
95
+ }
96
+ function isVisualVideo(visual) {
97
+ return visual?.video !== void 0;
98
+ }
99
+ function isVisualImage(visual) {
100
+ return visual?.image !== void 0;
101
+ }
102
+ function isVisualAnimation(visual) {
103
+ return visual?.animation !== void 0;
104
+ }
105
+
106
+ export { isAnimation, isArticle, isCollection, isComponent, isExternalVideo, isFullVideo, isImage, isLocalVideo, isPage, isPicture, isSvgData, isSvgImage, isTag, isTags, isVideo, isVisualAnimation, isVisualImage, isVisualVideo, processSizes };
107
+ //# sourceMappingURL=index.js.map
108
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types/article.ts","../src/types/common.ts","../src/types/page.ts","../src/types/tag.ts","../src/types/visual.ts"],"names":["proportion"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n BaseCmsConfig,\n BaseModelLinkOmissions,\n IBaseModel,\n IInternalLink,\n PageContent,\n} from './common';\nimport type { TagLink } from './tag';\n\nexport interface IArticle<TConfig extends BaseCmsConfig> extends IBaseModel<TConfig> {\n type: 'Article';\n articleType?: IInternalLink<TConfig>;\n structuredData?: ReadonlyArray<unknown>;\n contents?: ReadonlyArray<PageContent<TConfig>>;\n tags?: ReadonlyArray<IInternalLink<TConfig>>;\n}\n\nexport type ArticleLink<TConfig extends BaseCmsConfig> = Omit<\n IArticle<TConfig>,\n BaseModelLinkOmissions | 'structuredData' | 'contents' | 'tags'\n> & {\n tags?: ReadonlyArray<TagLink<TConfig>>;\n};\n\nexport function isArticle<TConfig extends BaseCmsConfig>(\n content: IBaseModel<TConfig>,\n): content is IArticle<TConfig> {\n return content.type === 'Article';\n}\n\nexport interface IArticleType<TConfig extends BaseCmsConfig> extends IBaseModel<TConfig> {\n type: 'Article type';\n indexPageContent?: ReadonlyArray<PageContent<TConfig>>;\n searchPageContent?: ReadonlyArray<PageContent<TConfig>>;\n}\n\nexport type ArticleTypeLink<TConfig extends BaseCmsConfig> = Omit<\n IArticleType<TConfig>,\n BaseModelLinkOmissions | 'indexPageContent' | 'searchPageContent'\n>;\n\nexport function isArticleType<TConfig extends BaseCmsConfig>(\n content: IBaseModel<TConfig>,\n): content is IArticleType<TConfig> {\n return content.type === 'Article type';\n}\n","import type { ArticleLink, ArticleTypeLink } from './article';\nimport type { PageLink } from './page';\nimport type { TagLink } from './tag';\nimport type { IResponsiveVisual, IVisual } from './visual';\n\n/**\n * Utility type to make all nested properties of a type optional\n */\nexport type DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];\n};\n\n/**\n * Utility type to make TypeScript's complex types more readable in IDE tooltips\n */\nexport type Prettify<T> = {\n [K in keyof T]: T[K];\n} & {};\n\nexport type BaseModelType =\n | 'Page'\n | 'Article'\n | 'Tag'\n | 'Article type'\n | 'Tags'\n | 'Person'\n | 'People'\n | 'Custom type';\n\nexport type BaseContentType =\n | 'Component'\n | 'Collection'\n | 'Internal link'\n | 'Visual'\n | 'External component';\n\nexport type Brand<T, U> = T & { __brand: U }; // Nominal typing helper\n\nexport type ColourName<T extends string = string> = Brand<T, 'ColourName'>;\nexport type GradientName<T extends string = string> = Brand<T, 'GradientName'>;\nexport type ModelType<T extends string = string> = Brand<T, 'ModelType'>;\nexport type ContentType<T extends string = string> = Brand<T, 'ContentType'>;\nexport type IconName<T extends string = string> = Brand<T, 'IconName'>;\nexport type ButtonVariant<T extends string = string> = Brand<T, 'ButtonVariant'>;\nexport type ButtonSize<T extends string = string> = Brand<T, 'ButtonSize'>;\nexport type ComponentType<T extends string = string> = Brand<T, 'ComponentType'>;\nexport type CollectionType<T extends string = string> = Brand<T, 'CollectionType'>;\nexport type ExternalComponentType<T extends string = string> = Brand<T, 'ExternalComponentType'>;\n\nexport interface IPageContext<TConfig extends BaseCmsConfig> {\n articleLink?: ArticleLink<TConfig>;\n articleTypeLink?: ArticleTypeLink<TConfig>;\n personLink?: PersonLink<TConfig>;\n pageLink?: PageLink<TConfig>;\n tagLink?: TagLink<TConfig>;\n}\n\nexport interface IContentContext<TConfig extends BaseCmsConfig> {\n analyticsContext?: IAnalyticsContext;\n pageContext: IPageContext<TConfig>;\n current: PageContent<TConfig>;\n previousContent?: PageContent<TConfig>;\n nextContent?: PageContent<TConfig>;\n}\n\nexport interface IAnalyticsContext {\n slug: string;\n title?: string;\n type?: string;\n}\n\nexport interface IRichTextOptions {\n cmsLabel?: string | null;\n analytics?: IAnalyticsContext;\n embedded?: boolean;\n parentId: string;\n parentIndex: number;\n}\n\nexport type BaseCmsConfig = {\n RichText: unknown; // Or whatever your default rich text type is\n ColourName: ColourName<string>;\n GradientName: GradientName<string>;\n ModelType: ModelType<string>;\n ContentType: ContentType<string>;\n CollectionType: CollectionType<string>;\n ComponentType: ComponentType<string>;\n ExternalComponentType: ExternalComponentType<string>;\n ButtonVariant: ButtonVariant<string>;\n ButtonSize: ButtonSize<string>;\n PageContext: IPageContext<BaseCmsConfig>;\n Component: IBaseComponent<BaseCmsConfig>;\n Collection: IBaseCollection<BaseCmsConfig>;\n ExternalComponent: IBaseExternalComponent<BaseCmsConfig>;\n RichTextOptions: IRichTextOptions;\n PageContent: PageContent<BaseCmsConfig>;\n};\n\nexport interface ILinkProps<TConfig extends BaseCmsConfig> {\n parentId?: string;\n parentFieldId?: string;\n id: string;\n useName?: boolean | null;\n name: string;\n text?: string | null;\n icon?: IVisual;\n visual?: IVisual;\n href?: string | null;\n click?: () => void;\n type: 'Blank link' | 'External link' | 'Internal link' | 'Download link';\n backgroundColour?: TConfig['ColourName'] | TConfig['GradientName'] | null;\n textColour?: TConfig['ColourName'] | null;\n variant?: TConfig['ButtonVariant'];\n size?: TConfig['ButtonSize'];\n}\n\nexport interface IBLankLink<TConfig extends BaseCmsConfig> extends ILinkProps<TConfig> {\n type: 'Blank link';\n}\n\nexport interface IExternalLink<TConfig extends BaseCmsConfig> extends ILinkProps<TConfig> {\n type: 'External link';\n}\n\nexport interface IInternalLink<TConfig extends BaseCmsConfig> extends ILinkProps<TConfig> {\n type: 'Internal link';\n slug: string;\n indexed?: boolean | null;\n hidden?: boolean | null;\n tags?: ReadonlyArray<IInternalLink<TConfig>>;\n}\n\nexport interface IDownloadLink<TConfig extends BaseCmsConfig> extends ILinkProps<TConfig> {\n type: 'Download link';\n}\n\nexport function isBlankLink<TConfig extends BaseCmsConfig>(\n link: ILinkProps<TConfig>,\n): link is IBLankLink<TConfig> {\n return link.type === 'Blank link';\n}\n\nexport function isExternalLink<TConfig extends BaseCmsConfig>(\n link: ILinkProps<TConfig>,\n): link is IExternalLink<TConfig> {\n return link.type === 'External link';\n}\n\nexport function isInternalLink<TConfig extends BaseCmsConfig>(\n link: ILinkProps<TConfig>,\n): link is IInternalLink<TConfig> {\n return link.type === 'Internal link';\n}\n\nexport function isDownloadLink<TConfig extends BaseCmsConfig>(\n link: ILinkProps<TConfig>,\n): link is IDownloadLink<TConfig> {\n return link.type === 'Download link';\n}\n\nexport interface INavigation<TConfig extends BaseCmsConfig> {\n id: string;\n name: string;\n entries: ReadonlyArray<INavigationItem<TConfig>>;\n textColour?: TConfig['ColourName'];\n backgroundColour?: TConfig['ColourName'] | TConfig['GradientName'];\n}\n\nexport interface INavigationItem<TConfig extends BaseCmsConfig> {\n id: string;\n link?: ILinkProps<TConfig>;\n entries?: ReadonlyArray<INavigationItem<TConfig>>;\n longText: TConfig['RichText'] | string | null;\n}\n\nexport interface IBaseModel<TConfig extends BaseCmsConfig> {\n type: BaseModelType | TConfig['ModelType'];\n id: string;\n slug: string;\n title: string;\n description: string;\n featuredImage?: IVisual;\n link?: string;\n indexed?: boolean | null;\n hidden?: boolean | null;\n lastUpdated?: string | Date;\n textColour?: TConfig['ColourName'];\n backgroundColour?: TConfig['ColourName'] | TConfig['GradientName'];\n menu?: INavigation<TConfig>;\n footer?: INavigation<TConfig>;\n}\nexport type BaseModelLinkOmissions = 'menu' | 'footer';\n\nexport interface IBaseContent<TConfig extends BaseCmsConfig> {\n type: BaseContentType | TConfig['ContentType'];\n index: number;\n isFirst: boolean;\n isLast: boolean;\n indexOfType: number;\n id: string;\n name: string;\n anchor?: string | null;\n cmsLabel: string | null; // Original CMS label for tracking purposes\n backgroundColour?: TConfig['ColourName'] | TConfig['GradientName'];\n textColour?: TConfig['ColourName'];\n hexColor?: string | null;\n backgroundVisual?: IResponsiveVisual;\n backgroundOverlayOpacity?: number | null;\n visual?: IResponsiveVisual;\n parentId?: string;\n parentFieldId?: string;\n}\n\nexport interface IBaseComponent<TConfig extends BaseCmsConfig> extends IBaseContent<TConfig> {\n type: 'Component';\n componentType: TConfig['ComponentType'];\n preHeading?: string | null;\n heading?: string | null;\n postHeading?: string | null;\n body?: TConfig['RichText'] | string;\n icon?: IVisual;\n links?: ReadonlyArray<ILinkProps<TConfig>>;\n additionalCopy?: TConfig['RichText'] | string;\n}\n\nexport function isComponent<TConfig extends BaseCmsConfig>(\n obj: unknown,\n): obj is TConfig['Component'] {\n if (typeof obj !== 'object' || obj === null) {\n return false;\n }\n if ((obj as TConfig['Component']).type !== 'Component') {\n return false;\n }\n return true;\n}\n\nexport type CollectionContent<TConfig extends BaseCmsConfig> =\n | IBaseComponent<TConfig>\n | IBaseCollection<TConfig>;\n\nexport interface IBaseCollection<TConfig extends BaseCmsConfig> extends IBaseContent<TConfig> {\n type: 'Collection';\n collectionType: TConfig['CollectionType'];\n anchor?: string | null;\n preHeading?: string | null;\n heading?: string | null;\n postHeading?: string | null;\n body?: TConfig['RichText'] | string;\n icon?: IVisual;\n links?: ReadonlyArray<ILinkProps<TConfig>>;\n additionalCopy?: TConfig['RichText'] | string;\n contents?: ReadonlyArray<CollectionContent<TConfig>>;\n}\n\nexport function isCollection<TConfig extends BaseCmsConfig>(\n obj: unknown,\n): obj is TConfig['Collection'] {\n if (typeof obj !== 'object' || obj === null) {\n return false;\n }\n if ((obj as TConfig['Collection']).type !== 'Collection') {\n return false;\n }\n return true;\n}\n\nexport interface IBaseExternalComponent<TConfig extends BaseCmsConfig>\n extends IBaseContent<TConfig> {\n type: 'External component';\n externalType: TConfig['ExternalComponentType'];\n data: unknown | null;\n}\n\nexport function isExternalComponent<TConfig extends BaseCmsConfig>(\n obj: unknown,\n): obj is TConfig['ExternalComponent'] {\n if (typeof obj !== 'object' || obj === null) {\n return false;\n }\n if ((obj as TConfig['ExternalComponent']).type !== 'External component') {\n return false;\n }\n return true;\n}\n\nexport interface IPerson<TConfig extends BaseCmsConfig> extends IBaseModel<TConfig> {\n type: 'Person';\n jobTitle?: string | null;\n phoneNumber: string | null;\n emailAddress: string | null;\n location: string | null;\n linkedIn: string | null;\n bio: TConfig['RichText'] | null | undefined;\n href: string | undefined;\n structuredData?: ReadonlyArray<unknown>;\n contents?: ReadonlyArray<PageContent<TConfig>>;\n}\n\nexport type PersonLink<TConfig extends BaseCmsConfig> = Omit<\n IPerson<TConfig>,\n BaseModelLinkOmissions | 'structuredData' | 'contents'\n>;\n\nexport function isPerson<TConfig extends BaseCmsConfig>(\n content: IBaseModel<TConfig>,\n): content is IPerson<TConfig> {\n return content.type === 'Person';\n}\n\nexport type PageContent<TConfig extends BaseCmsConfig> =\n | IBaseComponent<TConfig>\n | IBaseCollection<TConfig>\n | IBaseExternalComponent<TConfig>\n | IVisual\n | IInternalLink<TConfig>;\n","import type {\n BaseCmsConfig,\n BaseModelLinkOmissions,\n IBaseModel,\n IInternalLink,\n PageContent,\n} from './common';\n\nexport interface IPage<TConfig extends BaseCmsConfig> extends IBaseModel<TConfig> {\n type: 'Page';\n isHomePage: boolean;\n structuredData?: ReadonlyArray<unknown>;\n contents?: ReadonlyArray<PageContent<TConfig>>;\n tags?: ReadonlyArray<IInternalLink<TConfig>>;\n}\n\nexport type PageLink<TConfig extends BaseCmsConfig> = Omit<\n IPage<TConfig>,\n BaseModelLinkOmissions | 'structuredData' | 'contents'\n>;\n\nexport function isPage<TConfig extends BaseCmsConfig>(\n content: IBaseModel<TConfig>,\n): content is IPage<TConfig> {\n return content.type === 'Page';\n}\n","import type { BaseCmsConfig, BaseModelLinkOmissions, IBaseModel, PageContent } from './common';\n\nexport interface ITag<TConfig extends BaseCmsConfig> extends IBaseModel<TConfig> {\n type: 'Tag';\n tagType?: string | null;\n contents?: ReadonlyArray<PageContent<TConfig>>;\n}\n\nexport type TagLink<TConfig extends BaseCmsConfig> = Omit<\n ITag<TConfig>,\n BaseModelLinkOmissions | 'contents'\n>;\n\nexport function isTag<TConfig extends BaseCmsConfig>(\n content: IBaseModel<TConfig>,\n): content is ITag<TConfig> {\n return content.type === 'Tag';\n}\n\nexport interface ITags<TConfig extends BaseCmsConfig> extends IBaseModel<TConfig> {\n type: 'Tags';\n}\n\nexport function isTags<TConfig extends BaseCmsConfig>(\n content: IBaseModel<TConfig>,\n): content is ITags<TConfig> {\n return content.type === 'Tags';\n}\n","import type { VideoTypeData } from '@extractus/oembed-extractor';\n\nexport type Vertical = 'Top' | 'Middle' | 'Bottom';\nexport type Horizontal = 'Left' | 'Middle' | 'Right';\n\ninterface IInternalBreakpoint {\n maxWidth: number;\n proportion: number;\n pixels: number;\n size: string;\n}\ntype IBreakpoint = Pick<IInternalBreakpoint, 'maxWidth'> &\n Partial<Omit<IInternalBreakpoint, 'maxWidth'>>;\nexport interface IVisualSizes {\n defaultSize?: string;\n defaultPixels?: number;\n breakpoints?: IBreakpoint[];\n}\n\nfunction fillInBreakpoints(breakpoints?: IBreakpoint[]): IInternalBreakpoint[] | undefined {\n return breakpoints?.map(({ maxWidth, proportion, pixels, size }) => {\n if (proportion) {\n return {\n maxWidth,\n proportion,\n pixels: Math.round(maxWidth * proportion),\n size: `${Math.round(100 * proportion)}vw`,\n };\n }\n if (pixels) {\n const proportion = Math.round(maxWidth / pixels);\n return {\n maxWidth,\n proportion,\n pixels,\n size: size ?? `${Math.round(100 * proportion)}vw`,\n };\n }\n\n return { maxWidth, proportion: 1, pixels: maxWidth, size: size ?? `100vw` };\n });\n}\nexport function processSizes({ defaultSize, defaultPixels, breakpoints }: IVisualSizes) {\n return {\n defaultSize,\n defaultPixels,\n breakpoints: fillInBreakpoints(breakpoints),\n };\n}\n\nexport interface IVisualCommon {\n type: string;\n id: string;\n name: string;\n description?: string | null;\n nameAsCaption?: boolean | null;\n dontCrop?: boolean | null;\n horizontalCropPosition?: Horizontal | null;\n verticalCropPosition?: Vertical | null;\n horizontalPosition?: Horizontal | null;\n widthPercent?: number | null;\n}\n\nexport interface IOptimisedSvg {\n data: string;\n width: number;\n height: number;\n}\n\ninterface IImageCommon extends IVisualCommon {\n mimeType: string;\n}\nexport interface IPicture extends IImageCommon {\n type: 'Picture';\n src: string;\n width: number;\n height: number;\n size: number;\n}\n\nexport interface ISvgImage extends IImageCommon {\n type: 'Svg image';\n size: number;\n svgSrc: string;\n width: number;\n height: number;\n}\n\nexport interface ISvgData extends IImageCommon {\n type: 'Svg data';\n data: string;\n width: number;\n height: number;\n}\n\nexport type IImage = IPicture | ISvgImage | ISvgData;\n\nexport function isPicture(obj: IVisualCommon | undefined | null): obj is IPicture {\n return obj?.type === 'Picture';\n}\n\nexport function isSvgImage(obj: IVisualCommon | undefined | null): obj is ISvgImage {\n return obj?.type === 'Svg image';\n}\n\nexport function isSvgData(obj: IVisualCommon | undefined | null): obj is ISvgData {\n return obj?.type === 'Svg data';\n}\n\nexport function isImage(obj: IVisualCommon | undefined | null): obj is IImage {\n return isPicture(obj) || isSvgImage(obj) || isSvgData(obj);\n}\n\nexport interface IVideoDetails {\n id: string;\n videoUrl: string;\n mimeType: string;\n fileName: string;\n size: number;\n}\n\nexport interface IVideoCommon extends IVisualCommon {\n poster?: string;\n loop?: boolean | null;\n autoPlay?: boolean | null;\n width?: number;\n height?: number;\n hideControls?: boolean | null;\n}\n\nexport interface ILocalVideo extends IVideoCommon {\n type: 'Local video';\n preview: IVideoDetails;\n}\n\nexport interface IFullVideo extends IVideoCommon {\n type: 'Full video';\n preview?: IVideoDetails;\n full: IVideoDetails;\n}\n\nexport interface IExternalVideo extends IVideoCommon {\n type: 'External video';\n preview?: IVideoDetails;\n external: string;\n embed?: VideoTypeData;\n}\n\nexport type IVideo = ILocalVideo | IFullVideo | IExternalVideo;\n\nexport function isLocalVideo(obj: IVisualCommon | undefined | null): obj is ILocalVideo {\n return obj?.type === 'Local video';\n}\n\nexport function isFullVideo(obj: IVisualCommon | undefined | null): obj is IFullVideo {\n return obj?.type === 'Full video';\n}\n\nexport function isExternalVideo(obj: IVisualCommon | undefined | null): obj is IExternalVideo {\n return obj?.type === 'External video';\n}\n\nexport function isVideo(obj: IVisualCommon | undefined | null): obj is IVideo {\n return isLocalVideo(obj) || isFullVideo(obj) || isExternalVideo(obj);\n}\n\nexport interface IAnimation extends IVisualCommon {\n type: 'Animation';\n optimised?: IOptimisedSvg;\n animationSrc: string;\n loop?: boolean | null;\n loopDelay?: number | null;\n autoPlay?: boolean | null;\n}\n\nexport function isAnimation(obj: IVisualCommon | undefined | null) {\n return obj?.type === 'Animation';\n}\n\nexport interface IVisual {\n type: 'Visual';\n id: string;\n image?: IImage;\n video?: IVideo;\n animation?: IAnimation;\n}\n\nexport function isVisualVideo(visual: IVisual | undefined | null) {\n return visual?.video !== undefined;\n}\nexport function isVisualImage(visual: IVisual | undefined | null) {\n return visual?.image !== undefined;\n}\nexport function isVisualAnimation(visual: IVisual | undefined | null) {\n return visual?.animation !== undefined;\n}\n\nexport interface IResponsiveVisual {\n visual: IVisual;\n hideVisual?: boolean;\n mobileVisual?: IVisual;\n hideMobileVisual?: boolean;\n visualCustomSize?: number | null;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@se-studio/core-data-types",
3
+ "version": "0.1.0",
4
+ "description": "Core TypeScript type definitions for SE Studio content models",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/Something-Else-Studio/se-core-product",
8
+ "directory": "packages/core-data-types"
9
+ },
10
+ "license": "MIT",
11
+ "type": "module",
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "keywords": [
24
+ "typescript",
25
+ "types",
26
+ "contentful",
27
+ "cms",
28
+ "nextjs"
29
+ ],
30
+ "devDependencies": {
31
+ "@biomejs/biome": "^2.3.3",
32
+ "tsup": "^8.5.0",
33
+ "typescript": "^5.9.3",
34
+ "vitest": "^4.0.6"
35
+ },
36
+ "dependencies": {
37
+ "@extractus/oembed-extractor": "^4.0.9"
38
+ },
39
+ "scripts": {
40
+ "build": "tsup",
41
+ "dev": "tsup --watch --no-clean",
42
+ "test": "vitest run",
43
+ "test:watch": "vitest",
44
+ "type-check": "tsc --noEmit",
45
+ "lint": "biome lint .",
46
+ "clean": "rm -rf dist .turbo"
47
+ }
48
+ }