@imjp/writenex-astro 0.1.0 → 1.3.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.
Files changed (99) hide show
  1. package/README.md +13 -13
  2. package/dist/{chunk-CYLDJ3HZ.js → chunk-GIS7XEJF.js} +4 -4
  3. package/dist/{chunk-CYLDJ3HZ.js.map → chunk-GIS7XEJF.js.map} +1 -1
  4. package/dist/{chunk-7XU5X6CW.js → chunk-GUUSVFBP.js} +12 -12
  5. package/dist/chunk-GUUSVFBP.js.map +1 -0
  6. package/dist/{chunk-XNTQTTJU.js → chunk-JFQQJPDF.js} +2 -2
  7. package/dist/{chunk-XNTQTTJU.js.map → chunk-JFQQJPDF.js.map} +1 -1
  8. package/dist/{chunk-CF2XXJFF.js → chunk-OWYFIQFK.js} +436 -436
  9. package/dist/chunk-OWYFIQFK.js.map +1 -0
  10. package/dist/{chunk-5PM6EQE5.js → chunk-S2OUQLMK.js} +7 -5
  11. package/dist/chunk-S2OUQLMK.js.map +1 -0
  12. package/dist/{chunk-AAOQHQPU.js → chunk-TQAYIZOA.js} +5 -5
  13. package/dist/{chunk-AAOQHQPU.js.map → chunk-TQAYIZOA.js.map} +1 -1
  14. package/dist/{chunk-CRPZUUDU.js → chunk-YBCPOLMY.js} +1 -1
  15. package/dist/{chunk-CRPZUUDU.js.map → chunk-YBCPOLMY.js.map} +1 -1
  16. package/dist/client/index.css +1 -1
  17. package/dist/client/index.css.map +1 -1
  18. package/dist/client/index.d.ts +19 -0
  19. package/dist/client/index.js +159 -147
  20. package/dist/client/index.js.map +1 -1
  21. package/dist/client/styles.css +2 -8
  22. package/dist/config/index.d.ts +2 -2
  23. package/dist/config/index.js +2 -2
  24. package/dist/{config-BmEdBDo_.d.ts → config-CliL0CoN.d.ts} +1 -1
  25. package/dist/{content-BWR52vD-.d.ts → content-TuL3GT66.d.ts} +1 -1
  26. package/dist/discovery/index.d.ts +2 -2
  27. package/dist/discovery/index.js +3 -3
  28. package/dist/filesystem/index.d.ts +703 -703
  29. package/dist/filesystem/index.js +4 -4
  30. package/dist/filesystem/index.js.map +1 -1
  31. package/dist/index.d.ts +4 -4
  32. package/dist/index.js +7 -7
  33. package/dist/index.js.map +1 -1
  34. package/dist/{loader-55LWCXHA.js → loader-VGNXC2XJ.js} +3 -3
  35. package/dist/schema-DDJyoVkj.d.ts +189 -0
  36. package/dist/server/index.d.ts +37 -37
  37. package/dist/server/index.js +5 -5
  38. package/package.json +17 -18
  39. package/src/client/App.tsx +18 -18
  40. package/src/client/components/ConfigPanel/ConfigPanel.tsx +14 -13
  41. package/src/client/components/CreateContentModal/CreateContentModal.tsx +1 -1
  42. package/src/client/components/Editor/Editor.tsx +27 -27
  43. package/src/client/components/Editor/ImageDialog.tsx +4 -3
  44. package/src/client/components/Editor/LinkDialog.tsx +7 -6
  45. package/src/client/components/Editor/index.ts +1 -1
  46. package/src/client/components/FrontmatterForm/FrontmatterForm.css +1 -1
  47. package/src/client/components/FrontmatterForm/FrontmatterForm.tsx +1 -1
  48. package/src/client/components/Header/Header.tsx +8 -8
  49. package/src/client/components/KeyboardShortcuts/KeyboardShortcuts.tsx +1 -1
  50. package/src/client/components/LazyEditor.tsx +1 -1
  51. package/src/client/components/LiveRegion/index.ts +1 -1
  52. package/src/client/components/SearchReplace/SearchReplacePanel.tsx +5 -5
  53. package/src/client/components/SearchReplace/index.ts +1 -1
  54. package/src/client/components/SelectCollectionModal/SelectCollectionModal.tsx +2 -2
  55. package/src/client/components/Sidebar/Sidebar.tsx +6 -6
  56. package/src/client/components/SkipLink/index.ts +1 -1
  57. package/src/client/components/UnsavedChangesModal/UnsavedChangesModal.tsx +1 -1
  58. package/src/client/components/VersionHistory/DiffViewer.tsx +18 -11
  59. package/src/client/components/VersionHistory/VersionActions.tsx +6 -6
  60. package/src/client/components/VersionHistory/VersionHistoryPanel.tsx +10 -10
  61. package/src/client/components/VersionHistory/index.ts +2 -2
  62. package/src/client/context/ApiContext.tsx +2 -2
  63. package/src/client/context/ThemeContext.tsx +2 -2
  64. package/src/client/hooks/useApi.ts +1 -1
  65. package/src/client/hooks/useFocusTrap.ts +1 -1
  66. package/src/client/hooks/useSearch.ts +1 -1
  67. package/src/client/hooks/useVersionHistory.ts +2 -2
  68. package/src/client/index.tsx +1 -1
  69. package/src/client/styles.css +2 -8
  70. package/src/config/defaults.ts +4 -4
  71. package/src/config/index.ts +14 -16
  72. package/src/config/loader.ts +6 -4
  73. package/src/config/schema.ts +8 -4
  74. package/src/core/index.ts +1 -1
  75. package/src/discovery/collections.ts +3 -3
  76. package/src/discovery/index.ts +9 -11
  77. package/src/discovery/patterns.ts +2 -2
  78. package/src/discovery/schema.ts +1 -1
  79. package/src/filesystem/images.ts +3 -3
  80. package/src/filesystem/index.ts +74 -79
  81. package/src/filesystem/reader.ts +2 -2
  82. package/src/filesystem/version-config.ts +10 -10
  83. package/src/filesystem/versions.ts +9 -9
  84. package/src/filesystem/watcher.ts +1 -1
  85. package/src/filesystem/writer.ts +6 -6
  86. package/src/global.d.ts +39 -0
  87. package/src/index.ts +10 -10
  88. package/src/integration.ts +2 -2
  89. package/src/server/assets.ts +3 -3
  90. package/src/server/cache.ts +1 -1
  91. package/src/server/index.ts +12 -15
  92. package/src/server/middleware.ts +3 -3
  93. package/src/server/routes.ts +28 -28
  94. package/src/types/index.ts +24 -28
  95. package/dist/chunk-5PM6EQE5.js.map +0 -1
  96. package/dist/chunk-7XU5X6CW.js.map +0 -1
  97. package/dist/chunk-CF2XXJFF.js.map +0 -1
  98. package/dist/loader-CrdnaAWR.d.ts +0 -327
  99. /package/dist/{loader-55LWCXHA.js.map → loader-VGNXC2XJ.js.map} +0 -0
@@ -2,7 +2,7 @@ import {
2
2
  ContentWatcher,
3
3
  FileModificationTracker,
4
4
  createContentWatcher
5
- } from "../chunk-XNTQTTJU.js";
5
+ } from "../chunk-JFQQJPDF.js";
6
6
  import {
7
7
  DEFAULT_IMAGE_CONFIG,
8
8
  calculateRelativePath,
@@ -38,7 +38,7 @@ import {
38
38
  updateContent,
39
39
  uploadImage,
40
40
  writeManifest
41
- } from "../chunk-CF2XXJFF.js";
41
+ } from "../chunk-OWYFIQFK.js";
42
42
  import {
43
43
  checkCollection,
44
44
  extractSlug,
@@ -51,10 +51,10 @@ import {
51
51
  readCollection,
52
52
  readContentFile,
53
53
  toContentSummary
54
- } from "../chunk-AAOQHQPU.js";
54
+ } from "../chunk-TQAYIZOA.js";
55
55
  import {
56
56
  DEFAULT_VERSION_HISTORY_CONFIG
57
- } from "../chunk-CRPZUUDU.js";
57
+ } from "../chunk-YBCPOLMY.js";
58
58
 
59
59
  // src/filesystem/version-config.ts
