starlight-obsidian 0.6.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # starlight-obsidian
2
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
+
3
9
  ## 0.6.0
4
10
 
5
11
  ### Minor Changes
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/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,7 +280,7 @@ 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
+ function isSidebarGroup(item: SidebarItem): item is SidebarManualGroup {
283
284
  return typeof item === 'object' && 'items' in item
284
285
  }
285
286
 
@@ -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>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starlight-obsidian",
3
- "version": "0.6.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)",