@myst-theme/common 0.4.1

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,3 @@
1
+ # @myst-theme/common
2
+
3
+ Common utilities and types for working with the MyST Theme and sites
@@ -0,0 +1,3 @@
1
+ export * from './utils.js';
2
+ export * from './types.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from './utils.js';
2
+ export * from './types.js';
@@ -0,0 +1,54 @@
1
+ import type { Root } from 'mdast';
2
+ import type { Dependency, SourceFileKind } from 'myst-spec-ext';
3
+ import type { References } from 'myst-common';
4
+ import type { SiteManifest } from 'myst-config';
5
+ import type { PageFrontmatter } from 'myst-frontmatter';
6
+ export declare enum Theme {
7
+ light = "light",
8
+ dark = "dark"
9
+ }
10
+ export declare enum ErrorStatus {
11
+ noSite = "Site was not found",
12
+ noArticle = "Article was not found"
13
+ }
14
+ export type Heading = {
15
+ slug?: string;
16
+ path?: string;
17
+ title: string;
18
+ short_title?: string;
19
+ level: number | 'index';
20
+ group?: string;
21
+ };
22
+ export type SiteLoader = {
23
+ theme: Theme;
24
+ config?: SiteManifest;
25
+ CONTENT_CDN_PORT?: string | number;
26
+ MODE?: 'app' | 'static';
27
+ BASE_URL?: string;
28
+ };
29
+ export type NavigationLink = {
30
+ group?: string;
31
+ title: string;
32
+ url: string;
33
+ short_title?: string;
34
+ };
35
+ export type FooterLinks = {
36
+ navigation?: {
37
+ prev?: NavigationLink;
38
+ next?: NavigationLink;
39
+ };
40
+ };
41
+ export type PageLoader = {
42
+ kind: SourceFileKind;
43
+ file: string;
44
+ sha256: string;
45
+ slug: string;
46
+ domain: string;
47
+ project: string;
48
+ frontmatter: PageFrontmatter;
49
+ mdast: Root;
50
+ references: References;
51
+ footer?: FooterLinks;
52
+ dependencies?: Dependency[];
53
+ };
54
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,oBAAY,KAAK;IACf,KAAK,UAAU;IACf,IAAI,SAAS;CACd;AAED,oBAAY,WAAW;IACrB,MAAM,uBAAuB;IAC7B,SAAS,0BAA0B;CACpC;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,IAAI,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,CAAC,EAAE;QACX,IAAI,CAAC,EAAE,cAAc,CAAC;QACtB,IAAI,CAAC,EAAE,cAAc,CAAC;KACvB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,eAAe,CAAC;IAC7B,KAAK,EAAE,IAAI,CAAC;IACZ,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,CAAC,EAAE,WAAW,CAAC;IAErB,YAAY,CAAC,EAAE,UAAU,EAAE,CAAC;CAC7B,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,10 @@
1
+ export var Theme;
2
+ (function (Theme) {
3
+ Theme["light"] = "light";
4
+ Theme["dark"] = "dark";
5
+ })(Theme || (Theme = {}));
6
+ export var ErrorStatus;
7
+ (function (ErrorStatus) {
8
+ ErrorStatus["noSite"] = "Site was not found";
9
+ ErrorStatus["noArticle"] = "Article was not found";
10
+ })(ErrorStatus || (ErrorStatus = {}));
@@ -0,0 +1,14 @@
1
+ import type { SiteManifest } from 'myst-config';
2
+ import type { FooterLinks, Heading, PageLoader } from './types.js';
3
+ type ManifestProject = Required<SiteManifest>['projects'][0];
4
+ export declare function getProject(config?: SiteManifest, projectSlug?: string): ManifestProject | undefined;
5
+ export declare function getProjectHeadings(config: SiteManifest, projectSlug?: string, opts?: {
6
+ addGroups: boolean;
7
+ }): Heading[] | undefined;
8
+ export declare function getFooterLinks(config?: SiteManifest, projectSlug?: string, slug?: string): FooterLinks;
9
+ type UpdateUrl = (url: string) => string;
10
+ export declare function updateSiteManifestStaticLinksInplace(data: SiteManifest, updateUrl: UpdateUrl): SiteManifest;
11
+ export declare function updatePageStaticLinksInplace(data: PageLoader, updateUrl: UpdateUrl): PageLoader;
12
+ export declare function isFlatSite(config?: SiteManifest): boolean;
13
+ export {};
14
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAkB,UAAU,EAAE,MAAM,YAAY,CAAC;AAMnF,KAAK,eAAe,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAG7D,wBAAgB,UAAU,CACxB,MAAM,CAAC,EAAE,YAAY,EACrB,WAAW,CAAC,EAAE,MAAM,GACnB,eAAe,GAAG,SAAS,CAK7B;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EACpB,WAAW,CAAC,EAAE,MAAM,EACpB,IAAI,GAAE;IAAE,SAAS,EAAE,OAAO,CAAA;CAAyB,GAClD,OAAO,EAAE,GAAG,SAAS,CA0BvB;AAeD,wBAAgB,cAAc,CAC5B,MAAM,CAAC,EAAE,YAAY,EACrB,WAAW,CAAC,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,MAAM,GACZ,WAAW,CAab;AAED,KAAK,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;AAEzC,wBAAgB,oCAAoC,CAClD,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,SAAS,GACnB,YAAY,CA6Bd;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,UAAU,CA4C/F;AAED,wBAAgB,UAAU,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAEzD"}
package/dist/utils.js ADDED
@@ -0,0 +1,164 @@
1
+ import { walkOutputs } from 'nbtx';
2
+ import { selectAll } from 'unist-util-select';
3
+ export function getProject(config, projectSlug) {
4
+ var _a, _b;
5
+ if (!config)
6
+ return undefined;
7
+ if (!projectSlug)
8
+ return (_a = config.projects) === null || _a === void 0 ? void 0 : _a[0];
9
+ const project = (_b = config.projects) === null || _b === void 0 ? void 0 : _b.find((p) => p.slug === projectSlug);
10
+ return project;
11
+ }
12
+ export function getProjectHeadings(config, projectSlug, opts = { addGroups: false }) {
13
+ const project = getProject(config, projectSlug);
14
+ if (!project)
15
+ return undefined;
16
+ const headings = [
17
+ {
18
+ title: project.title,
19
+ short_title: project.short_title,
20
+ slug: project.index,
21
+ path: project.slug ? `/${project.slug}` : '/',
22
+ level: 'index',
23
+ },
24
+ ...project.pages.map((p) => {
25
+ if (!('slug' in p))
26
+ return p;
27
+ return { ...p, path: projectSlug ? `/${project.slug}/${p.slug}` : `/${p.slug}` };
28
+ }),
29
+ ];
30
+ if (opts.addGroups) {
31
+ let lastTitle = project.short_title || project.title;
32
+ return headings.map((heading) => {
33
+ if (!heading.slug || heading.level === 'index') {
34
+ lastTitle = heading.short_title || heading.title;
35
+ }
36
+ return { ...heading, group: lastTitle };
37
+ });
38
+ }
39
+ return headings;
40
+ }
41
+ function getHeadingLink(currentSlug, headings) {
42
+ if (!headings)
43
+ return undefined;
44
+ const linkIndex = headings.findIndex(({ slug }) => !!slug && slug !== currentSlug);
45
+ const link = headings[linkIndex];
46
+ if (!(link === null || link === void 0 ? void 0 : link.path))
47
+ return undefined;
48
+ return {
49
+ title: link.title,
50
+ short_title: link.short_title,
51
+ url: link.path,
52
+ group: link.group,
53
+ };
54
+ }
55
+ export function getFooterLinks(config, projectSlug, slug) {
56
+ var _a;
57
+ if (!slug || !config)
58
+ return {};
59
+ const pages = getProjectHeadings(config, projectSlug, {
60
+ addGroups: true,
61
+ });
62
+ const found = (_a = pages === null || pages === void 0 ? void 0 : pages.findIndex(({ slug: s }) => s === slug)) !== null && _a !== void 0 ? _a : -1;
63
+ if (found === -1)
64
+ return {};
65
+ const prev = getHeadingLink(slug, pages === null || pages === void 0 ? void 0 : pages.slice(0, found).reverse());
66
+ const next = getHeadingLink(slug, pages === null || pages === void 0 ? void 0 : pages.slice(found + 1));
67
+ const footer = {
68
+ navigation: { prev, next },
69
+ };
70
+ return footer;
71
+ }
72
+ export function updateSiteManifestStaticLinksInplace(data, updateUrl) {
73
+ var _a, _b;
74
+ (_a = data.actions) === null || _a === void 0 ? void 0 : _a.forEach((action) => {
75
+ if (!action.static)
76
+ return;
77
+ action.url = updateUrl(action.url);
78
+ });
79
+ // TODO: this needs to be based on the template.yml in the future
80
+ if (data.logo)
81
+ data.logo = updateUrl(data.logo);
82
+ if (data.logo_dark)
83
+ data.logo_dark = updateUrl(data.logo_dark);
84
+ // Update the thumbnails to point at the CDN
85
+ (_b = data.projects) === null || _b === void 0 ? void 0 : _b.forEach((project) => {
86
+ if (project.banner)
87
+ project.banner = updateUrl(project.banner);
88
+ if (project.bannerOptimized)
89
+ project.bannerOptimized = updateUrl(project.bannerOptimized);
90
+ if (project.thumbnail)
91
+ project.thumbnail = updateUrl(project.thumbnail);
92
+ if (project.thumbnailOptimized)
93
+ project.thumbnailOptimized = updateUrl(project.thumbnailOptimized);
94
+ if (project === null || project === void 0 ? void 0 : project.exports) {
95
+ project.exports = project.exports.map((exp) => {
96
+ if (!exp.url)
97
+ return exp;
98
+ return { ...exp, url: updateUrl(exp.url) };
99
+ });
100
+ }
101
+ project.pages
102
+ .filter((page) => 'slug' in page)
103
+ .forEach((page) => {
104
+ if (page.thumbnail)
105
+ page.thumbnail = updateUrl(page.thumbnail);
106
+ if (page.thumbnailOptimized)
107
+ page.thumbnailOptimized = updateUrl(page.thumbnailOptimized);
108
+ });
109
+ });
110
+ return data;
111
+ }
112
+ export function updatePageStaticLinksInplace(data, updateUrl) {
113
+ var _a, _b, _c, _d, _e;
114
+ if ((_a = data === null || data === void 0 ? void 0 : data.frontmatter) === null || _a === void 0 ? void 0 : _a.thumbnail) {
115
+ data.frontmatter.thumbnail = updateUrl(data.frontmatter.thumbnail);
116
+ }
117
+ if ((_b = data === null || data === void 0 ? void 0 : data.frontmatter) === null || _b === void 0 ? void 0 : _b.thumbnailOptimized) {
118
+ data.frontmatter.thumbnailOptimized = updateUrl(data.frontmatter.thumbnailOptimized);
119
+ }
120
+ if ((_c = data === null || data === void 0 ? void 0 : data.frontmatter) === null || _c === void 0 ? void 0 : _c.banner) {
121
+ data.frontmatter.banner = updateUrl(data.frontmatter.banner);
122
+ }
123
+ if ((_d = data === null || data === void 0 ? void 0 : data.frontmatter) === null || _d === void 0 ? void 0 : _d.bannerOptimized) {
124
+ data.frontmatter.bannerOptimized = updateUrl(data.frontmatter.bannerOptimized);
125
+ }
126
+ if ((_e = data === null || data === void 0 ? void 0 : data.frontmatter) === null || _e === void 0 ? void 0 : _e.exports) {
127
+ data.frontmatter.exports = data.frontmatter.exports.map((exp) => {
128
+ if (!exp.url)
129
+ return exp;
130
+ return { ...exp, url: updateUrl(exp.url) };
131
+ });
132
+ }
133
+ // Fix all of the images to point to the CDN
134
+ const images = selectAll('image', data.mdast);
135
+ images.forEach((node) => {
136
+ node.url = updateUrl(node.url);
137
+ if (node.urlOptimized) {
138
+ node.urlOptimized = updateUrl(node.urlOptimized);
139
+ }
140
+ });
141
+ const links = selectAll('link,linkBlock,card', data.mdast);
142
+ const staticLinks = links.filter((node) => node.static);
143
+ staticLinks.forEach((node) => {
144
+ // These are static links to thinks like PDFs or other referenced files
145
+ node.url = updateUrl(node.url);
146
+ });
147
+ const outputs = selectAll('output', data.mdast);
148
+ outputs.forEach((node) => {
149
+ if (!node.data)
150
+ return;
151
+ walkOutputs(node.data, (obj) => {
152
+ // The path will be defined from output of myst
153
+ // Here we are re-assigning it to the current domain
154
+ if (!obj.path)
155
+ return;
156
+ obj.path = updateUrl(obj.path);
157
+ });
158
+ });
159
+ return data;
160
+ }
161
+ export function isFlatSite(config) {
162
+ var _a;
163
+ return ((_a = config === null || config === void 0 ? void 0 : config.projects) === null || _a === void 0 ? void 0 : _a.length) === 1 && !config.projects[0].slug;
164
+ }
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@myst-theme/common",
3
+ "version": "0.4.1",
4
+ "type": "module",
5
+ "exports": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "license": "MIT",
11
+ "sideEffects": false,
12
+ "scripts": {
13
+ "clean": "rimraf dist",
14
+ "lint": "eslint \"src/**/*.ts*\" -c ./.eslintrc.cjs",
15
+ "lint:format": "prettier --check \"src/**/*.{ts,tsx,md}\"",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest watch",
18
+ "build:esm": "tsc --project ./tsconfig.json --module es2015 --outDir dist --declaration",
19
+ "build": "npm-run-all -l clean -p build:esm"
20
+ },
21
+ "dependencies": {
22
+ "myst-common": "^1.1.0",
23
+ "myst-config": "^1.1.0",
24
+ "myst-spec-ext": "^1.1.0",
25
+ "nbtx": "^0.2.3",
26
+ "unist-util-select": "^4.0.3"
27
+ }
28
+ }