60
60
  function resolveVersionConfig(config) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/filesystem/version-config.ts"],"sourcesContent":["/**\n * @fileoverview Config-aware wrappers for version history operations\n *\n * This module provides wrapper functions that automatically apply configuration\n * defaults and check the enabled flag before performing version operations.\n * These wrappers simplify usage by accepting partial configuration and handling\n * all the configuration resolution internally.\n *\n * @module @writenex/astro/filesystem/version-config\n * @see {@link saveVersion} - Core save function\n * @see {@link getVersions} - Core list function\n */\n\nimport type {\n VersionHistoryConfig,\n VersionEntry,\n Version,\n VersionResult,\n SaveVersionOptions,\n RestoreVersionOptions,\n RestoreResult,\n} from \"@/types\";\nimport { DEFAULT_VERSION_HISTORY_CONFIG } from \"@/config/defaults\";\nimport {\n saveVersion as coreSaveVersion,\n getVersions as coreGetVersions,\n getVersion as coreGetVersion,\n deleteVersion as coreDeleteVersion,\n clearVersions as coreClearVersions,\n pruneVersions as corePruneVersions,\n restoreVersion as coreRestoreVersion,\n} from \"./versions\";\n\n// =============================================================================\n// Configuration Resolution\n// =============================================================================\n\n/**\n * Resolve version history configuration with defaults applied.\n *\n * Takes a partial configuration and merges it with defaults to produce\n * a complete configuration object.\n *\n * @param config - Partial version history configuration\n * @returns Complete configuration with all defaults applied\n *\n * @example\n * ```typescript\n * const resolved = resolveVersionConfig({ maxVersions: 50 });\n * // Returns: { enabled: true, maxVersions: 50, storagePath: '.writenex/versions' }\n * ```\n */\nexport function resolveVersionConfig(\n config?: VersionHistoryConfig\n): Required<VersionHistoryConfig> {\n if (!config) {\n return { ...DEFAULT_VERSION_HISTORY_CONFIG };\n }\n\n return {\n enabled: config.enabled ?? DEFAULT_VERSION_HISTORY_CONFIG.enabled,\n maxVersions:\n config.maxVersions ?? DEFAULT_VERSION_HISTORY_CONFIG.maxVersions,\n storagePath:\n config.storagePath ?? DEFAULT_VERSION_HISTORY_CONFIG.storagePath,\n };\n}\n\n/**\n * Check if version history is enabled in the configuration.\n *\n * @param config - Version history configuration (partial or full)\n * @returns True if version history is enabled\n *\n * @example\n * ```typescript\n * if (isVersionHistoryEnabled({ enabled: false })) {\n * // This won't execute\n * }\n * ```\n */\nexport function isVersionHistoryEnabled(\n config?: VersionHistoryConfig\n): boolean {\n const resolved = resolveVersionConfig(config);\n return resolved.enabled;\n}\n\n// =============================================================================\n// Config-Aware Version Operations\n// =============================================================================\n\n/**\n * Save a version with automatic configuration resolution.\n *\n * This wrapper automatically applies configuration defaults and checks\n * the enabled flag before delegating to the core saveVersion function.\n *\n * @param projectRoot - Absolute path to project root\n * @param collection - Collection name\n * @param contentId - Content item ID (slug)\n * @param content - Full markdown content to save\n * @param config - Partial version history configuration\n * @param options - Save options\n * @returns Result of the save operation\n *\n * @example\n * ```typescript\n * // With partial config - defaults are applied automatically\n * const result = await saveVersionWithConfig(\n * '/project',\n * 'blog',\n * 'my-post',\n * '---\\ntitle: My Post\\n---\\n\\nContent...',\n * { maxVersions: 50 } // enabled and storagePath use defaults\n * );\n * ```\n */\nexport async function saveVersionWithConfig(\n projectRoot: string,\n collection: string,\n contentId: string,\n content: string,\n config?: VersionHistoryConfig,\n options?: SaveVersionOptions\n): Promise<VersionResult> {\n const resolvedConfig = resolveVersionConfig(config);\n\n // Early return if disabled\n if (!resolvedConfig.enabled) {\n return { success: true };\n }\n\n return coreSaveVersion(\n projectRoot,\n collection,\n contentId,\n content,\n resolvedConfig,\n options\n );\n}\n\n/**\n * Get all versions with automatic configuration resolution.\n *\n * This wrapper automatically applies configuration defaults and checks\n * the enabled flag before delegating to the core getVersions function.\n *\n * @param projectRoot - Absolute path to project root\n * @param collection - Collection name\n * @param contentId - Content item ID (slug)\n * @param config - Partial version history configuration\n * @returns Array of version entries (empty if disabled)\n *\n * @example\n * ```typescript\n * const versions = await getVersionsWithConfig(\n * '/project',\n * 'blog',\n * 'my-post',\n * { storagePath: 'custom/versions' }\n * );\n * ```\n */\nexport async function getVersionsWithConfig(\n projectRoot: string,\n collection: string,\n contentId: string,\n config?: VersionHistoryConfig\n): Promise<VersionEntry[]> {\n const resolvedConfig = resolveVersionConfig(config);\n\n // Early return if disabled\n if (!resolvedConfig.enabled) {\n return [];\n }\n\n return coreGetVersions(projectRoot, collection, contentId, resolvedConfig);\n}\n\n/**\n * Get a specific version with automatic configuration resolution.\n *\n * This wrapper automatically applies configuration defaults and checks\n * the enabled flag before delegating to the core getVersion function.\n *\n * @param projectRoot - Absolute path to project root\n * @param collection - Collection name\n * @param contentId - Content item ID (slug)\n * @param versionId - Version ID to retrieve\n * @param config - Partial version history configuration\n * @returns Full version data or null if not found/disabled\n *\n * @example\n * ```typescript\n * const version = await getVersionWithConfig(\n * '/project',\n * 'blog',\n * 'my-post',\n * '2024-12-11T10-30-00-000Z'\n * );\n * ```\n */\nexport async function getVersionWithConfig(\n projectRoot: string,\n collection: string,\n contentId: string,\n versionId: string,\n config?: VersionHistoryConfig\n): Promise<Version | null> {\n const resolvedConfig = resolveVersionConfig(config);\n\n // Early return if disabled\n if (!resolvedConfig.enabled) {\n return null;\n }\n\n return coreGetVersion(\n projectRoot,\n collection,\n contentId,\n versionId,\n resolvedConfig\n );\n}\n\n/**\n * Delete a version with automatic configuration resolution.\n *\n * This wrapper automatically applies configuration defaults before\n * delegating to the core deleteVersion function.\n *\n * @param projectRoot - Absolute path to project root\n * @param collection - Collection name\n * @param contentId - Content item ID (slug)\n * @param versionId - Version ID to delete\n * @param config - Partial version history configuration\n * @returns Result of the delete operation\n *\n * @example\n * ```typescript\n * const result = await deleteVersionWithConfig(\n * '/project',\n * 'blog',\n * 'my-post',\n * '2024-12-11T10-30-00-000Z'\n * );\n * ```\n */\nexport async function deleteVersionWithConfig(\n projectRoot: string,\n collection: string,\n contentId: string,\n versionId: string,\n config?: VersionHistoryConfig\n): Promise<VersionResult> {\n const resolvedConfig = resolveVersionConfig(config);\n\n return coreDeleteVersion(\n projectRoot,\n collection,\n contentId,\n versionId,\n resolvedConfig\n );\n}\n\n/**\n * Clear all versions with automatic configuration resolution.\n *\n * This wrapper automatically applies configuration defaults before\n * delegating to the core clearVersions function.\n *\n * @param projectRoot - Absolute path to project root\n * @param collection - Collection name\n * @param contentId - Content item ID (slug)\n * @param config - Partial version history configuration\n * @returns Result of the clear operation\n *\n * @example\n * ```typescript\n * const result = await clearVersionsWithConfig(\n * '/project',\n * 'blog',\n * 'my-post'\n * );\n * ```\n */\nexport async function clearVersionsWithConfig(\n projectRoot: string,\n collection: string,\n contentId: string,\n config?: VersionHistoryConfig\n): Promise<VersionResult> {\n const resolvedConfig = resolveVersionConfig(config);\n\n return coreClearVersions(projectRoot, collection, contentId, resolvedConfig);\n}\n\n/**\n * Prune old versions with automatic configuration resolution.\n *\n * This wrapper automatically applies configuration defaults before\n * delegating to the core pruneVersions function. Uses the configured\n * maxVersions value for determining how many versions to keep.\n *\n * @param projectRoot - Absolute path to project root\n * @param collection - Collection name\n * @param contentId - Content item ID (slug)\n * @param config - Partial version history configuration\n * @returns Result of the prune operation\n *\n * @example\n * ```typescript\n * // Uses custom maxVersions\n * const result = await pruneVersionsWithConfig(\n * '/project',\n * 'blog',\n * 'my-post',\n * { maxVersions: 10 }\n * );\n * ```\n */\nexport async function pruneVersionsWithConfig(\n projectRoot: string,\n collection: string,\n contentId: string,\n config?: VersionHistoryConfig\n): Promise<VersionResult> {\n const resolvedConfig = resolveVersionConfig(config);\n\n return corePruneVersions(projectRoot, collection, contentId, resolvedConfig);\n}\n\n/**\n * Restore a version with automatic configuration resolution.\n *\n * This wrapper automatically applies configuration defaults and checks\n * the enabled flag before delegating to the core restoreVersion function.\n *\n * @param projectRoot - Absolute path to project root\n * @param collection - Collection name\n * @param contentId - Content item ID (slug)\n * @param versionId - Version ID to restore\n * @param contentFilePath - Absolute path to the current content file\n * @param config - Partial version history configuration\n * @param options - Restore options\n * @returns Result of the restore operation\n *\n * @example\n * ```typescript\n * const result = await restoreVersionWithConfig(\n * '/project',\n * 'blog',\n * 'my-post',\n * '2024-12-11T10-30-00-000Z',\n * '/project/src/content/blog/my-post.md'\n * );\n * ```\n */\nexport async function restoreVersionWithConfig(\n projectRoot: string,\n collection: string,\n contentId: string,\n versionId: string,\n contentFilePath: string,\n config?: VersionHistoryConfig,\n options?: RestoreVersionOptions\n): Promise<RestoreResult> {\n const resolvedConfig = resolveVersionConfig(config);\n\n // Early return if disabled\n if (!resolvedConfig.enabled) {\n return {\n success: false,\n error: \"Version history is disabled\",\n };\n }\n\n return coreRestoreVersion(\n projectRoot,\n collection,\n contentId,\n versionId,\n contentFilePath,\n resolvedConfig,\n options\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDO,SAAS,qBACd,QACgC;AAChC,MAAI,CAAC,QAAQ;AACX,WAAO,EAAE,GAAG,+BAA+B;AAAA,EAC7C;AAEA,SAAO;AAAA,IACL,SAAS,OAAO,WAAW,+BAA+B;AAAA,IAC1D,aACE,OAAO,eAAe,+BAA+B;AAAA,IACvD,aACE,OAAO,eAAe,+BAA+B;AAAA,EACzD;AACF;AAeO,SAAS,wBACd,QACS;AACT,QAAM,WAAW,qBAAqB,MAAM;AAC5C,SAAO,SAAS;AAClB;AAgCA,eAAsB,sBACpB,aACA,YACA,WACA,SACA,QACA,SACwB;AACxB,QAAM,iBAAiB,qBAAqB,MAAM;AAGlD,MAAI,CAAC,eAAe,SAAS;AAC3B,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAwBA,eAAsB,sBACpB,aACA,YACA,WACA,QACyB;AACzB,QAAM,iBAAiB,qBAAqB,MAAM;AAGlD,MAAI,CAAC,eAAe,SAAS;AAC3B,WAAO,CAAC;AAAA,EACV;AAEA,SAAO,YAAgB,aAAa,YAAY,WAAW,cAAc;AAC3E;AAyBA,eAAsB,qBACpB,aACA,YACA,WACA,WACA,QACyB;AACzB,QAAM,iBAAiB,qBAAqB,MAAM;AAGlD,MAAI,CAAC,eAAe,SAAS;AAC3B,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAyBA,eAAsB,wBACpB,aACA,YACA,WACA,WACA,QACwB;AACxB,QAAM,iBAAiB,qBAAqB,MAAM;AAElD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAuBA,eAAsB,wBACpB,aACA,YACA,WACA,QACwB;AACxB,QAAM,iBAAiB,qBAAqB,MAAM;AAElD,SAAO,cAAkB,aAAa,YAAY,WAAW,cAAc;AAC7E;AA0BA,eAAsB,wBACpB,aACA,YACA,WACA,QACwB;AACxB,QAAM,iBAAiB,qBAAqB,MAAM;AAElD,SAAO,cAAkB,aAAa,YAAY,WAAW,cAAc;AAC7E;AA4BA,eAAsB,yBACpB,aACA,YACA,WACA,WACA,iBACA,QACA,SACwB;AACxB,QAAM,iBAAiB,qBAAqB,MAAM;AAGlD,MAAI,CAAC,eAAe,SAAS;AAC3B,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/filesystem/version-config.ts"],"sourcesContent":["/**\n * @fileoverview Config-aware wrappers for version history operations\n *\n * This module provides wrapper functions that automatically apply configuration\n * defaults and check the enabled flag before performing version operations.\n * These wrappers simplify usage by accepting partial configuration and handling\n * all the configuration resolution internally.\n *\n * @module @writenex/astro/filesystem/version-config\n * @see {@link saveVersion} - Core save function\n * @see {@link getVersions} - Core list function\n */\n\nimport { DEFAULT_VERSION_HISTORY_CONFIG } from \"@/config/defaults\";\nimport type {\n RestoreResult,\n RestoreVersionOptions,\n SaveVersionOptions,\n Version,\n VersionEntry,\n VersionHistoryConfig,\n VersionResult,\n} from \"@/types\";\nimport {\n clearVersions as coreClearVersions,\n deleteVersion as coreDeleteVersion,\n getVersion as coreGetVersion,\n getVersions as coreGetVersions,\n pruneVersions as corePruneVersions,\n restoreVersion as coreRestoreVersion,\n saveVersion as coreSaveVersion,\n} from \"./versions\";\n\n// =============================================================================\n// Configuration Resolution\n// =============================================================================\n\n/**\n * Resolve version history configuration with defaults applied.\n *\n * Takes a partial configuration and merges it with defaults to produce\n * a complete configuration object.\n *\n * @param config - Partial version history configuration\n * @returns Complete configuration with all defaults applied\n *\n * @example\n * ```typescript\n * const resolved = resolveVersionConfig({ maxVersions: 50 });\n * // Returns: { enabled: true, maxVersions: 50, storagePath: '.writenex/versions' }\n * ```\n */\nexport function resolveVersionConfig(\n config?: VersionHistoryConfig\n): Required<VersionHistoryConfig> {\n if (!config) {\n return { ...DEFAULT_VERSION_HISTORY_CONFIG };\n }\n\n return {\n enabled: config.enabled ?? DEFAULT_VERSION_HISTORY_CONFIG.enabled,\n maxVersions:\n config.maxVersions ?? DEFAULT_VERSION_HISTORY_CONFIG.maxVersions,\n storagePath:\n config.storagePath ?? DEFAULT_VERSION_HISTORY_CONFIG.storagePath,\n };\n}\n\n/**\n * Check if version history is enabled in the configuration.\n *\n * @param config - Version history configuration (partial or full)\n * @returns True if version history is enabled\n *\n * @example\n * ```typescript\n * if (isVersionHistoryEnabled({ enabled: false })) {\n * // This won't execute\n * }\n * ```\n */\nexport function isVersionHistoryEnabled(\n config?: VersionHistoryConfig\n): boolean {\n const resolved = resolveVersionConfig(config);\n return resolved.enabled;\n}\n\n// =============================================================================\n// Config-Aware Version Operations\n// =============================================================================\n\n/**\n * Save a version with automatic configuration resolution.\n *\n * This wrapper automatically applies configuration defaults and checks\n * the enabled flag before delegating to the core saveVersion function.\n *\n * @param projectRoot - Absolute path to project root\n * @param collection - Collection name\n * @param contentId - Content item ID (slug)\n * @param content - Full markdown content to save\n * @param config - Partial version history configuration\n * @param options - Save options\n * @returns Result of the save operation\n *\n * @example\n * ```typescript\n * // With partial config - defaults are applied automatically\n * const result = await saveVersionWithConfig(\n * '/project',\n * 'blog',\n * 'my-post',\n * '---\\ntitle: My Post\\n---\\n\\nContent...',\n * { maxVersions: 50 } // enabled and storagePath use defaults\n * );\n * ```\n */\nexport async function saveVersionWithConfig(\n projectRoot: string,\n collection: string,\n contentId: string,\n content: string,\n config?: VersionHistoryConfig,\n options?: SaveVersionOptions\n): Promise<VersionResult> {\n const resolvedConfig = resolveVersionConfig(config);\n\n // Early return if disabled\n if (!resolvedConfig.enabled) {\n return { success: true };\n }\n\n return coreSaveVersion(\n projectRoot,\n collection,\n contentId,\n content,\n resolvedConfig,\n options\n );\n}\n\n/**\n * Get all versions with automatic configuration resolution.\n *\n * This wrapper automatically applies configuration defaults and checks\n * the enabled flag before delegating to the core getVersions function.\n *\n * @param projectRoot - Absolute path to project root\n * @param collection - Collection name\n * @param contentId - Content item ID (slug)\n * @param config - Partial version history configuration\n * @returns Array of version entries (empty if disabled)\n *\n * @example\n * ```typescript\n * const versions = await getVersionsWithConfig(\n * '/project',\n * 'blog',\n * 'my-post',\n * { storagePath: 'custom/versions' }\n * );\n * ```\n */\nexport async function getVersionsWithConfig(\n projectRoot: string,\n collection: string,\n contentId: string,\n config?: VersionHistoryConfig\n): Promise<VersionEntry[]> {\n const resolvedConfig = resolveVersionConfig(config);\n\n // Early return if disabled\n if (!resolvedConfig.enabled) {\n return [];\n }\n\n return coreGetVersions(projectRoot, collection, contentId, resolvedConfig);\n}\n\n/**\n * Get a specific version with automatic configuration resolution.\n *\n * This wrapper automatically applies configuration defaults and checks\n * the enabled flag before delegating to the core getVersion function.\n *\n * @param projectRoot - Absolute path to project root\n * @param collection - Collection name\n * @param contentId - Content item ID (slug)\n * @param versionId - Version ID to retrieve\n * @param config - Partial version history configuration\n * @returns Full version data or null if not found/disabled\n *\n * @example\n * ```typescript\n * const version = await getVersionWithConfig(\n * '/project',\n * 'blog',\n * 'my-post',\n * '2024-12-11T10-30-00-000Z'\n * );\n * ```\n */\nexport async function getVersionWithConfig(\n projectRoot: string,\n collection: string,\n contentId: string,\n versionId: string,\n config?: VersionHistoryConfig\n): Promise<Version | null> {\n const resolvedConfig = resolveVersionConfig(config);\n\n // Early return if disabled\n if (!resolvedConfig.enabled) {\n return null;\n }\n\n return coreGetVersion(\n projectRoot,\n collection,\n contentId,\n versionId,\n resolvedConfig\n );\n}\n\n/**\n * Delete a version with automatic configuration resolution.\n *\n * This wrapper automatically applies configuration defaults before\n * delegating to the core deleteVersion function.\n *\n * @param projectRoot - Absolute path to project root\n * @param collection - Collection name\n * @param contentId - Content item ID (slug)\n * @param versionId - Version ID to delete\n * @param config - Partial version history configuration\n * @returns Result of the delete operation\n *\n * @example\n * ```typescript\n * const result = await deleteVersionWithConfig(\n * '/project',\n * 'blog',\n * 'my-post',\n * '2024-12-11T10-30-00-000Z'\n * );\n * ```\n */\nexport async function deleteVersionWithConfig(\n projectRoot: string,\n collection: string,\n contentId: string,\n versionId: string,\n config?: VersionHistoryConfig\n): Promise<VersionResult> {\n const resolvedConfig = resolveVersionConfig(config);\n\n return coreDeleteVersion(\n projectRoot,\n collection,\n contentId,\n versionId,\n resolvedConfig\n );\n}\n\n/**\n * Clear all versions with automatic configuration resolution.\n *\n * This wrapper automatically applies configuration defaults before\n * delegating to the core clearVersions function.\n *\n * @param projectRoot - Absolute path to project root\n * @param collection - Collection name\n * @param contentId - Content item ID (slug)\n * @param config - Partial version history configuration\n * @returns Result of the clear operation\n *\n * @example\n * ```typescript\n * const result = await clearVersionsWithConfig(\n * '/project',\n * 'blog',\n * 'my-post'\n * );\n * ```\n */\nexport async function clearVersionsWithConfig(\n projectRoot: string,\n collection: string,\n contentId: string,\n config?: VersionHistoryConfig\n): Promise<VersionResult> {\n const resolvedConfig = resolveVersionConfig(config);\n\n return coreClearVersions(projectRoot, collection, contentId, resolvedConfig);\n}\n\n/**\n * Prune old versions with automatic configuration resolution.\n *\n * This wrapper automatically applies configuration defaults before\n * delegating to the core pruneVersions function. Uses the configured\n * maxVersions value for determining how many versions to keep.\n *\n * @param projectRoot - Absolute path to project root\n * @param collection - Collection name\n * @param contentId - Content item ID (slug)\n * @param config - Partial version history configuration\n * @returns Result of the prune operation\n *\n * @example\n * ```typescript\n * // Uses custom maxVersions\n * const result = await pruneVersionsWithConfig(\n * '/project',\n * 'blog',\n * 'my-post',\n * { maxVersions: 10 }\n * );\n * ```\n */\nexport async function pruneVersionsWithConfig(\n projectRoot: string,\n collection: string,\n contentId: string,\n config?: VersionHistoryConfig\n): Promise<VersionResult> {\n const resolvedConfig = resolveVersionConfig(config);\n\n return corePruneVersions(projectRoot, collection, contentId, resolvedConfig);\n}\n\n/**\n * Restore a version with automatic configuration resolution.\n *\n * This wrapper automatically applies configuration defaults and checks\n * the enabled flag before delegating to the core restoreVersion function.\n *\n * @param projectRoot - Absolute path to project root\n * @param collection - Collection name\n * @param contentId - Content item ID (slug)\n * @param versionId - Version ID to restore\n * @param contentFilePath - Absolute path to the current content file\n * @param config - Partial version history configuration\n * @param options - Restore options\n * @returns Result of the restore operation\n *\n * @example\n * ```typescript\n * const result = await restoreVersionWithConfig(\n * '/project',\n * 'blog',\n * 'my-post',\n * '2024-12-11T10-30-00-000Z',\n * '/project/src/content/blog/my-post.md'\n * );\n * ```\n */\nexport async function restoreVersionWithConfig(\n projectRoot: string,\n collection: string,\n contentId: string,\n versionId: string,\n contentFilePath: string,\n config?: VersionHistoryConfig,\n options?: RestoreVersionOptions\n): Promise<RestoreResult> {\n const resolvedConfig = resolveVersionConfig(config);\n\n // Early return if disabled\n if (!resolvedConfig.enabled) {\n return {\n success: false,\n error: \"Version history is disabled\",\n };\n }\n\n return coreRestoreVersion(\n projectRoot,\n collection,\n contentId,\n versionId,\n contentFilePath,\n resolvedConfig,\n options\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDO,SAAS,qBACd,QACgC;AAChC,MAAI,CAAC,QAAQ;AACX,WAAO,EAAE,GAAG,+BAA+B;AAAA,EAC7C;AAEA,SAAO;AAAA,IACL,SAAS,OAAO,WAAW,+BAA+B;AAAA,IAC1D,aACE,OAAO,eAAe,+BAA+B;AAAA,IACvD,aACE,OAAO,eAAe,+BAA+B;AAAA,EACzD;AACF;AAeO,SAAS,wBACd,QACS;AACT,QAAM,WAAW,qBAAqB,MAAM;AAC5C,SAAO,SAAS;AAClB;AAgCA,eAAsB,sBACpB,aACA,YACA,WACA,SACA,QACA,SACwB;AACxB,QAAM,iBAAiB,qBAAqB,MAAM;AAGlD,MAAI,CAAC,eAAe,SAAS;AAC3B,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAwBA,eAAsB,sBACpB,aACA,YACA,WACA,QACyB;AACzB,QAAM,iBAAiB,qBAAqB,MAAM;AAGlD,MAAI,CAAC,eAAe,SAAS;AAC3B,WAAO,CAAC;AAAA,EACV;AAEA,SAAO,YAAgB,aAAa,YAAY,WAAW,cAAc;AAC3E;AAyBA,eAAsB,qBACpB,aACA,YACA,WACA,WACA,QACyB;AACzB,QAAM,iBAAiB,qBAAqB,MAAM;AAGlD,MAAI,CAAC,eAAe,SAAS;AAC3B,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAyBA,eAAsB,wBACpB,aACA,YACA,WACA,WACA,QACwB;AACxB,QAAM,iBAAiB,qBAAqB,MAAM;AAElD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAuBA,eAAsB,wBACpB,aACA,YACA,WACA,QACwB;AACxB,QAAM,iBAAiB,qBAAqB,MAAM;AAElD,SAAO,cAAkB,aAAa,YAAY,WAAW,cAAc;AAC7E;AA0BA,eAAsB,wBACpB,aACA,YACA,WACA,QACwB;AACxB,QAAM,iBAAiB,qBAAqB,MAAM;AAElD,SAAO,cAAkB,aAAa,YAAY,WAAW,cAAc;AAC7E;AA4BA,eAAsB,yBACpB,aACA,YACA,WACA,WACA,iBACA,QACA,SACwB;AACxB,QAAM,iBAAiB,qBAAqB,MAAM;AAGlD,MAAI,CAAC,eAAe,SAAS;AAC3B,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { AstroIntegration } from 'astro';
2
- import { W as WritenexOptions } from './config-BmEdBDo_.js';
3
- export { C as CollectionConfig, b as CollectionSchema, D as DiscoveryConfig, E as EditorConfig, F as FieldType, I as ImageConfig, c as ImageStrategy, S as SchemaField, V as VersionHistoryConfig, a as WritenexConfig } from './config-BmEdBDo_.js';
4
- export { d as defineConfig, l as loadConfig, v as validateConfig } from './loader-CrdnaAWR.js';
5
- export { C as ContentItem, a as ContentSummary, D as DiscoveredCollection } from './content-BWR52vD-.js';
2
+ import { W as WritenexOptions } from './config-CliL0CoN.js';
3
+ export { C as CollectionConfig, a as CollectionSchema, D as DiscoveryConfig, E as EditorConfig, F as FieldType, I as ImageConfig, b as ImageStrategy, S as SchemaField, V as VersionHistoryConfig, c as WritenexConfig } from './config-CliL0CoN.js';
4
+ export { C as ContentItem, a as ContentSummary, D as DiscoveredCollection } from './content-TuL3GT66.js';
5
+ export { d as defineConfig, l as loadConfig, v as validateConfig } from './schema-DDJyoVkj.js';
6
6
  export { W as WritenexError, a as WritenexErrorCode, i as isWritenexError } from './errors-C0iYiDTv.js';
7
7
  import 'zod';
8
8
 
package/dist/index.js CHANGED
@@ -1,24 +1,24 @@
1
1
  import "./chunk-KIKIPIFA.js";
2
2
  import {
3
3
  ContentWatcher
4
- } from "./chunk-XNTQTTJU.js";
4
+ } from "./chunk-JFQQJPDF.js";
5
5
  import {
6
6
  createMiddleware,
7
7
  getCache
8
- } from "./chunk-7XU5X6CW.js";
9
- import "./chunk-CYLDJ3HZ.js";
8
+ } from "./chunk-GUUSVFBP.js";
9
+ import "./chunk-GIS7XEJF.js";
10
10
  import {
11
11
  WritenexError,
12
12
  WritenexErrorCode,
13
13
  isWritenexError
14
- } from "./chunk-CF2XXJFF.js";
15
- import "./chunk-AAOQHQPU.js";
14
+ } from "./chunk-OWYFIQFK.js";
15
+ import "./chunk-TQAYIZOA.js";
16
16
  import {
17
17
  defineConfig,
18
18
  loadConfig,
19
19
  validateConfig
20
- } from "./chunk-5PM6EQE5.js";
21
- import "./chunk-CRPZUUDU.js";
20
+ } from "./chunk-S2OUQLMK.js";
21
+ import "./chunk-YBCPOLMY.js";
22
22
 
