@nuasite/cms 0.18.0 → 0.19.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 (62) hide show
  1. package/dist/editor.js +44697 -26834
  2. package/package.json +23 -21
  3. package/src/build-processor.ts +4 -1
  4. package/src/collection-scanner.ts +425 -48
  5. package/src/dev-middleware.ts +26 -203
  6. package/src/editor/api.ts +1 -22
  7. package/src/editor/components/ai-chat.tsx +3 -3
  8. package/src/editor/components/ai-tooltip.tsx +2 -1
  9. package/src/editor/components/block-editor.tsx +13 -108
  10. package/src/editor/components/collections-browser.tsx +168 -205
  11. package/src/editor/components/component-card.tsx +49 -0
  12. package/src/editor/components/confirm-dialog.tsx +34 -47
  13. package/src/editor/components/create-page-modal.tsx +529 -101
  14. package/src/editor/components/delete-page-dialog.tsx +100 -0
  15. package/src/editor/components/fields.tsx +175 -0
  16. package/src/editor/components/frontmatter-fields.tsx +281 -70
  17. package/src/editor/components/frontmatter-sidebar.tsx +223 -0
  18. package/src/editor/components/highlight-overlay.ts +3 -2
  19. package/src/editor/components/markdown-editor-overlay.tsx +131 -85
  20. package/src/editor/components/markdown-inline-editor.tsx +74 -5
  21. package/src/editor/components/mdx-block-view.tsx +102 -0
  22. package/src/editor/components/mdx-component-picker.tsx +123 -0
  23. package/src/editor/components/mdx-props-editor.tsx +94 -0
  24. package/src/editor/components/media-library.tsx +373 -100
  25. package/src/editor/components/modal-shell.tsx +87 -0
  26. package/src/editor/components/prop-editor.tsx +52 -0
  27. package/src/editor/components/redirect-countdown.tsx +3 -1
  28. package/src/editor/components/redirects-manager.tsx +269 -0
  29. package/src/editor/components/reference-picker.tsx +203 -0
  30. package/src/editor/components/seo-editor.tsx +285 -303
  31. package/src/editor/components/toast/toast-container.tsx +2 -1
  32. package/src/editor/components/toolbar.tsx +177 -46
  33. package/src/editor/constants.ts +26 -0
  34. package/src/editor/editor.ts +112 -0
  35. package/src/editor/fetch.ts +62 -0
  36. package/src/editor/index.tsx +19 -1
  37. package/src/editor/markdown-api.ts +105 -156
  38. package/src/editor/milkdown-mdx-plugin.tsx +269 -0
  39. package/src/editor/signals.ts +206 -13
  40. package/src/editor/types.ts +52 -1
  41. package/src/handlers/api-routes.ts +251 -0
  42. package/src/handlers/component-ops.ts +2 -18
  43. package/src/handlers/markdown-ops.ts +202 -47
  44. package/src/handlers/page-ops.ts +229 -0
  45. package/src/handlers/redirect-ops.ts +163 -0
  46. package/src/handlers/source-writer.ts +157 -1
  47. package/src/html-processor.ts +14 -2
  48. package/src/index.ts +76 -2
  49. package/src/manifest-writer.ts +19 -1
  50. package/src/media/contember.ts +2 -1
  51. package/src/media/local.ts +66 -28
  52. package/src/media/project-images.ts +81 -0
  53. package/src/media/s3.ts +32 -11
  54. package/src/media/types.ts +24 -2
  55. package/src/shared.ts +27 -0
  56. package/src/source-finder/collection-finder.ts +219 -41
  57. package/src/source-finder/index.ts +7 -1
  58. package/src/source-finder/search-index.ts +178 -36
  59. package/src/source-finder/snippet-utils.ts +423 -3
  60. package/src/tsconfig.json +0 -2
  61. package/src/types.ts +111 -2
  62. package/src/utils.ts +40 -4
package/src/utils.ts CHANGED
@@ -143,11 +143,14 @@ export function escapeReplacement(str: string): string {
143
143
  */
144
144
  export function resolveAndValidatePath(filePath: string): string {
145
145
  const projectRoot = getProjectRoot()
146
- const fullPath = path.isAbsolute(filePath)
147
- ? path.resolve(filePath)
148
- : path.resolve(projectRoot, filePath)
149
-
150
146
  const resolvedRoot = path.resolve(projectRoot)
147
+ // Absolute filesystem paths (e.g. /Users/...) stay intact;
148
+ // project-relative paths with a leading slash (e.g. /src/content/...) get it stripped
149
+ const isAbsoluteFs = filePath.startsWith(resolvedRoot)
150
+ const normalizedPath = (!isAbsoluteFs && filePath.startsWith('/')) ? filePath.slice(1) : filePath
151
+ const fullPath = path.isAbsolute(normalizedPath) ? path.resolve(normalizedPath) : path.resolve(projectRoot, normalizedPath)
152
+
153
+ // Ensure the resolved path is within the project root
151
154
  if (!fullPath.startsWith(resolvedRoot + path.sep) && fullPath !== resolvedRoot) {
152
155
  throw new Error(`Path traversal detected: ${filePath}`)
153
156
  }
@@ -184,3 +187,36 @@ export async function acquireFileLock(filePath: string): Promise<() => void> {
184
187
  release()
185
188
  }
186
189
  }
190
+
191
+ export { slugify } from './shared'
192
+
193
+ /**
194
+ * Type-safe check for Node.js system errors (ENOENT, EEXIST, etc.).
195
+ */
196
+ export function isNodeError(error: unknown, code: string): boolean {
197
+ return error instanceof Error && 'code' in error && (error as NodeJS.ErrnoException).code === code
198
+ }
199
+
200
+ /**
201
+ * Escape HTML special characters to prevent injection.
202
+ * Covers &, <, >, ", and ' — the full set needed for both text content and attribute values.
203
+ */
204
+ export function escapeHtml(text: string): string {
205
+ return text
206
+ .replace(/&/g, '&amp;')
207
+ .replace(/</g, '&lt;')
208
+ .replace(/>/g, '&gt;')
209
+ .replace(/"/g, '&quot;')
210
+ .replace(/'/g, '&#39;')
211
+ }
212
+
213
+ /**
214
+ * Compute a POSIX-style relative import path from one file to another.
215
+ * Ensures the result starts with `./' or `../` and uses forward slashes.
216
+ */
217
+ export function relativeImportPath(fromFile: string, toFile: string): string {
218
+ const fromDir = path.dirname(fromFile)
219
+ let rel = path.relative(fromDir, toFile).split(path.sep).join('/')
220
+ if (!rel.startsWith('.')) rel = `./${rel}`
221
+ return rel
222
+ }