@purestack/ts-common 1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ahmed Yasin Koculu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,10 @@
1
+ # @purestack/ts-common
2
+
3
+ Shared TypeScript contracts for PureStack's site generator, components, and page
4
+ scripts. This package defines site configuration, page frontmatter, navigation,
5
+ logos, templates, and the rendering context so those packages agree on the same
6
+ shapes.
7
+
8
+ Import types such as `SiteConfig`, `PageFrontmatter`, and `TsSsgContext` when
9
+ building a custom integration. The runtime exports `resolveTsSsgContext` and
10
+ `tryResolveTsSsgContext` find the site context in a Regor component.
@@ -0,0 +1,588 @@
1
+ /*! @purestack/ts-common v1.1.0 | (c) 2026 Ahmed Yasin Koculu | MIT License */
2
+
3
+ import { SemanticTone, ThemeOptions, ThemeOptionsInput, ThemeStylesheetLink } from "@purestack/ts-style";
4
+ import { DeepPartial } from "@purestack/ts-util";
5
+ import { BasicHeadConfig, TSNode } from "@purestack/ts-html";
6
+ //#region packages/ts-common/src/consent-types.d.ts
7
+ interface ConsentCategory {
8
+ id: string;
9
+ label: string;
10
+ description?: string;
11
+ required?: boolean;
12
+ }
13
+ interface ConsentScript {
14
+ src?: string;
15
+ content?: string;
16
+ type?: string;
17
+ async?: boolean;
18
+ defer?: boolean;
19
+ integrity?: string;
20
+ nonce?: string;
21
+ crossOrigin?: 'anonymous' | 'use-credentials';
22
+ referrerPolicy?: string;
23
+ }
24
+ interface ConsentService {
25
+ id: string;
26
+ category: string;
27
+ label?: string;
28
+ description?: string;
29
+ scripts: ConsentScript[];
30
+ }
31
+ interface ConsentConfig {
32
+ enabled: boolean;
33
+ storageKey: string;
34
+ policyVersion: string;
35
+ bannerTitle: string;
36
+ bannerDescription: string;
37
+ privacyPolicyUrl?: string;
38
+ privacyPolicyLabel: string;
39
+ acceptAllLabel: string;
40
+ rejectAllLabel: string;
41
+ manageLabel: string;
42
+ saveLabel: string;
43
+ settingsLabel: string;
44
+ categories: ConsentCategory[];
45
+ services: ConsentService[];
46
+ }
47
+ //#endregion
48
+ //#region packages/ts-common/src/logo-types.d.ts
49
+ type LogoLayout = 'horizontal' | 'stacked' | 'wordmark' | 'mark';
50
+ type LogoSize = 'sm' | 'md' | 'lg' | 'xl';
51
+ type LogoAppearance = 'plain' | 'badge' | 'outline';
52
+ type LogoMarkStyle = 'plain' | 'soft' | 'solid' | 'outline';
53
+ type LogoWordmarkStyle = 'plain' | 'accent' | 'gradient';
54
+ type LogoShape = 'rounded' | 'square' | 'circle';
55
+ interface LogoConfig {
56
+ brand: string;
57
+ subtitle?: string;
58
+ suffix?: string;
59
+ href?: string | null;
60
+ ariaLabel?: string;
61
+ icon?: string;
62
+ imageSrc?: string;
63
+ imageSrcDark?: string;
64
+ monogram?: string;
65
+ layout?: LogoLayout;
66
+ size?: LogoSize;
67
+ appearance?: LogoAppearance;
68
+ markStyle?: LogoMarkStyle;
69
+ wordmarkStyle?: LogoWordmarkStyle;
70
+ shape?: LogoShape;
71
+ tone?: SemanticTone;
72
+ brandColor?: string;
73
+ accentColor?: string;
74
+ markBackground?: string;
75
+ markColor?: string;
76
+ brandSize?: string;
77
+ subtitleSize?: string;
78
+ markSize?: string;
79
+ gap?: string;
80
+ }
81
+ /** The original uppercase, letter-colored logo. */
82
+ interface ClassicLogoConfig {
83
+ brand: string;
84
+ letterColors?: string;
85
+ subtitleLetterColors?: string;
86
+ colors?: string[];
87
+ logoBackground?: number;
88
+ logoForeground?: number;
89
+ subtitle?: string;
90
+ brandSize?: string;
91
+ brandSizeSm?: string;
92
+ brandSizeMd?: string;
93
+ brandSizeLg?: string;
94
+ brandSizeXl?: string;
95
+ subtitleSize?: string;
96
+ subtitleSizeSm?: string;
97
+ subtitleSizeMd?: string;
98
+ subtitleSizeLg?: string;
99
+ subtitleSizeXl?: string;
100
+ iconSize?: string;
101
+ iconSizeSm?: string;
102
+ iconSizeMd?: string;
103
+ iconSizeLg?: string;
104
+ iconSizeXl?: string;
105
+ subtitleInset?: string;
106
+ subtitleInsetSm?: string;
107
+ subtitleInsetMd?: string;
108
+ subtitleInsetLg?: string;
109
+ subtitleInsetXl?: string;
110
+ href?: string | null;
111
+ icon?: string;
112
+ ariaLabel?: string;
113
+ }
114
+ /** Shared header configuration; each component reads its own presentation fields. */
115
+ interface SiteLogoConfig extends LogoConfig, ClassicLogoConfig {
116
+ component?: string;
117
+ }
118
+ //#endregion
119
+ //#region packages/ts-common/src/navMenu-types.d.ts
120
+ type NavigationMode = 'auto' | 'custom' | 'hybrid' | 'none';
121
+ type NavigationSort = 'order' | 'title' | 'path';
122
+ interface NavigationConfig {
123
+ mode?: NavigationMode;
124
+ navFileName?: string;
125
+ maxDepth?: number;
126
+ includeIndex?: boolean;
127
+ sortBy?: NavigationSort;
128
+ roots?: string[];
129
+ tone?: SemanticTone;
130
+ /** Treatment of the navigation panel, such as flat, surfaceAlt or glass. */
131
+ variant?: string;
132
+ /** Extra classes for the navigation panel. */
133
+ class?: string;
134
+ }
135
+ interface NavItem {
136
+ id?: string;
137
+ title: string;
138
+ url?: string;
139
+ children?: NavItem[];
140
+ order?: number;
141
+ hidden?: boolean;
142
+ badge?: string;
143
+ icon?: string;
144
+ tone?: SemanticTone;
145
+ }
146
+ interface PageNavigationLink {
147
+ title: string;
148
+ url: string;
149
+ }
150
+ interface PageNavigationLinks {
151
+ previous?: PageNavigationLink;
152
+ next?: PageNavigationLink;
153
+ }
154
+ interface PageNavigation {
155
+ mode: NavigationMode;
156
+ folder: string;
157
+ root: string;
158
+ items: NavItem[];
159
+ global: NavItem[];
160
+ tone: SemanticTone;
161
+ pageLinks?: PageNavigationLinks;
162
+ }
163
+ //#endregion
164
+ //#region packages/ts-common/src/site-config-types.d.ts
165
+ interface SiteConfig {
166
+ rootDir: string;
167
+ contentDir: string;
168
+ outDir: string;
169
+ publishDir: string;
170
+ basePath: string;
171
+ siteTitle: string;
172
+ favicon?: string;
173
+ logo: SiteLogoConfig;
174
+ docLayout: DocLayoutConfig;
175
+ style: SiteStyleConfig;
176
+ html: SiteHtmlConfig;
177
+ navigation: NavigationConfig;
178
+ pageToc: PageTocConfig;
179
+ auth: AuthConfig;
180
+ scripts: SiteScriptsConfig;
181
+ sitemap: SitemapConfig;
182
+ consent: ConsentConfig;
183
+ analytics: AnalyticsConfig;
184
+ pagefind: PagefindConfig;
185
+ preview: PreviewConfig;
186
+ i18n: I18nConfig;
187
+ mdx: SiteMdxConfig;
188
+ }
189
+ interface DocLayoutConfig {
190
+ /** CSS length reserved above desktop navigation and TOC sidebars. */
191
+ sidebarTop: string;
192
+ /** CSS length reserved above mobile navigation and TOC drawers. */
193
+ sidebarTopMobile: string;
194
+ }
195
+ interface PageTocConfig {
196
+ enabled: boolean;
197
+ tone: SemanticTone;
198
+ /** Treatment of the table of contents panel, such as flat, surfaceAlt or glass. */
199
+ variant?: string;
200
+ /** Extra classes for the table of contents panel. */
201
+ class?: string;
202
+ }
203
+ interface AuthConfig {
204
+ enabled: boolean;
205
+ signUp: boolean;
206
+ signedInStorageKey: string;
207
+ }
208
+ interface SiteScriptsConfig {
209
+ cacheBusting: boolean;
210
+ }
211
+ interface SiteStyleConfig {
212
+ fileName: string;
213
+ href: string;
214
+ themes: string[];
215
+ pretty: boolean;
216
+ theme: ThemeOptions;
217
+ }
218
+ interface SiteHtmlConfig {
219
+ minify: boolean;
220
+ }
221
+ interface SitemapConfig {
222
+ enabled: boolean;
223
+ baseUrl: string;
224
+ fileName: string;
225
+ robots: RobotsConfig;
226
+ }
227
+ interface RobotsConfig {
228
+ enabled: boolean;
229
+ fileName: string;
230
+ userAgent: string;
231
+ allow: string[];
232
+ disallow: string[];
233
+ crawlDelay?: number;
234
+ host?: string;
235
+ additionalSitemaps: string[];
236
+ customDirectives: string[];
237
+ }
238
+ interface Ga4Config {
239
+ enabled: boolean;
240
+ measurementId?: string;
241
+ serviceId: string;
242
+ consentCategory: string;
243
+ }
244
+ interface AnalyticsConfig {
245
+ ga4: Ga4Config;
246
+ }
247
+ interface PagefindConfig {
248
+ enabled: boolean;
249
+ excludePaths: string[];
250
+ }
251
+ interface PreviewConfig {
252
+ title?: string;
253
+ description?: string;
254
+ image?: string;
255
+ imageAlt?: string;
256
+ imageWidth?: number;
257
+ imageHeight?: number;
258
+ siteName?: string;
259
+ type?: string;
260
+ locale?: string;
261
+ twitterCard?: string;
262
+ twitterSite?: string;
263
+ twitterCreator?: string;
264
+ }
265
+ type I18nUrlStrategy = 'prefix-all' | 'hidden';
266
+ interface I18nConfig {
267
+ enabled: boolean;
268
+ defaultLocale: string;
269
+ locales: string[];
270
+ urlStrategy: I18nUrlStrategy;
271
+ queryParam: string;
272
+ cookieName: string;
273
+ }
274
+ interface SiteMdxConfig {
275
+ highlighter: 'shiki' | 'highlightjs';
276
+ disableHighlighter: boolean;
277
+ compileMdAsMdx: boolean;
278
+ }
279
+ type SiteStyleConfigInput = DeepPartial<Omit<SiteStyleConfig, 'theme'>> & {
280
+ theme?: ThemeOptionsInput;
281
+ };
282
+ type SiteConfigInput = DeepPartial<Omit<SiteConfig, 'style'>> & {
283
+ style?: SiteStyleConfigInput;
284
+ };
285
+ //#endregion
286
+ //#region packages/ts-common/src/frontmatter-types.d.ts
287
+ /**
288
+ * Normalized frontmatter for a content page.
289
+ *
290
+ * This shape is produced from MD/MDX frontmatter and is consumed by template
291
+ * rendering, navigation building, head generation, and page-level runtime
292
+ * embedding.
293
+ *
294
+ * Known keys are normalized case-insensitively. Custom keys are preserved.
295
+ */
296
+ interface PageFrontmatter {
297
+ /**
298
+ * Primary page title.
299
+ *
300
+ * Used by templates, head generation, and as a fallback for navigation
301
+ * titles when `nav.title` is not provided.
302
+ */
303
+ title?: string;
304
+ /**
305
+ * Short page summary for metadata and presentation surfaces such as
306
+ * `<meta name="description">`.
307
+ */
308
+ description?: string;
309
+ /**
310
+ * Arbitrary head-related metadata.
311
+ *
312
+ * This is intentionally open-ended so projects can attach custom values such
313
+ * as canonical URLs or downstream head configuration inputs.
314
+ */
315
+ head?: Record<string, unknown>;
316
+ /**
317
+ * Social/search preview metadata for this page.
318
+ *
319
+ * Missing fields are filled from the page title/description and site-level
320
+ * preview defaults before Open Graph and Twitter tags are generated.
321
+ */
322
+ preview?: PreviewConfig;
323
+ /**
324
+ * Page template key.
325
+ *
326
+ * Built-in templates include `doc` and `splash`. Custom template names can
327
+ * also be provided by the host application.
328
+ *
329
+ * Defaults to `doc`.
330
+ */
331
+ template: string;
332
+ /**
333
+ * Page sort order.
334
+ *
335
+ * Used by generated navigation unless overridden by `nav.order`.
336
+ */
337
+ order?: number;
338
+ /**
339
+ * Hides the page from generated navigation when set to `true`.
340
+ */
341
+ hidden: boolean;
342
+ /**
343
+ * Marks the page as draft content.
344
+ *
345
+ * Draft pages are excluded from generated navigation.
346
+ */
347
+ draft: boolean;
348
+ /**
349
+ * Navigation-specific overrides for this page.
350
+ */
351
+ nav: FrontmatterNavOptions;
352
+ /**
353
+ * Layout and template presentation controls.
354
+ */
355
+ layout: FrontmatterLayoutOptions;
356
+ /**
357
+ * Page-level runtime embedding switches for supported MDX features.
358
+ */
359
+ embed?: FrontmatterEmbedOptions;
360
+ /**
361
+ * Preserves additional custom frontmatter keys.
362
+ */
363
+ [key: string]: unknown;
364
+ }
365
+ /**
366
+ * Layout controls for the built-in page templates.
367
+ *
368
+ * These options are normalized from MD/MDX frontmatter and primarily affect
369
+ * the built-in `doc` and `splash` templates.
370
+ */
371
+ interface FrontmatterLayoutOptions {
372
+ /**
373
+ * Controls how the page navigation is presented in the `doc` template.
374
+ *
375
+ * - `sidebar`: persistent sidebar layout on larger screens
376
+ * - `drawer`: collapsible drawer-style navigation
377
+ *
378
+ * Defaults to `sidebar`. Any other value is invalid and should throw during
379
+ * frontmatter normalization.
380
+ */
381
+ navMode: 'sidebar' | 'drawer';
382
+ /**
383
+ * Expands the main content area to the wider documentation layout.
384
+ *
385
+ * In the built-in `doc` template this adds the full-width main-content
386
+ * treatment instead of the narrower default reading width.
387
+ *
388
+ * Defaults to `false`.
389
+ */
390
+ fullWidth: boolean;
391
+ /**
392
+ * Enables table-of-contents rendering when the page outline contains items.
393
+ *
394
+ * The TOC appears only when this flag is `true` and the page actually has
395
+ * extracted headings.
396
+ *
397
+ * Defaults to the site-level `pageToc.enabled` setting.
398
+ */
399
+ showToc: boolean;
400
+ /**
401
+ * Controls whether the generated page navigation menu is rendered.
402
+ *
403
+ * This is separate from `nav.hidden`: `nav.hidden` removes the current page
404
+ * from generated navigation, while `showNav` controls the navigation shell on
405
+ * the current page.
406
+ *
407
+ * Defaults to `true`.
408
+ */
409
+ showNav: boolean;
410
+ /**
411
+ * Starts the built-in TOC in its collapsed visual state.
412
+ *
413
+ * This does not disable the TOC. It only changes the initial presentation
414
+ * when `showToc` is enabled and a TOC is available.
415
+ *
416
+ * Defaults to `false`.
417
+ */
418
+ tocCollapsed?: boolean;
419
+ /**
420
+ * Overrides the page TOC tone for this page.
421
+ *
422
+ * When present, this takes precedence over the resolved site TOC tone for
423
+ * the current page render only.
424
+ */
425
+ tocTone?: SemanticTone;
426
+ /**
427
+ * Controls whether the resolved page footer is rendered.
428
+ *
429
+ * Defaults to `true`.
430
+ */
431
+ showFooter: boolean;
432
+ /**
433
+ * Allows template-specific custom layout keys without narrowing the public
434
+ * frontmatter surface to only the built-in options.
435
+ */
436
+ [key: string]: unknown;
437
+ }
438
+ /**
439
+ * Navigation-specific overrides for a single page.
440
+ *
441
+ * These values are consumed when building navigation trees and take precedence
442
+ * over the page-level equivalents where noted.
443
+ */
444
+ interface FrontmatterNavOptions {
445
+ /**
446
+ * Overrides the title shown in generated navigation.
447
+ *
448
+ * Navigation title fallback order is:
449
+ * `nav.title` -> `title` -> first `# heading` -> filename.
450
+ */
451
+ title?: string;
452
+ /**
453
+ * Overrides page sort order inside navigation.
454
+ *
455
+ * When present, this takes precedence over the page-level `order` field.
456
+ */
457
+ order?: number;
458
+ /**
459
+ * Badge text shown with this page's generated navigation item.
460
+ */
461
+ badge?: string;
462
+ /**
463
+ * Icon name shown with this page's generated navigation item.
464
+ */
465
+ icon?: string;
466
+ /**
467
+ * Overrides the navigation menu tone for this page.
468
+ *
469
+ * When present, this takes precedence over the resolved site navigation tone
470
+ * for the current page render only.
471
+ */
472
+ tone?: SemanticTone;
473
+ /**
474
+ * Excludes the page from generated navigation when set to `true`.
475
+ *
476
+ * This is evaluated together with the page-level `hidden` and `draft` flags.
477
+ */
478
+ hidden: boolean;
479
+ /**
480
+ * Allows additional project-specific navigation metadata.
481
+ */
482
+ [key: string]: unknown;
483
+ }
484
+ /**
485
+ * Runtime asset injection controls for MDX features that require page-level
486
+ * scripts or supporting markup.
487
+ */
488
+ interface FrontmatterEmbedOptions {
489
+ /**
490
+ * Chooses where the tabs runtime is injected.
491
+ *
492
+ * - `head`: inject supporting runtime into the page head
493
+ * - `body`: inject supporting runtime near the end of the body
494
+ */
495
+ tabs?: 'head' | 'body';
496
+ /**
497
+ * Chooses where the modal runtime is injected.
498
+ *
499
+ * - `head`: inject supporting runtime into the page head
500
+ * - `body`: inject supporting runtime near the end of the body
501
+ */
502
+ modal?: 'head' | 'body';
503
+ /**
504
+ * Allows future or project-specific embed flags.
505
+ */
506
+ [key: string]: unknown;
507
+ }
508
+ /**
509
+ * Parsed page source split into normalized frontmatter and markdown/MDX body.
510
+ */
511
+ interface ParsedFrontmatterSource {
512
+ /**
513
+ * Page content without the frontmatter block.
514
+ */
515
+ body: string;
516
+ /**
517
+ * Normalized page frontmatter.
518
+ */
519
+ frontmatter: PageFrontmatter;
520
+ }
521
+ //#endregion
522
+ //#region packages/ts-common/src/ts-ssg-context.d.ts
523
+ interface PageOutlineItem {
524
+ id: string;
525
+ title: string;
526
+ depth?: number;
527
+ children?: PageOutlineItem[];
528
+ }
529
+ interface TsSsgNavigation {
530
+ folder?: string;
531
+ root?: string;
532
+ global?: NavItem[];
533
+ items?: NavItem[];
534
+ pageLinks?: PageNavigationLinks;
535
+ }
536
+ interface TsSsgContext {
537
+ site: SiteConfig;
538
+ pageInfo: PageInfo;
539
+ navigation?: TsSsgNavigation;
540
+ outline?: PageOutlineItem[];
541
+ theme: ThemeOptions;
542
+ basePath: string;
543
+ locale?: string;
544
+ locales: string[];
545
+ defaultLocale?: string;
546
+ resolveLocaleHref: (locale: string) => string | undefined;
547
+ resolvePublicHref: (href: string) => string;
548
+ recordScriptEntrypoint: (sourceRelPath: string) => void;
549
+ resolveScriptPublicPath?: (sourceRelPath: string) => string;
550
+ recordRuntimeEmbed: (name: string, position: 'body' | 'head') => void;
551
+ }
552
+ //#endregion
553
+ //#region packages/ts-common/src/page-template-types.d.ts
554
+ interface PageInfo {
555
+ relPath: string;
556
+ urlPath: string;
557
+ frontmatter: PageFrontmatter;
558
+ locale?: string;
559
+ translationKey?: string;
560
+ translations?: PageTranslationInfo[];
561
+ }
562
+ interface PageTranslationInfo {
563
+ locale: string;
564
+ urlPath: string;
565
+ relPath: string;
566
+ }
567
+ interface PageTemplateInput {
568
+ head: TSNode<'head'>;
569
+ bodyHtml: string;
570
+ headConfig?: BasicHeadConfig;
571
+ styleLinks?: ThemeStylesheetLink[];
572
+ templateName: string;
573
+ site: SiteConfig;
574
+ navigation?: PageNavigation;
575
+ outline?: PageOutlineItem[];
576
+ pageInfo: PageInfo;
577
+ headerHtml?: string;
578
+ footerHtml?: string;
579
+ }
580
+ type PageTemplate = (input: PageTemplateInput) => TSNode<'html'> | Promise<TSNode<'html'>>;
581
+ type PageTemplateMap = Record<string, PageTemplate>;
582
+ //#endregion
583
+ //#region packages/ts-common/src/resolveTsSsgContext.d.ts
584
+ export declare function resolveTsSsgContext(head: unknown): TsSsgContext;
585
+ export declare function tryResolveTsSsgContext(head: unknown): TsSsgContext | undefined;
586
+ //#endregion
587
+ export type { AnalyticsConfig, AuthConfig, ClassicLogoConfig, ConsentCategory, ConsentConfig, ConsentScript, ConsentService, DocLayoutConfig, FrontmatterEmbedOptions, FrontmatterLayoutOptions, FrontmatterNavOptions, Ga4Config, I18nConfig, I18nUrlStrategy, LogoAppearance, LogoConfig, LogoLayout, LogoMarkStyle, LogoShape, LogoSize, LogoWordmarkStyle, NavItem, NavigationConfig, NavigationMode, NavigationSort, PageFrontmatter, PageInfo, PageNavigation, PageNavigationLink, PageNavigationLinks, PageOutlineItem, PageTemplate, PageTemplateInput, PageTemplateMap, PageTocConfig, PageTranslationInfo, PagefindConfig, ParsedFrontmatterSource, PreviewConfig, RobotsConfig, SiteConfig, SiteConfigInput, SiteHtmlConfig, SiteLogoConfig, SiteMdxConfig, SiteScriptsConfig, SiteStyleConfig, SiteStyleConfigInput, SitemapConfig, TsSsgContext, TsSsgNavigation };
588
+ //# sourceMappingURL=ts-common.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts-common.d.mts","names":[],"sources":["../src/consent-types.ts","../src/logo-types.ts","../src/navMenu-types.ts","../src/site-config-types.ts","../src/frontmatter-types.ts","../src/ts-ssg-context.ts","../src/page-template-types.ts","../src/resolveTsSsgContext.ts"],"mappings":";;;;UAAiB;EACf;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA,SAAS;;UAGM;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YAAY;EACZ,UAAU;;;;KCvCA;KACA;KACA;KACA;KACA;KACA;UAEK;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS;EACT,OAAO;EACP,aAAa;EACb,YAAY;EACZ,gBAAgB;EAChB,QAAQ;EACR,OAAO;EACP;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;UAIe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;UAIe,uBAAuB,YAAY;EAClD;;;;KCtEU;KACA;UAEK;EACf,OAAO;EACP;EACA;EACA;EACA,SAAS;EACT;EACA,OAAO;;EAEP;;EAEA;;UAGe;EACf;EACA;EACA;EACA,WAAW;EACX;EACA;EACA;EACA;EACA,OAAO;;UAGQ;EACf;EACA;;UAGe;EACf,WAAW;EACX,OAAO;;UAGQ;EACf,MAAM;EACN;EACA;EACA,OAAO;EACP,QAAQ;EACR,MAAM;EACN,YAAY;;;;UCtCG;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAM;EACN,WAAW;EACX,OAAO;EACP,MAAM;EACN,YAAY;EACZ,SAAS;EACT,MAAM;EACN,SAAS;EACT,SAAS;EACT,SAAS;EACT,WAAW;EACX,UAAU;EACV,SAAS;EACT,MAAM;EACN,KAAK;;UAGU;;EAEf;;EAEA;;UAGe;EACf;EACA,MAAM;;EAEN;;EAEA;;UAGe;EACf;EACA;EACA;;UAGe;EACf;;UAGe;EACf;EACA;EACA;EACA;EACA,OAAO;;UAGQ;EACf;;UAGe;EACf;EACA;EACA;EACA,QAAQ;;UAGO;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;;UAGe;EACf,KAAK;;UAGU;EACf;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAGU;UAEK;EACf;EACA;EACA;EACA,aAAa;EACb;EACA;;UAGe;EACf;EACA;EACA;;KAGU,uBAAuB,YACjC,KAAK;EAEL,QAAQ;;KAGE,kBAAkB,YAAY,KAAK;EAC7C,QAAQ;;;;;;;;;;;;;UCvIO;;;;;;;EAOf;;;;;EAMA;;;;;;;EAQA,OAAO;;;;;;;EAQP,UAAU;;;;;;;;;EAUV;;;;;;EAOA;;;;EAKA;;;;;;EAOA;;;;EAKA,KAAK;;;;EAKL,QAAQ;;;;EAKR,QAAQ;;;;GAKP;;;;;;;;UASc;;;;;;;;;;EAUf;;;;;;;;;EAUA;;;;;;;;;EAUA;;;;;;;;;;EAWA;;;;;;;;;EAUA;;;;;;;EAQA,UAAU;;;;;;EAOV;;;;;GAMC;;;;;;;;UASc;;;;;;;EAOf;;;;;;EAOA;;;;EAKA;;;;EAKA;;;;;;;EAQA,OAAO;;;;;;EAOP;;;;GAKC;;;;;;UAOc;;;;;;;EAOf;;;;;;;EAQA;;;;GAKC;;;;;UAMc;;;;EAIf;;;;EAKA,aAAa;;;;UClQE;EACf;EACA;EACA;EACA,WAAW;;UAGI;EACf;EACA;EACA,SAAS;EACT,QAAQ;EACR,YAAY;;UAGG;EACf,MAAM;EACN,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP;EACA;EACA;EACA;EACA,oBAAoB;EACpB,oBAAoB;EACpB,yBAAyB;EACzB,2BAA2B;EAC3B,qBAAqB,cAAc;;;;UC9BpB;EACf;EACA;EACA,aAAa;EACb;EACA;EACA,eAAe;;UAGA;EACf;EACA;EACA;;UAGe;EACf,MAAM;EACN;EACA,aAAa;EACb,aAAa;EACb;EACA,MAAM;EACN,aAAa;EACb,UAAU;EACV,UAAU;EACV;EACA;;KAGU,gBACV,OAAO,sBACJ,iBAAiB,QAAQ;KAElB,kBAAkB,eAAe;;;wBCtB7B,oBAAoB,gBAAgB;wBASpC,uBACd,gBACC"}
@@ -0,0 +1,28 @@
1
+ /*! @purestack/ts-common v1.1.0 | (c) 2026 Ahmed Yasin Koculu | MIT License */
2
+
3
+ //#region packages/ts-common/src/resolveTsSsgContext.ts
4
+ function hasTsSsgContext(value) {
5
+ return typeof value === "object" && value !== null && "tsSsgContext" in value;
6
+ }
7
+ function hasContextStack(value) {
8
+ return typeof value === "object" && value !== null && "ctx" in value;
9
+ }
10
+ function resolveTsSsgContext(head) {
11
+ const stack = hasContextStack(head) && Array.isArray(head.ctx) ? head.ctx : [];
12
+ for (const ctx of stack) {
13
+ if (!hasTsSsgContext(ctx)) continue;
14
+ if (ctx.tsSsgContext) return ctx.tsSsgContext;
15
+ }
16
+ throw new Error("tsSsgContext is not available in the Regor context stack.");
17
+ }
18
+ function tryResolveTsSsgContext(head) {
19
+ const stack = hasContextStack(head) && Array.isArray(head.ctx) ? head.ctx : [];
20
+ for (const ctx of stack) {
21
+ if (!hasTsSsgContext(ctx)) continue;
22
+ if (ctx.tsSsgContext) return ctx.tsSsgContext;
23
+ }
24
+ }
25
+
26
+ //#endregion
27
+ export { resolveTsSsgContext, tryResolveTsSsgContext };
28
+ //# sourceMappingURL=ts-common.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts-common.mjs","names":[],"sources":["../src/resolveTsSsgContext.ts"],"sourcesContent":["import type { TsSsgContext } from './ts-ssg-context'\n\ntype ContextCarrier = {\n tsSsgContext?: TsSsgContext\n}\n\ntype HeadLike = {\n ctx?: unknown[]\n}\n\nfunction hasTsSsgContext(value: unknown): value is ContextCarrier {\n return typeof value === 'object' && value !== null && 'tsSsgContext' in value\n}\n\nfunction hasContextStack(value: unknown): value is HeadLike {\n return typeof value === 'object' && value !== null && 'ctx' in value\n}\n\nexport function resolveTsSsgContext(head: unknown): TsSsgContext {\n const stack = hasContextStack(head) && Array.isArray(head.ctx) ? head.ctx : []\n for (const ctx of stack) {\n if (!hasTsSsgContext(ctx)) continue\n if (ctx.tsSsgContext) return ctx.tsSsgContext\n }\n throw new Error('tsSsgContext is not available in the Regor context stack.')\n}\n\nexport function tryResolveTsSsgContext(\n head: unknown,\n): TsSsgContext | undefined {\n const stack = hasContextStack(head) && Array.isArray(head.ctx) ? head.ctx : []\n for (const ctx of stack) {\n if (!hasTsSsgContext(ctx)) continue\n if (ctx.tsSsgContext) return ctx.tsSsgContext\n }\n return undefined\n}\n"],"mappings":";AAUA,SAAS,gBAAgB,OAAyC;CAChE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,kBAAkB;AAC1E;AAEA,SAAS,gBAAgB,OAAmC;CAC1D,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,SAAS;AACjE;AAEA,SAAgB,oBAAoB,MAA6B;CAC/D,MAAM,QAAQ,gBAAgB,IAAI,KAAK,MAAM,QAAQ,KAAK,GAAG,IAAI,KAAK,MAAM,CAAC;CAC7E,KAAK,MAAM,OAAO,OAAO;EACvB,IAAI,CAAC,gBAAgB,GAAG,GAAG;EAC3B,IAAI,IAAI,cAAc,OAAO,IAAI;CACnC;CACA,MAAM,IAAI,MAAM,2DAA2D;AAC7E;AAEA,SAAgB,uBACd,MAC0B;CAC1B,MAAM,QAAQ,gBAAgB,IAAI,KAAK,MAAM,QAAQ,KAAK,GAAG,IAAI,KAAK,MAAM,CAAC;CAC7E,KAAK,MAAM,OAAO,OAAO;EACvB,IAAI,CAAC,gBAAgB,GAAG,GAAG;EAC3B,IAAI,IAAI,cAAc,OAAO,IAAI;CACnC;AAEF"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@purestack/ts-common",
3
+ "version": "1.1.0",
4
+ "packageManager": "yarn@4.9.2",
5
+ "module": "./dist/ts-common.mjs",
6
+ "types": "./dist/ts-common.d.mts",
7
+ "type": "module",
8
+ "sideEffects": false,
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/PureStackStudio/PureStack.git",
12
+ "directory": "packages/ts-common"
13
+ },
14
+ "homepage": "https://purestack.studio",
15
+ "bugs": {
16
+ "url": "https://github.com/PureStackStudio/PureStack/issues"
17
+ },
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/ts-common.d.mts",
24
+ "import": "./dist/ts-common.mjs"
25
+ }
26
+ },
27
+ "dependencies": {
28
+ "@purestack/ts-html": "^1.1.0",
29
+ "@purestack/ts-style": "^1.1.0",
30
+ "@purestack/ts-util": "^1.1.0"
31
+ },
32
+ "license": "MIT",
33
+ "files": [
34
+ "dist/*.mjs",
35
+ "dist/*.mjs.map",
36
+ "dist/*.d.mts",
37
+ "dist/*.d.mts.map",
38
+ "README.md",
39
+ "LICENSE"
40
+ ],
41
+ "scripts": {
42
+ "build": "tsc",
43
+ "lint": "biome check ./src --formatter-enabled=false --write",
44
+ "test": "vitest"
45
+ }
46
+ }