23
23
  // src/integration.ts
24
24
  var DEFAULT_BASE_PATH = "/_writenex";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/integration.ts","../src/core/constants.ts"],"sourcesContent":["/**\n * @fileoverview Astro integration for Writenex visual editor\n *\n * This module provides the main Astro integration that injects the Writenex\n * editor UI and API routes into an Astro project.\n *\n * ## Features:\n * - Injects editor UI at /_writenex\n * - Provides API routes for content CRUD operations\n * - Auto-discovers content collections\n * - Production guard to prevent accidental exposure\n *\n * ## Usage:\n * ```typescript\n * // astro.config.mjs\n * import { defineConfig } from 'astro/config';\n * import writenex from '@writenex/astro';\n *\n * export default defineConfig({\n * integrations: [writenex()],\n * });\n * ```\n *\n * @module @writenex/astro/integration\n */\n\nimport type { AstroIntegration } from \"astro\";\nimport type { WritenexOptions, WritenexConfig } from \"@/types\";\nimport { loadConfig } from \"@/config/loader\";\nimport { createMiddleware } from \"@/server/middleware\";\nimport { ContentWatcher } from \"@/filesystem/watcher\";\nimport { getCache } from \"@/server/cache\";\n\n/**\n * Default base path for the Writenex editor UI\n */\nconst DEFAULT_BASE_PATH = \"/_writenex\";\n\n/**\n * Package name for logging\n */\nconst PACKAGE_NAME = \"@writenex/astro\";\n\n/**\n * Creates the Writenex Astro integration.\n *\n * This integration injects the Writenex visual editor into your Astro project,\n * providing a WYSIWYG interface for editing content collections.\n *\n * @param options - Integration options\n * @param options.allowProduction - Allow running in production (default: false)\n * @returns Astro integration object\n *\n * @example\n * ```typescript\n * // Basic usage\n * export default defineConfig({\n * integrations: [writenex()],\n * });\n *\n * // With options\n * export default defineConfig({\n * integrations: [\n * writenex({\n * allowProduction: true, // Enable in production (use with caution)\n * }),\n * ],\n * });\n * ```\n */\nexport default function writenex(options?: WritenexOptions): AstroIntegration {\n const { allowProduction = false } = options ?? {};\n\n // Use fixed base path for consistency and branding\n const basePath = DEFAULT_BASE_PATH;\n\n // Track if we should be active\n let isActive = true;\n\n // Store loaded configuration\n let resolvedConfig: Required<WritenexConfig> | null = null;\n\n // Store project root\n let projectRoot = \"\";\n\n // Store Astro's trailingSlash setting\n let astroTrailingSlash: \"always\" | \"never\" | \"ignore\" = \"ignore\";\n\n // File watcher instance\n let watcher: ContentWatcher | null = null;\n\n // Track if editor URL has been logged (to avoid duplicate logs)\n let hasLoggedEditorUrl = false;\n\n return {\n name: PACKAGE_NAME,\n hooks: {\n /**\n * Configuration setup hook\n *\n * This hook runs during Astro's config resolution phase.\n * We use it to:\n * 1. Check if we should run (production guard)\n * 2. Load Writenex configuration\n * 3. Register any necessary Vite plugins\n */\n \"astro:config:setup\": async ({ command, logger, config }) => {\n // Production guard: disable in production unless explicitly allowed\n if (command === \"build\" && !allowProduction) {\n logger.warn(\n \"Disabled in production build. Use allowProduction: true to override.\"\n );\n isActive = false;\n return;\n }\n\n // Store project root\n projectRoot = config.root.pathname;\n\n // Capture Astro's trailingSlash setting for preview URLs\n astroTrailingSlash = config.trailingSlash ?? \"ignore\";\n\n // Load Writenex configuration\n const { config: loadedConfig, warnings } =\n await loadConfig(projectRoot);\n resolvedConfig = loadedConfig;\n\n // Log any configuration warnings\n for (const warning of warnings) {\n logger.warn(warning);\n }\n },\n\n /**\n * Server setup hook\n *\n * This hook runs when the Astro dev server starts.\n * We use it to:\n * 1. Inject middleware for API routes\n * 2. Serve the editor UI\n * 3. Start file watcher for cache invalidation\n */\n \"astro:server:setup\": ({ server }) => {\n // Skip if disabled (production guard triggered)\n if (!isActive || !resolvedConfig) {\n return;\n }\n\n // Create and register the middleware\n const middleware = createMiddleware({\n basePath,\n projectRoot,\n config: resolvedConfig,\n trailingSlash: astroTrailingSlash,\n });\n\n server.middlewares.use(middleware);\n\n // Setup cache with file watcher integration\n const cache = getCache({ hasWatcher: true });\n\n // Start file watcher for cache invalidation\n watcher = new ContentWatcher(projectRoot, \"src/content\", {\n onChange: (event) => {\n cache.handleFileChange(event.type, event.collection);\n },\n });\n\n watcher.start();\n },\n\n /**\n * Server start hook\n *\n * This hook runs after the dev server has started and is listening.\n * We use it to log the full editor URL with the actual server address.\n */\n \"astro:server:start\": ({ address, logger }) => {\n if (!isActive || hasLoggedEditorUrl) {\n return;\n }\n\n // Build the full URL from the server address\n // Normalize loopback addresses to \"localhost\" for better readability\n const protocol = \"http\";\n const rawHost = address.address;\n const isLoopback =\n rawHost === \"\" ||\n rawHost === \"::\" ||\n rawHost === \"127.0.0.1\" ||\n rawHost === \"::1\";\n const host = isLoopback ? \"localhost\" : rawHost;\n const port = address.port;\n const editorUrl = `${protocol}://${host}:${port}${basePath}`;\n\n logger.info(`Writenex editor running at: ${editorUrl}`);\n hasLoggedEditorUrl = true;\n },\n\n /**\n * Server done hook\n *\n * This hook runs when the server is shutting down.\n * We use it to clean up the file watcher.\n */\n \"astro:server:done\": async () => {\n if (watcher) {\n await watcher.stop();\n watcher = null;\n }\n },\n\n /**\n * Build done hook\n *\n * This hook runs after the build completes.\n * Currently just logs a warning if production mode is enabled.\n */\n \"astro:build:done\": ({ logger }) => {\n if (allowProduction) {\n logger.warn(\n \"Production mode enabled. Ensure your deployment is secured.\"\n );\n }\n },\n },\n };\n}\n","/**\n * @fileoverview Shared constants for @writenex/astro\n *\n * This module provides centralized constants used across the integration,\n * including version information, default paths, and configuration limits.\n *\n * @module @writenex/astro/core/constants\n */\n\n/**\n * Current version of the @writenex/astro package\n */\nexport const WRITENEX_VERSION = \"1.0.0\";\n\n/**\n * Default base path for the Writenex editor UI\n */\nexport const DEFAULT_BASE_PATH = \"/_writenex\";\n\n/**\n * Default API path for Writenex API endpoints\n */\nexport const DEFAULT_API_PATH = \"/_writenex/api\";\n\n/**\n * Supported image MIME types for upload\n */\nexport const SUPPORTED_IMAGE_TYPES = [\n \"image/jpeg\",\n \"image/png\",\n \"image/gif\",\n \"image/webp\",\n \"image/svg+xml\",\n] as const;\n\n/**\n * Maximum allowed image file size in bytes (10MB)\n */\nexport const MAX_IMAGE_SIZE = 10 * 1024 * 1024;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAoCA,IAAM,oBAAoB;AAK1B,IAAM,eAAe;AA6BN,SAAR,SAA0B,SAA6C;AAC5E,QAAM,EAAE,kBAAkB,MAAM,IAAI,WAAW,CAAC;AAGhD,QAAM,WAAW;AAGjB,MAAI,WAAW;AAGf,MAAI,iBAAkD;AAGtD,MAAI,cAAc;AAGlB,MAAI,qBAAoD;AAGxD,MAAI,UAAiC;AAGrC,MAAI,qBAAqB;AAEzB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUL,sBAAsB,OAAO,EAAE,SAAS,QAAQ,OAAO,MAAM;AAE3D,YAAI,YAAY,WAAW,CAAC,iBAAiB;AAC3C,iBAAO;AAAA,YACL;AAAA,UACF;AACA,qBAAW;AACX;AAAA,QACF;AAGA,sBAAc,OAAO,KAAK;AAG1B,6BAAqB,OAAO,iBAAiB;AAG7C,cAAM,EAAE,QAAQ,cAAc,SAAS,IACrC,MAAM,WAAW,WAAW;AAC9B,yBAAiB;AAGjB,mBAAW,WAAW,UAAU;AAC9B,iBAAO,KAAK,OAAO;AAAA,QACrB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAWA,sBAAsB,CAAC,EAAE,OAAO,MAAM;AAEpC,YAAI,CAAC,YAAY,CAAC,gBAAgB;AAChC;AAAA,QACF;AAGA,cAAM,aAAa,iBAAiB;AAAA,UAClC;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR,eAAe;AAAA,QACjB,CAAC;AAED,eAAO,YAAY,IAAI,UAAU;AAGjC,cAAM,QAAQ,SAAS,EAAE,YAAY,KAAK,CAAC;AAG3C,kBAAU,IAAI,eAAe,aAAa,eAAe;AAAA,UACvD,UAAU,CAAC,UAAU;AACnB,kBAAM,iBAAiB,MAAM,MAAM,MAAM,UAAU;AAAA,UACrD;AAAA,QACF,CAAC;AAED,gBAAQ,MAAM;AAAA,MAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,sBAAsB,CAAC,EAAE,SAAS,OAAO,MAAM;AAC7C,YAAI,CAAC,YAAY,oBAAoB;AACnC;AAAA,QACF;AAIA,cAAM,WAAW;AACjB,cAAM,UAAU,QAAQ;AACxB,cAAM,aACJ,YAAY,MACZ,YAAY,QACZ,YAAY,eACZ,YAAY;AACd,cAAM,OAAO,aAAa,cAAc;AACxC,cAAM,OAAO,QAAQ;AACrB,cAAM,YAAY,GAAG,QAAQ,MAAM,IAAI,IAAI,IAAI,GAAG,QAAQ;AAE1D,eAAO,KAAK,+BAA+B,SAAS,EAAE;AACtD,6BAAqB;AAAA,MACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,qBAAqB,YAAY;AAC/B,YAAI,SAAS;AACX,gBAAM,QAAQ,KAAK;AACnB,oBAAU;AAAA,QACZ;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,oBAAoB,CAAC,EAAE,OAAO,MAAM;AAClC,YAAI,iBAAiB;AACnB,iBAAO;AAAA,YACL;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC7LO,IAAM,iBAAiB,KAAK,OAAO;","names":[]}
