starlight-obsidian 0.5.0 → 0.7.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/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ # starlight-obsidian
2
+
3
+ ## 0.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#37](https://github.com/HiDeoo/starlight-obsidian/pull/37) [`96f7cef`](https://github.com/HiDeoo/starlight-obsidian/commit/96f7cef43c4a08923c24221fbfb95b4ef840779f) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Adds support for running [multiple instances](https://starlight-obsidian.vercel.app/guides/multiple-instances/) of the plugin for different Obsidian vaults and configurations.
8
+
9
+ ## 0.6.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#34](https://github.com/HiDeoo/starlight-obsidian/pull/34) [`9079b9b`](https://github.com/HiDeoo/starlight-obsidian/commit/9079b9be67eb2efd68a3d8906068263657629974) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Adds support for Astro v5, drops support for Astro v4.
14
+
15
+ ⚠️ **BREAKING CHANGE:** The minimum supported version of Starlight is now `0.30.0`.
16
+
17
+ Please follow the [upgrade guide](https://github.com/withastro/starlight/releases/tag/%40astrojs/starlight%400.30.0) to update your project.
package/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { randomBytes } from 'node:crypto'
2
+
1
3
  import type { StarlightPlugin, StarlightUserConfig } from '@astrojs/starlight/types'
2
4
  import type { AstroIntegrationLogger } from 'astro'
3
5
  import { z } from 'astro/zod'
@@ -5,7 +7,7 @@ import { z } from 'astro/zod'
5
7
  import { starlightObsidianIntegration } from './libs/integration'
6
8
  import { getObsidianPaths, getVault } from './libs/obsidian'
7
9
  import { throwUserError } from './libs/plugin'
8
- import { addObsidianFiles, getSidebarFromConfig, getSidebarGroupPlaceholder } from './libs/starlight'
10
+ import { addObsidianFiles, getSidebarFromConfig, getSidebarGroupPlaceholder, type SidebarGroup } from './libs/starlight'
9
11
 
10
12
  const starlightObsidianConfigSchema = z.object({
11
13
  /**
@@ -104,100 +106,119 @@ const starlightObsidianConfigSchema = z.object({
104
106
  vault: z.string(),
105
107
  })
106
108
 
109
+ let pluginsCount = 0
110
+
107
111
  export const obsidianSidebarGroup = getSidebarGroupPlaceholder()
108
112
 
109
113
  export default function starlightObsidianPlugin(userConfig: StarlightObsidianUserConfig): StarlightPlugin {
110
- const parsedConfig = starlightObsidianConfigSchema.safeParse(userConfig)
114
+ return makeStarlightObsidianPlugin(obsidianSidebarGroup)(userConfig)
115
+ }
116
+
117
+ export function createStarlightObsidianPlugin(): [plugin: typeof starlightObsidianPlugin, sidebarGroup: SidebarGroup] {
118
+ const sidebarGroup = getSidebarGroupPlaceholder(Symbol(randomBytes(24).toString('base64url')))
119
+ return [makeStarlightObsidianPlugin(sidebarGroup), sidebarGroup]
120
+ }
121
+
122
+ function makeStarlightObsidianPlugin(
123
+ sidebarGroup: SidebarGroup,
124
+ ): (userConfig: StarlightObsidianUserConfig) => StarlightPlugin {
125
+ pluginsCount++
126
+
127
+ return function starlightObsidianPlugin(userConfig) {
128
+ const parsedConfig = starlightObsidianConfigSchema.safeParse(userConfig)
111
129
 
112
- if (!parsedConfig.success) {
113
- const isUsingDeprecatedCopyStarlightFrontmatter = parsedConfig.error.issues.some(
114
- (issue) => issue.path.join('.') === 'copyStarlightFrontmatter',
115
- )
130
+ if (!parsedConfig.success) {
131
+ const isUsingDeprecatedCopyStarlightFrontmatter = parsedConfig.error.issues.some(
132
+ (issue) => issue.path.join('.') === 'copyStarlightFrontmatter',
133
+ )
134
+
135
+ if (isUsingDeprecatedCopyStarlightFrontmatter) {
136
+ throwUserError(
137
+ 'The `copyStarlightFrontmatter` option has been deprecated in favor of the `copyFrontmatter` option.',
138
+ 'For more information see https://starlight-obsidian.vercel.app/configuration/#copyfrontmatter',
139
+ )
140
+ }
116
141
 
117
- if (isUsingDeprecatedCopyStarlightFrontmatter) {
118
142
  throwUserError(
119
- 'The `copyStarlightFrontmatter` option has been deprecated in favor of the `copyFrontmatter` option.',
120
- 'For more information see https://starlight-obsidian.vercel.app/configuration/#copyfrontmatter',
143
+ `The provided plugin configuration is invalid.\n${parsedConfig.error.issues.map((issue) => issue.message).join('\n')}`,
121
144
  )
122
145
  }
123
146
 
124
- throwUserError(
125
- `The provided plugin configuration is invalid.\n${parsedConfig.error.issues.map((issue) => issue.message).join('\n')}`,
126
- )
127
- }
147
+ const config = parsedConfig.data
148
+
149
+ return {
150
+ name: 'starlight-obsidian-plugin',
151
+ hooks: {
152
+ async setup({ addIntegration, command, config: starlightConfig, logger, updateConfig }) {
153
+ if (command !== 'build' && command !== 'dev') {
154
+ return
155
+ }
156
+
157
+ const customCss = [...(starlightConfig.customCss ?? []), 'starlight-obsidian/styles/common']
158
+
159
+ if (config.autoLinkHeadings) {
160
+ customCss.push('starlight-obsidian/styles/autolinks-headings')
161
+ }
162
+
163
+ const updatedStarlightConfig: Partial<StarlightUserConfig> = {
164
+ components: starlightConfig.components,
165
+ customCss,
166
+ sidebar: getSidebarFromConfig(config, starlightConfig.sidebar, sidebarGroup),
167
+ }
128
168
 
129
- const config = parsedConfig.data
130
-
131
- return {
132
- name: 'starlight-obsidian-plugin',
133
- hooks: {
134
- async setup({ addIntegration, command, config: starlightConfig, logger, updateConfig }) {
135
- if (command !== 'build' && command !== 'dev') {
136
- return
137
- }
138
-
139
- const customCss = [...(starlightConfig.customCss ?? []), 'starlight-obsidian/styles/common']
140
-
141
- if (config.autoLinkHeadings) {
142
- customCss.push('starlight-obsidian/styles/autolinks-headings')
143
- }
144
-
145
- const updatedStarlightConfig: Partial<StarlightUserConfig> = {
146
- components: starlightConfig.components,
147
- customCss,
148
- sidebar: getSidebarFromConfig(config, starlightConfig.sidebar),
149
- }
150
-
151
- if (!updatedStarlightConfig.components) {
152
- updatedStarlightConfig.components = {}
153
- }
154
-
155
- if (starlightConfig.components?.PageTitle) {
156
- logComponentOverrideWarning(logger, 'PageTitle')
157
- } else {
158
- updatedStarlightConfig.components.PageTitle = 'starlight-obsidian/overrides/PageTitle.astro'
159
- }
160
-
161
- if (config.tableOfContentsOverview === 'title') {
162
- if (starlightConfig.components?.PageSidebar) {
163
- logComponentOverrideWarning(logger, 'PageSidebar')
169
+ if (!updatedStarlightConfig.components) {
170
+ updatedStarlightConfig.components = {}
171
+ }
172
+
173
+ if (starlightConfig.components?.PageTitle) {
174
+ logComponentOverrideWarning(logger, 'PageTitle')
164
175
  } else {
165
- updatedStarlightConfig.components.PageSidebar = 'starlight-obsidian/overrides/PageSidebar.astro'
176
+ updatedStarlightConfig.components.PageTitle = 'starlight-obsidian/overrides/PageTitle.astro'
177
+ }
178
+
179
+ if (config.tableOfContentsOverview === 'title') {
180
+ if (starlightConfig.components?.PageSidebar) {
181
+ logComponentOverrideWarning(logger, 'PageSidebar')
182
+ } else {
183
+ updatedStarlightConfig.components.PageSidebar = 'starlight-obsidian/overrides/PageSidebar.astro'
184
+ }
166
185
  }
167
- }
168
-
169
- if (config.skipGeneration) {
170
- logger.warn(
171
- `Skipping generation of Starlight pages from Obsidian vault as the 'skipGeneration' option is enabled.`,
172
- )
173
- } else {
174
- try {
175
- const start = performance.now()
176
- logger.info('Generating Starlight pages from Obsidian vault…')
177
-
178
- const vault = await getVault(config)
179
- const obsidianPaths = await getObsidianPaths(vault, config.ignore)
180
- await addObsidianFiles(config, vault, obsidianPaths, logger)
181
-
182
- const duration = Math.round(performance.now() - start)
183
- logger.info(`Starlight pages generated from Obsidian vault in ${duration}ms.`)
184
- } catch (error) {
185
- logger.error(error instanceof Error ? error.message : String(error))
186
-
187
- throwUserError('Failed to generate Starlight pages from Obsidian vault.')
186
+
187
+ if (config.skipGeneration) {
188
+ logger.warn(
189
+ `Skipping generation of Starlight pages from Obsidian vault as the 'skipGeneration' option is enabled.`,
190
+ )
191
+ } else {
192
+ try {
193
+ const start = performance.now()
194
+ logger.info(`Generating Starlight pages from Obsidian vault at '${config.vault}'…`)
195
+
196
+ const vault = await getVault(config)
197
+ const obsidianPaths = await getObsidianPaths(vault, config.ignore)
198
+ await addObsidianFiles(config, vault, obsidianPaths, logger)
199
+
200
+ const duration = Math.round(performance.now() - start)
201
+ logger.info(`Starlight pages generated from Obsidian vault at '${config.vault}' in ${duration}ms.`)
202
+ } catch (error) {
203
+ logger.error(error instanceof Error ? error.message : String(error))
204
+
205
+ throwUserError(`Failed to generate Starlight pages from Obsidian vault at '${config.vault}'.`)
206
+ }
188
207
  }
189
- }
190
208
 
191
- addIntegration(starlightObsidianIntegration(config))
192
- updateConfig(updatedStarlightConfig)
209
+ addIntegration(starlightObsidianIntegration(config))
210
+ updateConfig(updatedStarlightConfig)
211
+ },
193
212
  },
194
- },
213
+ }
195
214
  }
196
215
  }
197
216
 
198
217
  function logComponentOverrideWarning(logger: AstroIntegrationLogger, component: string) {
199
- logger.warn(`It looks like you already have a \`${component}\` component override in your Starlight configuration.`)
200
- logger.warn(`To use \`starlight-obsidian\`, remove the override for the \`${component}\` component.\n`)
218
+ if (pluginsCount < 2) {
219
+ logger.warn(`It looks like you already have a \`${component}\` component override in your Starlight configuration.`)
220
+ logger.warn(`To use \`starlight-obsidian\`, remove the override for the \`${component}\` component.\n`)
221
+ }
201
222
  }
202
223
 
203
224
  export type StarlightObsidianUserConfig = z.input<typeof starlightObsidianConfigSchema>
package/libs/obsidian.ts CHANGED
@@ -224,8 +224,8 @@ interface BaseVaultFile {
224
224
  }
225
225
 
226
226
  export interface VaultFile extends BaseVaultFile {
227
- isEqualFileName(otherFileName: string): boolean
228
- isEqualStem(otherStem: string): boolean
227
+ isEqualFileName: (otherFileName: string) => boolean
228
+ isEqualStem: (otherStem: string) => boolean
229
229
  }
230
230
 
231
231
  export type ObsidianFrontmatter = z.output<typeof obsidianFrontmatterSchema> & {
package/libs/rehype.ts CHANGED
@@ -82,7 +82,7 @@ function isNodeWithValue(node: ElementContent | undefined): node is NodeWithValu
82
82
  }
83
83
 
84
84
  function getBlockIdentifer(node: NodeWithValue): { length: number; name: string } | undefined {
85
- const match = node.value.match(blockIdentifierRegex)
85
+ const match = blockIdentifierRegex.exec(node.value)
86
86
  const identifier = match?.groups?.['identifier']
87
87
  const name = match?.groups?.['name']
88
88
 
package/libs/remark.ts CHANGED
@@ -377,7 +377,7 @@ function handleBlockquotes(node: Blockquote, context: VisitorContext) {
377
377
  return SKIP
378
378
  }
379
379
 
380
- const match = firstLine.match(calloutRegex)
380
+ const match = calloutRegex.exec(firstLine)
381
381
 
382
382
  const { title, type } = match?.groups ?? {}
383
383
 
@@ -566,7 +566,7 @@ function handleImagesWithSize(node: Image, context: VisitorContext, type: 'asset
566
566
  return
567
567
  }
568
568
 
569
- const match = node.alt.match(imageSizeRegex)
569
+ const match = imageSizeRegex.exec(node.alt)
570
570
  const { altText, width, widthOnly, height } = match?.groups ?? {}
571
571
 
572
572
  if (widthOnly === undefined && width === undefined) {
package/libs/starlight.ts CHANGED
@@ -66,23 +66,24 @@ const starlightFrontmatterKeys = [
66
66
  'sidebar',
67
67
  ]
68
68
 
69
- export function getSidebarGroupPlaceholder(): SidebarManualGroup {
69
+ export function getSidebarGroupPlaceholder(label = starlightObsidianSidebarGroupLabel): SidebarManualGroup {
70
70
  return {
71
71
  items: [],
72
- label: starlightObsidianSidebarGroupLabel.toString(),
72
+ label: label.toString(),
73
73
  }
74
74
  }
75
75
 
76
76
  export function getSidebarFromConfig(
77
77
  config: StarlightObsidianConfig,
78
78
  sidebar: StarlightUserConfig['sidebar'],
79
+ sidebarGroupPlaceholder: SidebarGroup,
79
80
  ): StarlightUserConfig['sidebar'] {
80
81
  if (!sidebar || sidebar.length === 0) {
81
82
  return sidebar
82
83
  }
83
84
 
84
- function replaceSidebarGroupPlaceholder(group: SidebarManualGroup): SidebarGroup {
85
- if (group.label === starlightObsidianSidebarGroupLabel.toString()) {
85
+ function replaceSidebarGroupPlaceholder(group: SidebarManualGroup): SidebarItem {
86
+ if (group.label === sidebarGroupPlaceholder.label) {
86
87
  return {
87
88
  autogenerate: {
88
89
  collapsed: config.sidebar.collapsedFolders ?? config.sidebar.collapsed,
@@ -279,8 +280,8 @@ function throwVaultFileError(error: unknown, vaultFile: VaultFile): never {
279
280
  throw new Error(`${vaultFile.path} — ${error instanceof Error ? error.message : String(error)}`, { cause: error })
280
281
  }
281
282
 
282
- function isSidebarGroup(item: SidebarGroup): item is SidebarManualGroup {
283
- return 'items' in item
283
+ function isSidebarGroup(item: SidebarItem): item is SidebarManualGroup {
284
+ return typeof item === 'object' && 'items' in item
284
285
  }
285
286
 
286
287
  interface OutputPaths {
@@ -294,4 +295,5 @@ interface SidebarManualGroup {
294
295
  label: string
295
296
  }
296
297
 
297
- type SidebarGroup = NonNullable<StarlightUserConfig['sidebar']>[number]
298
+ type SidebarItem = NonNullable<StarlightUserConfig['sidebar']>[number]
299
+ export type SidebarGroup = Exclude<SidebarItem, string>
@@ -6,6 +6,7 @@ import Tags from '../components/Tags.astro'
6
6
 
7
7
  const { entry } = Astro.props
8
8
 
9
+ // @ts-expect-error - This plugin does not extend Starlight's schema so tags are unknown.
9
10
  const tags = entry['data']['tags']
10
11
  const showTags = tags !== undefined && tags.length > 0
11
12
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starlight-obsidian",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "license": "MIT",
5
5
  "description": "Starlight plugin to publish Obsidian vaults.",
6
6
  "author": "HiDeoo <github@hideoo.dev> (https://hideoo.dev)",
@@ -17,53 +17,52 @@
17
17
  "./package.json": "./package.json"
18
18
  },
19
19
  "dependencies": {
20
- "@astro-community/astro-embed-twitter": "0.5.3",
21
- "@astro-community/astro-embed-youtube": "0.4.4",
22
- "@astrojs/markdown-remark": "4.2.1",
23
- "decode-uri-component": "0.4.1",
24
- "github-slugger": "2.0.0",
25
- "globby": "14.0.0",
26
- "hast-util-to-html": "9.0.0",
27
- "hast-util-to-string": "3.0.0",
28
- "hastscript": "9.0.0",
29
- "html-escaper": "3.0.3",
30
- "is-absolute-url": "4.0.1",
31
- "mdast-util-find-and-replace": "3.0.1",
32
- "mdast-util-from-markdown": "2.0.0",
33
- "mdast-util-to-hast": "13.1.0",
34
- "nanoid": "5.0.4",
35
- "rehype": "13.0.1",
36
- "rehype-autolink-headings": "7.1.0",
37
- "rehype-katex": "7.0.0",
38
- "rehype-mermaid": "2.1.0",
39
- "remark": "15.0.1",
40
- "remark-frontmatter": "5.0.0",
41
- "remark-gfm": "4.0.0",
42
- "remark-math": "6.0.0",
43
- "unist-util-visit": "5.0.0",
44
- "vfile": "6.0.1",
45
- "yaml": "2.3.4"
20
+ "@astro-community/astro-embed-twitter": "^0.5.8",
21
+ "@astro-community/astro-embed-youtube": "^0.5.6",
22
+ "@astrojs/markdown-remark": "^6.0.0",
23
+ "decode-uri-component": "^0.4.1",
24
+ "github-slugger": "^2.0.0",
25
+ "globby": "^14.0.2",
26
+ "hast-util-to-html": "^9.0.4",
27
+ "hast-util-to-string": "^3.0.1",
28
+ "hastscript": "^9.0.0",
29
+ "html-escaper": "^3.0.3",
30
+ "is-absolute-url": "^4.0.1",
31
+ "mdast-util-find-and-replace": "^3.0.1",
32
+ "mdast-util-from-markdown": "^2.0.2",
33
+ "mdast-util-to-hast": "^13.2.0",
34
+ "nanoid": "^5.0.9",
35
+ "rehype": "^13.0.2",
36
+ "rehype-autolink-headings": "^7.1.0",
37
+ "rehype-katex": "^7.0.1",
38
+ "rehype-mermaid": "^2.1.0",
39
+ "remark": "^15.0.1",
40
+ "remark-frontmatter": "^5.0.0",
41
+ "remark-gfm": "^4.0.0",
42
+ "remark-math": "^6.0.0",
43
+ "unist-util-visit": "^5.0.0",
44
+ "vfile": "^6.0.3",
45
+ "yaml": "^2.6.1"
46
46
  },
47
47
  "devDependencies": {
48
- "@astrojs/starlight": "0.24.4",
49
- "@types/hast": "3.0.3",
50
- "@types/html-escaper": "3.0.2",
51
- "@types/mdast": "4.0.3",
52
- "@types/unist": "3.0.2",
53
- "astro": "4.11.1",
54
- "typescript": "5.3.3",
55
- "vitest": "1.2.1"
48
+ "@types/hast": "^3.0.4",
49
+ "@types/html-escaper": "^3.0.2",
50
+ "@types/mdast": "^4.0.4",
51
+ "@types/node": "^18.19.68",
52
+ "@types/unist": "^3.0.3",
53
+ "typescript": "^5.7.2",
54
+ "vitest": "2.1.6"
56
55
  },
57
56
  "peerDependencies": {
58
- "@astrojs/starlight": ">=0.15.0",
59
- "astro": ">=4.0.0"
57
+ "@astrojs/starlight": ">=0.30.0"
60
58
  },
61
59
  "engines": {
62
- "node": ">=18.14.1"
60
+ "node": ">=18.17.1"
63
61
  },
64
62
  "packageManager": "pnpm@8.14.1",
65
63
  "publishConfig": {
66
- "access": "public"
64
+ "access": "public",
65
+ "provenance": true
67
66
  },
68
67
  "sideEffects": false,
69
68
  "keywords": [
@@ -77,11 +76,12 @@
77
76
  "homepage": "https://github.com/HiDeoo/starlight-obsidian",
78
77
  "repository": {
79
78
  "type": "git",
80
- "url": "https://github.com/HiDeoo/starlight-obsidian.git"
79
+ "url": "https://github.com/HiDeoo/starlight-obsidian.git",
80
+ "directory": "packages/starlight-obsidian"
81
81
  },
82
82
  "bugs": "https://github.com/HiDeoo/starlight-obsidian/issues",
83
83
  "scripts": {
84
84
  "test": "vitest",
85
- "lint": "prettier -c --cache . && eslint . --cache --max-warnings=0"
85
+ "lint": "eslint . --cache --max-warnings=0"
86
86
  }
87
87
  }