1
+ {"version":3,"sources":["../src/integration.ts","../src/core/constants.ts"],"sourcesContent":["/**\n * @fileoverview Astro integration for Writenex visual editor\n *\n * This module provides the main Astro integration that injects the Writenex\n * editor UI and API routes into an Astro project.\n *\n * ## Features:\n * - Injects editor UI at /_writenex\n * - Provides API routes for content CRUD operations\n * - Auto-discovers content collections\n * - Production guard to prevent accidental exposure\n *\n * ## Usage:\n * ```typescript\n * // astro.config.mjs\n * import { defineConfig } from 'astro/config';\n * import writenex from '@writenex/astro';\n *\n * export default defineConfig({\n * integrations: [writenex()],\n * });\n * ```\n *\n * @module @writenex/astro/integration\n */\n\nimport type { AstroIntegration } from \"astro\";\nimport { loadConfig } from \"@/config/loader\";\nimport { ContentWatcher } from \"@/filesystem/watcher\";\nimport { getCache } from \"@/server/cache\";\nimport { createMiddleware } from \"@/server/middleware\";\nimport type { WritenexConfig, WritenexOptions } from \"@/types\";\n\n/**\n * Default base path for the Writenex editor UI\n */\nconst DEFAULT_BASE_PATH = \"/_writenex\";\n\n/**\n * Package name for logging\n */\nconst PACKAGE_NAME = \"@writenex/astro\";\n\n/**\n * Creates the Writenex Astro integration.\n *\n * This integration injects the Writenex visual editor into your Astro project,\n * providing a WYSIWYG interface for editing content collections.\n *\n * @param options - Integration options\n * @param options.allowProduction - Allow running in production (default: false)\n * @returns Astro integration object\n *\n * @example\n * ```typescript\n * // Basic usage\n * export default defineConfig({\n * integrations: [writenex()],\n * });\n *\n * // With options\n * export default defineConfig({\n * integrations: [\n * writenex({\n * allowProduction: true, // Enable in production (use with caution)\n * }),\n * ],\n * });\n * ```\n */\nexport default function writenex(options?: WritenexOptions): AstroIntegration {\n const { allowProduction = false } = options ?? {};\n\n // Use fixed base path for consistency and branding\n const basePath = DEFAULT_BASE_PATH;\n\n // Track if we should be active\n let isActive = true;\n\n // Store loaded configuration\n let resolvedConfig: Required<WritenexConfig> | null = null;\n\n // Store project root\n let projectRoot = \"\";\n\n // Store Astro's trailingSlash setting\n let astroTrailingSlash: \"always\" | \"never\" | \"ignore\" = \"ignore\";\n\n // File watcher instance\n let watcher: ContentWatcher | null = null;\n\n // Track if editor URL has been logged (to avoid duplicate logs)\n let hasLoggedEditorUrl = false;\n\n return {\n name: PACKAGE_NAME,\n hooks: {\n /**\n * Configuration setup hook\n *\n * This hook runs during Astro's config resolution phase.\n * We use it to:\n * 1. Check if we should run (production guard)\n * 2. Load Writenex configuration\n * 3. Register any necessary Vite plugins\n */\n \"astro:config:setup\": async ({ command, logger, config }) => {\n // Production guard: disable in production unless explicitly allowed\n if (command === \"build\" && !allowProduction) {\n logger.warn(\n \"Disabled in production build. Use allowProduction: true to override.\"\n );\n isActive = false;\n return;\n }\n\n // Store project root\n projectRoot = config.root.pathname;\n\n // Capture Astro's trailingSlash setting for preview URLs\n astroTrailingSlash = config.trailingSlash ?? \"ignore\";\n\n // Load Writenex configuration\n const { config: loadedConfig, warnings } =\n await loadConfig(projectRoot);\n resolvedConfig = loadedConfig;\n\n // Log any configuration warnings\n for (const warning of warnings) {\n logger.warn(warning);\n }\n },\n\n /**\n * Server setup hook\n *\n * This hook runs when the Astro dev server starts.\n * We use it to:\n * 1. Inject middleware for API routes\n * 2. Serve the editor UI\n * 3. Start file watcher for cache invalidation\n */\n \"astro:server:setup\": ({ server }) => {\n // Skip if disabled (production guard triggered)\n if (!isActive || !resolvedConfig) {\n return;\n }\n\n // Create and register the middleware\n const middleware = createMiddleware({\n basePath,\n projectRoot,\n config: resolvedConfig,\n trailingSlash: astroTrailingSlash,\n });\n\n server.middlewares.use(middleware);\n\n // Setup cache with file watcher integration\n const cache = getCache({ hasWatcher: true });\n\n // Start file watcher for cache invalidation\n watcher = new ContentWatcher(projectRoot, \"src/content\", {\n onChange: (event) => {\n cache.handleFileChange(event.type, event.collection);\n },\n });\n\n watcher.start();\n },\n\n /**\n * Server start hook\n *\n * This hook runs after the dev server has started and is listening.\n * We use it to log the full editor URL with the actual server address.\n */\n \"astro:server:start\": ({ address, logger }) => {\n if (!isActive || hasLoggedEditorUrl) {\n return;\n }\n\n // Build the full URL from the server address\n // Normalize loopback addresses to \"localhost\" for better readability\n const protocol = \"http\";\n const rawHost = address.address;\n const isLoopback =\n rawHost === \"\" ||\n rawHost === \"::\" ||\n rawHost === \"127.0.0.1\" ||\n rawHost === \"::1\";\n const host = isLoopback ? \"localhost\" : rawHost;\n const port = address.port;\n const editorUrl = `${protocol}://${host}:${port}${basePath}`;\n\n logger.info(`Writenex editor running at: ${editorUrl}`);\n hasLoggedEditorUrl = true;\n },\n\n /**\n * Server done hook\n *\n * This hook runs when the server is shutting down.\n * We use it to clean up the file watcher.\n */\n \"astro:server:done\": async () => {\n if (watcher) {\n await watcher.stop();\n watcher = null;\n }\n },\n\n /**\n * Build done hook\n *\n * This hook runs after the build completes.\n * Currently just logs a warning if production mode is enabled.\n */\n \"astro:build:done\": ({ logger }) => {\n if (allowProduction) {\n logger.warn(\n \"Production mode enabled. Ensure your deployment is secured.\"\n );\n }\n },\n },\n };\n}\n","/**\n * @fileoverview Shared constants for @writenex/astro\n *\n * This module provides centralized constants used across the integration,\n * including version information, default paths, and configuration limits.\n *\n * @module @writenex/astro/core/constants\n */\n\n/**\n * Current version of the @writenex/astro package\n */\nexport const WRITENEX_VERSION = \"1.0.0\";\n\n/**\n * Default base path for the Writenex editor UI\n */\nexport const DEFAULT_BASE_PATH = \"/_writenex\";\n\n/**\n * Default API path for Writenex API endpoints\n */\nexport const DEFAULT_API_PATH = \"/_writenex/api\";\n\n/**\n * Supported image MIME types for upload\n */\nexport const SUPPORTED_IMAGE_TYPES = [\n \"image/jpeg\",\n \"image/png\",\n \"image/gif\",\n \"image/webp\",\n \"image/svg+xml\",\n] as const;\n\n/**\n * Maximum allowed image file size in bytes (10MB)\n */\nexport const MAX_IMAGE_SIZE = 10 * 1024 * 1024;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAoCA,IAAM,oBAAoB;AAK1B,IAAM,eAAe;AA6BN,SAAR,SAA0B,SAA6C;AAC5E,QAAM,EAAE,kBAAkB,MAAM,IAAI,WAAW,CAAC;AAGhD,QAAM,WAAW;AAGjB,MAAI,WAAW;AAGf,MAAI,iBAAkD;AAGtD,MAAI,cAAc;AAGlB,MAAI,qBAAoD;AAGxD,MAAI,UAAiC;AAGrC,MAAI,qBAAqB;AAEzB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUL,sBAAsB,OAAO,EAAE,SAAS,QAAQ,OAAO,MAAM;AAE3D,YAAI,YAAY,WAAW,CAAC,iBAAiB;AAC3C,iBAAO;AAAA,YACL;AAAA,UACF;AACA,qBAAW;AACX;AAAA,QACF;AAGA,sBAAc,OAAO,KAAK;AAG1B,6BAAqB,OAAO,iBAAiB;AAG7C,cAAM,EAAE,QAAQ,cAAc,SAAS,IACrC,MAAM,WAAW,WAAW;AAC9B,yBAAiB;AAGjB,mBAAW,WAAW,UAAU;AAC9B,iBAAO,KAAK,OAAO;AAAA,QACrB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAWA,sBAAsB,CAAC,EAAE,OAAO,MAAM;AAEpC,YAAI,CAAC,YAAY,CAAC,gBAAgB;AAChC;AAAA,QACF;AAGA,cAAM,aAAa,iBAAiB;AAAA,UAClC;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR,eAAe;AAAA,QACjB,CAAC;AAED,eAAO,YAAY,IAAI,UAAU;AAGjC,cAAM,QAAQ,SAAS,EAAE,YAAY,KAAK,CAAC;AAG3C,kBAAU,IAAI,eAAe,aAAa,eAAe;AAAA,UACvD,UAAU,CAAC,UAAU;AACnB,kBAAM,iBAAiB,MAAM,MAAM,MAAM,UAAU;AAAA,UACrD;AAAA,QACF,CAAC;AAED,gBAAQ,MAAM;AAAA,MAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,sBAAsB,CAAC,EAAE,SAAS,OAAO,MAAM;AAC7C,YAAI,CAAC,YAAY,oBAAoB;AACnC;AAAA,QACF;AAIA,cAAM,WAAW;AACjB,cAAM,UAAU,QAAQ;AACxB,cAAM,aACJ,YAAY,MACZ,YAAY,QACZ,YAAY,eACZ,YAAY;AACd,cAAM,OAAO,aAAa,cAAc;AACxC,cAAM,OAAO,QAAQ;AACrB,cAAM,YAAY,GAAG,QAAQ,MAAM,IAAI,IAAI,IAAI,GAAG,QAAQ;AAE1D,eAAO,KAAK,+BAA+B,SAAS,EAAE;AACtD,6BAAqB;AAAA,MACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,qBAAqB,YAAY;AAC/B,YAAI,SAAS;AACX,gBAAM,QAAQ,KAAK;AACnB,oBAAU;AAAA,QACZ;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,oBAAoB,CAAC,EAAE,OAAO,MAAM;AAClC,YAAI,iBAAiB;AACnB,iBAAO;AAAA,YACL;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC7LO,IAAM,iBAAiB,KAAK,OAAO;","names":[]}
@@ -2,11 +2,11 @@ import {
2
2
  contentDirectoryExists,
3
3
  findConfigFile,
4
4
  loadConfig
5
- } from "./chunk-5PM6EQE5.js";
6
- import "./chunk-CRPZUUDU.js";
5
+ } from "./chunk-S2OUQLMK.js";
6
+ import "./chunk-YBCPOLMY.js";
7
7
  export {
8
8
  contentDirectoryExists,
9
9
  findConfigFile,
10
10
  loadConfig
11
11
  };
12
- //# sourceMappingURL=loader-55LWCXHA.js.map
12
+ //# sourceMappingURL=loader-VGNXC2XJ.js.map
@@ -0,0 +1,189 @@
1
+ import { c as WritenexConfig } from './config-CliL0CoN.js';
2
+ import { z } from 'zod';
3
+
4
+ /**
5
+ * @fileoverview Configuration loader for @writenex/astro
6
+ *
7
+ * This module handles loading Writenex configuration from various sources:
8
+ * - writenex.config.ts (TypeScript)
9
+ * - writenex.config.js (JavaScript)
10
+ * - writenex.config.mjs (ES Module)
11
+ *
12
+ * The loader searches for configuration files in the project root and
13
+ * applies default values for any missing options.
14
+ *
15
+ * @module @writenex/astro/config/loader
16
+ */
17
+
18
+ /**
19
+ * Result of loading configuration
20
+ */
21
+ interface LoadConfigResult {
22
+ /** The loaded and validated configuration with defaults applied */
23
+ config: Required<WritenexConfig>;
24
+ /** Path to the configuration file (if found) */
25
+ configPath: string | null;
26
+ /** Whether a configuration file was found */
27
+ hasConfigFile: boolean;
28
+ /** Any warnings generated during loading */
29
+ warnings: string[];
30
+ }
31
+ /**
32
+ * Find the configuration file in the project root
33
+ *
34
+ * @param projectRoot - The root directory of the Astro project
35
+ * @returns Path to the configuration file, or null if not found
36
+ */
37
+ declare function findConfigFile(projectRoot: string): string | null;
38
+ /**
39
+ * Load Writenex configuration from the project root
40
+ *
41
+ * This function:
42
+ * 1. Searches for a configuration file in the project root
43
+ * 2. Loads and validates the configuration if found
44
+ * 3. Applies default values for any missing options
45
+ * 4. Returns the resolved configuration
46
+ *
47
+ * If no configuration file is found, default configuration is returned
48
+ * with auto-discovery enabled.
49
+ *
50
+ * @param projectRoot - The root directory of the Astro project
51
+ * @returns LoadConfigResult with the resolved configuration
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const { config, hasConfigFile, warnings } = await loadConfig('/path/to/project');
56
+ *
57
+ * if (!hasConfigFile) {
58
+ * console.log('Using auto-discovery mode');
59
+ * }
60
+ *
61
+ * if (warnings.length > 0) {
62
+ * warnings.forEach(w => console.warn(w));
63
+ * }
64
+ * ```
65
+ */
66
+ declare function loadConfig(projectRoot: string): Promise<LoadConfigResult>;
67
+ /**
68
+ * Check if a content directory exists in the project
69
+ *
70
+ * @param projectRoot - The root directory of the Astro project
71
+ * @param contentPath - Relative path to the content directory
72
+ * @returns True if the content directory exists
73
+ */
74
+ declare function contentDirectoryExists(projectRoot: string, contentPath?: string): boolean;
75
+
76
+ /**
77
+ * @fileoverview Configuration schema and validation for @writenex/astro
78
+ *
79
+ * This module provides Zod schemas for validating Writenex configuration
80
+ * and a helper function for defining type-safe configurations.
81
+ *
82
+ * @module @writenex/astro/config/schema
83
+ */
84
+
85
+ /**
86
+ * Main Writenex configuration schema
87
+ */
88
+ declare const writenexConfigSchema: z.ZodObject<{
89
+ collections: z.ZodOptional<z.ZodArray<z.ZodObject<{
90
+ name: z.ZodString;
91
+ path: z.ZodString;
92
+ filePattern: z.ZodOptional<z.ZodString>;
93
+ previewUrl: z.ZodOptional<z.ZodString>;
94
+ schema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
95
+ type: z.ZodEnum<{
96
+ string: "string";
97
+ number: "number";
98
+ boolean: "boolean";
99
+ object: "object";
100
+ date: "date";
101
+ array: "array";
102
+ image: "image";
103
+ }>;
104
+ required: z.ZodOptional<z.ZodBoolean>;
105
+ default: z.ZodOptional<z.ZodUnknown>;
106
+ items: z.ZodOptional<z.ZodString>;
107
+ description: z.ZodOptional<z.ZodString>;
108
+ }, z.core.$strip>>>;
109
+ images: z.ZodOptional<z.ZodObject<{
110
+ strategy: z.ZodEnum<{
111
+ colocated: "colocated";
112
+ public: "public";
113
+ custom: "custom";
114
+ }>;
115
+ publicPath: z.ZodOptional<z.ZodString>;
116
+ storagePath: z.ZodOptional<z.ZodString>;
117
+ }, z.core.$strip>>;
118
+ }, z.core.$strip>>>;
119
+ images: z.ZodOptional<z.ZodObject<{
120
+ strategy: z.ZodEnum<{
121
+ colocated: "colocated";
122
+ public: "public";
123
+ custom: "custom";
124
+ }>;
125
+ publicPath: z.ZodOptional<z.ZodString>;
126
+ storagePath: z.ZodOptional<z.ZodString>;
127
+ }, z.core.$strip>>;
128
+ editor: z.ZodOptional<z.ZodObject<{
129
+ autosave: z.ZodOptional<z.ZodBoolean>;
130
+ autosaveInterval: z.ZodOptional<z.ZodNumber>;
131
+ }, z.core.$strip>>;
132
+ discovery: z.ZodOptional<z.ZodObject<{
133
+ enabled: z.ZodBoolean;
134
+ ignore: z.ZodOptional<z.ZodArray<z.ZodString>>;
135
+ }, z.core.$strip>>;
136
+ versionHistory: z.ZodOptional<z.ZodObject<{
137
+ enabled: z.ZodOptional<z.ZodBoolean>;
138
+ maxVersions: z.ZodOptional<z.ZodNumber>;
139
+ storagePath: z.ZodOptional<z.ZodString>;
140
+ }, z.core.$strip>>;
141
+ }, z.core.$strip>;
142
+ /**
143
+ * Schema for integration options
144
+ */
145
+ declare const writenexOptionsSchema: z.ZodObject<{
146
+ allowProduction: z.ZodOptional<z.ZodBoolean>;
147
+ }, z.core.$strip>;
148
+ /**
149
+ * Helper function for defining type-safe Writenex configuration.
150
+ *
151
+ * This function provides IDE autocompletion and type checking for
152
+ * the configuration object. It's the recommended way to create
153
+ * a writenex.config.ts file.
154
+ *
155
+ * @param config - The Writenex configuration object
156
+ * @returns The same configuration object (identity function for type safety)
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * // writenex.config.ts
161
+ * import { defineConfig } from '@writenex/astro';
162
+ *
163
+ * export default defineConfig({
164
+ * collections: [
165
+ * {
166
+ * name: 'blog',
167
+ * path: 'src/content/blog',
168
+ * filePattern: '{slug}.md',
169
+ * },
170
+ * ],
171
+ * });
172
+ * ```
173
+ */
174
+ declare function defineConfig(config: WritenexConfig): WritenexConfig;
175
+ /**
176
+ * Validate a Writenex configuration object
177
+ *
178
+ * @param config - The configuration to validate
179
+ * @returns Validation result with success status and parsed data or errors
180
+ */
181
+ declare function validateConfig(config: unknown): {
182
+ success: true;
183
+ data: WritenexConfig;
184
+ } | {
185
+ success: false;
186
+ error: z.ZodError;
187
+ };
188
+
189
+ export { type LoadConfigResult as L, writenexOptionsSchema as a, contentDirectoryExists as c, defineConfig as d, findConfigFile as f, loadConfig as l, validateConfig as v, writenexConfigSchema as w };
@@ -1,8 +1,8 @@
1
1
  import { IncomingMessage, ServerResponse } from 'node:http';
2
2
  import { Connect } from 'vite';
3
- import { a as WritenexConfig } from '../config-BmEdBDo_.js';
4
3
  import { W as WritenexError } from '../errors-C0iYiDTv.js';
5
- import { D as DiscoveredCollection, a as ContentSummary } from '../content-BWR52vD-.js';
4
+ import { c as WritenexConfig } from '../config-CliL0CoN.js';
5
+ import { D as DiscoveredCollection, a as ContentSummary } from '../content-TuL3GT66.js';
6
6
  import { D as DiscoveredImage } from '../image-FP7w5ZIs.js';
7
7
 
8
8
  /**
@@ -91,41 +91,6 @@ declare function sendError(res: ServerResponse, message: string, statusCode?: nu
91
91
  */
92
92
  declare function sendWritenexError(res: ServerResponse, error: WritenexError): void;
93
93
 
94
- /**
95
- * @fileoverview API route handlers for Writenex
96
- *
97
- * This module provides the API router that handles CRUD operations
98
- * for content collections.
99
- *
100
- * ## API Endpoints:
101
- * - GET /api/collections - List all collections
102
- * - GET /api/content/:collection - List content in collection
103
- * - GET /api/content/:collection/:id - Get single content item
104
- * - POST /api/content/:collection - Create new content
105
- * - PUT /api/content/:collection/:id - Update content
106
- * - DELETE /api/content/:collection/:id - Delete content
107
- * - GET /api/images/:collection/:contentId - Discover images for content
108
- * - GET /api/images/:collection/:contentId/* - Serve image file
109
- * - POST /api/images - Upload image
110
- * - GET /api/versions/:collection/:id - List versions
111
- * - GET /api/versions/:collection/:id/:versionId - Get version
112
- * - POST /api/versions/:collection/:id - Create manual version
113
- * - POST /api/versions/:collection/:id/:versionId/restore - Restore version
114
- * - GET /api/versions/:collection/:id/:versionId/diff - Get diff data
115
- * - DELETE /api/versions/:collection/:id/:versionId - Delete version
116
- * - DELETE /api/versions/:collection/:id - Clear all versions
117
- *
118
- * @module @writenex/astro/server/routes
119
- */
120
-
121
- /**
122
- * Create the API router
123
- *
124
- * @param context - Middleware context
125
- * @returns Router function that handles API requests
126
- */
127
- declare function createApiRouter(context: MiddlewareContext): (req: IncomingMessage, res: ServerResponse, path: string) => Promise<void>;
128
-
129
94
  /**
130
95
  * @fileoverview Static asset serving for Writenex editor
131
96
  *
@@ -354,4 +319,39 @@ declare function getCache(options?: {
354
319
  */
355
320
  declare function resetCache(): void;
356
321
 
322
+ /**
323
+ * @fileoverview API route handlers for Writenex
324
+ *
325
+ * This module provides the API router that handles CRUD operations
326
+ * for content collections.
327
+ *
328
+ * ## API Endpoints:
329
+ * - GET /api/collections - List all collections
330
+ * - GET /api/content/:collection - List content in collection
331
+ * - GET /api/content/:collection/:id - Get single content item
332
+ * - POST /api/content/:collection - Create new content
333
+ * - PUT /api/content/:collection/:id - Update content
334
+ * - DELETE /api/content/:collection/:id - Delete content
335
+ * - GET /api/images/:collection/:contentId - Discover images for content
336
+ * - GET /api/images/:collection/:contentId/* - Serve image file
337
+ * - POST /api/images - Upload image
338
+ * - GET /api/versions/:collection/:id - List versions
339
+ * - GET /api/versions/:collection/:id/:versionId - Get version
340
+ * - POST /api/versions/:collection/:id - Create manual version
341
+ * - POST /api/versions/:collection/:id/:versionId/restore - Restore version
342
+ * - GET /api/versions/:collection/:id/:versionId/diff - Get diff data
343
+ * - DELETE /api/versions/:collection/:id/:versionId - Delete version
344
+ * - DELETE /api/versions/:collection/:id - Clear all versions
345
+ *
346
+ * @module @writenex/astro/server/routes
347
+ */
348
+
349
+ /**
350
+ * Create the API router
351
+ *
352
+ * @param context - Middleware context
353
+ * @returns Router function that handles API requests
354
+ */
355
+ declare function createApiRouter(context: MiddlewareContext): (req: IncomingMessage, res: ServerResponse, path: string) => Promise<void>;
356
+
357
357
  export { type MiddlewareContext, ServerCache, createApiRouter, createMiddleware, getCache, getClientDistPath, hasClientBundle, parseJsonBody, parseQueryParams, resetCache, sendError, sendJson, sendWritenexError, serveAsset, serveEditorHtml };
@@ -13,11 +13,11 @@ import {
13
13
  sendWritenexError,
14
14
  serveAsset,
15
15
  serveEditorHtml
16
- } from "../chunk-7XU5X6CW.js";
17
- import "../chunk-CYLDJ3HZ.js";
18
- import "../chunk-CF2XXJFF.js";
19
- import "../chunk-AAOQHQPU.js";
20
- import "../chunk-CRPZUUDU.js";
16
+ } from "../chunk-GUUSVFBP.js";
17
+ import "../chunk-GIS7XEJF.js";
18
+ import "../chunk-OWYFIQFK.js";
19
+ import "../chunk-TQAYIZOA.js";
20
+ import "../chunk-YBCPOLMY.js";
21
21
  export {
22
22
  ServerCache,
23
23
  createApiRouter,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@imjp/writenex-astro",
3
- "version": "0.1.0",
4
- "description": "Visual editor for Astro content collections - WYSIWYG editing for your Astro site",
3
+ "version": "1.3.0",
4
+ "description": "Visual editor for Astro content collections - WYSIWYG editing for your Astro site.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -40,7 +40,7 @@
40
40
  "build": "tsup",
41
41
  "prepublishOnly": "pnpm build",
42
42
  "type-check": "tsc --noEmit",
43
- "lint": "eslint src/"
43
+ "lint": "biome lint src/"
44
44
  },
45
45
  "keywords": [
46
46
  "astro",
@@ -68,27 +68,26 @@
68
68
  "access": "public"
69
69
  },
70
70
  "dependencies": {
71
- "@mdxeditor/editor": "^3.52.1",
72
- "chokidar": "^4.0.3",
71
+ "@mdxeditor/editor": "^3.53.1",
72
+ "chokidar": "^5.0.0",
73
73
  "gray-matter": "^4.0.3",
74
- "lucide-react": "^0.561.0",
75
- "slugify": "^1.6.6",
76
- "zod": "^3.24.0"
74
+ "lucide-react": "^1.7.0",
75
+ "slugify": "^1.6.8",
76
+ "zod": "^4.3.6"
77
77
  },
78
78
  "peerDependencies": {
79
- "astro": "^4.0.0 || ^5.0.0",
79
+ "astro": "^4.0.0 || ^5.0.0 || ^6.0.0",
80
80
  "react": "^18.0.0 || ^19.0.0",
81
81
  "react-dom": "^18.0.0 || ^19.0.0"
82
82
  },
83
83
  "devDependencies": {
84
- "@types/node": "^22.19.1",
85
- "@types/react": "^19.1.8",
86
- "@types/react-dom": "^19.1.6",
87
- "@writenex/eslint-config": "workspace:*",
84
+ "@types/node": "^25.5.0",
85
+ "@types/react": "^19.2.14",
86
+ "@types/react-dom": "^19.2.3",
88
87
  "@writenex/tsconfig": "workspace:*",
89
- "astro": "^5.16.5",
90
- "tsup": "^8.5.0",
91
- "typescript": "^5.8.3",
92
- "vite": "^6.4.1"
88
+ "astro": "^6.1.2",
89
+ "tsup": "^8.5.1",
90
+ "typescript": "^6.0.2",
91
+ "vite": "^8.0.3"
93
92
  }
94
- }
93
+ }
@@ -7,41 +7,41 @@
7
7
  * @module @writenex/astro/client/App
8
8
  */
9
9
 
10
+ import { CheckCircle, ExternalLink, FileEdit, Save } from "lucide-react";
10
11
  import { useCallback, useEffect, useRef, useState } from "react";
11
- import { Sidebar } from "./components/Sidebar";
12
+ import type { CollectionSchema } from "../types";
13
+ import { ConfigPanel } from "./components/ConfigPanel/ConfigPanel";
14
+ import { CreateContentModal } from "./components/CreateContentModal";
15
+ import { FrontmatterForm } from "./components/FrontmatterForm";
16
+ import { Header } from "./components/Header";
17
+ import { ShortcutsHelpModal } from "./components/KeyboardShortcuts";
12
18
  import {
13
19
  LazyEditor as Editor,
14
20
  EditorEmpty,
15
21
  EditorLoading,
16
22
  } from "./components/LazyEditor";
17
- import { ConfigPanel } from "./components/ConfigPanel/ConfigPanel";
18
- import { CreateContentModal } from "./components/CreateContentModal";
23
+ import { LiveRegion } from "./components/LiveRegion";
24
+ import { SearchReplacePanel } from "./components/SearchReplace";
19
25
  import { SelectCollectionModal } from "./components/SelectCollectionModal";
26
+ import { Sidebar } from "./components/Sidebar";
27
+ import { SkipLink } from "./components/SkipLink";
20
28
  import { UnsavedChangesModal } from "./components/UnsavedChangesModal";
21
- import { Header } from "./components/Header";
22
- import { FrontmatterForm } from "./components/FrontmatterForm";
23
- import { Save, FileEdit, CheckCircle, ExternalLink } from "lucide-react";
24
- import type { CollectionSchema } from "../types";
29
+ import { VersionHistoryPanel } from "./components/VersionHistory";
30
+ import { useSharedApi } from "./context/ApiContext";
31
+ import { useAnnounce } from "./hooks/useAnnounce";
25
32
  import {
33
+ type ContentItem,
26
34
  useCollections,
27
- useContentList,
28
35
  useConfig,
29
- type ContentItem,
36
+ useContentList,
30
37
  } from "./hooks/useApi";
31
- import { useSharedApi } from "./context/ApiContext";
32
38
  import {
33
- useAutosave,
34
- formatLastSaved,
35
39
  type AutosaveStatus,
40
+ formatLastSaved,
41
+ useAutosave,
36
42
  } from "./hooks/useAutosave";
37
43
  import { useKeyboardShortcuts } from "./hooks/useKeyboardShortcuts";
38
- import { ShortcutsHelpModal } from "./components/KeyboardShortcuts";
39
- import { SearchReplacePanel } from "./components/SearchReplace";
40
44
  import { useSearch } from "./hooks/useSearch";
41
- import { VersionHistoryPanel } from "./components/VersionHistory";
42
- import { SkipLink } from "./components/SkipLink";
43
- import { LiveRegion } from "./components/LiveRegion";
44
- import { useAnnounce } from "./hooks/useAnnounce";
45
45
 
46
46
  function generatePreviewUrl(
47
47
  pattern: string,