jamdesk 1.0.5 → 1.0.7

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 (51) hide show
  1. package/README.md +1 -1
  2. package/dist/__tests__/integration/init.integration.test.d.ts +2 -0
  3. package/dist/__tests__/integration/init.integration.test.d.ts.map +1 -0
  4. package/dist/__tests__/integration/init.integration.test.js +135 -0
  5. package/dist/__tests__/integration/init.integration.test.js.map +1 -0
  6. package/dist/__tests__/unit/deploy-templates.test.js +8 -0
  7. package/dist/__tests__/unit/deploy-templates.test.js.map +1 -1
  8. package/dist/__tests__/unit/deps-sync.test.js +77 -1
  9. package/dist/__tests__/unit/deps-sync.test.js.map +1 -1
  10. package/dist/__tests__/unit/init.test.d.ts +2 -0
  11. package/dist/__tests__/unit/init.test.d.ts.map +1 -0
  12. package/dist/__tests__/unit/init.test.js +202 -0
  13. package/dist/__tests__/unit/init.test.js.map +1 -0
  14. package/dist/commands/deploy/templates.d.ts.map +1 -1
  15. package/dist/commands/deploy/templates.js +8 -1
  16. package/dist/commands/deploy/templates.js.map +1 -1
  17. package/dist/commands/init.d.ts +7 -1
  18. package/dist/commands/init.d.ts.map +1 -1
  19. package/dist/commands/init.js +64 -33
  20. package/dist/commands/init.js.map +1 -1
  21. package/dist/index.js +6 -5
  22. package/dist/index.js.map +1 -1
  23. package/dist/lib/deps.js +4 -4
  24. package/dist/lib/deps.js.map +1 -1
  25. package/dist/lib/download.d.ts +12 -0
  26. package/dist/lib/download.d.ts.map +1 -0
  27. package/dist/lib/download.js +65 -0
  28. package/dist/lib/download.js.map +1 -0
  29. package/dist/lib/template-substitution.d.ts +14 -0
  30. package/dist/lib/template-substitution.d.ts.map +1 -0
  31. package/dist/lib/template-substitution.js +29 -0
  32. package/dist/lib/template-substitution.js.map +1 -0
  33. package/dist/utils/update-checker.d.ts.map +1 -1
  34. package/dist/utils/update-checker.js +15 -4
  35. package/dist/utils/update-checker.js.map +1 -1
  36. package/package.json +3 -3
  37. package/vendored/app/[[...slug]]/page.tsx +6 -1
  38. package/vendored/app/api/mcp/[project]/route.ts +10 -5
  39. package/vendored/app/api/r2/[project]/[...path]/route.ts +17 -14
  40. package/vendored/app/layout.tsx +6 -6
  41. package/vendored/components/navigation/Header.tsx +1 -1
  42. package/vendored/components/navigation/Sidebar.tsx +1 -1
  43. package/vendored/lib/build/error-parser.ts +14 -0
  44. package/vendored/lib/docs-types.ts +22 -7
  45. package/vendored/lib/mdx-security-options.ts +11 -0
  46. package/vendored/lib/mdx.ts +3 -1
  47. package/vendored/lib/page-isr-helpers.ts +10 -2
  48. package/vendored/lib/preprocess-mdx.ts +56 -80
  49. package/vendored/lib/revalidation-helpers.ts +3 -2
  50. package/vendored/lib/revalidation-trigger.ts +57 -52
  51. package/vendored/next.config.js +12 -0
@@ -1,57 +1,59 @@
1
1
  /**
2
- * Revalidation Trigger
3
- *
4
- * Triggers cache revalidation on the Vercel ISR deployment
2
+ * Triggers cache revalidation on the Vercel ISR app and proxy
5
3
  * after content updates from the build service.
6
4
  */
7
5
 
8
6
  import { log } from './logger.js';
9
7
 
10
- /**
11
- * Options for triggering revalidation.
12
- */
13
8
  export interface RevalidationOptions {
14
- /** Project slug */
15
9
  projectSlug: string;
16
10
  /** Specific paths that changed (without .mdx extension) */
17
11
  changedPaths?: string[];
18
- /** Revalidate all pages for this project */
19
12
  all?: boolean;
20
13
  }
21
14
 
22
15
  /**
23
- * Trigger cache revalidation on the ISR app.
24
- *
25
- * Called by the build service after uploading content to R2.
26
- * This ensures that cached pages are refreshed with new content.
27
- *
28
- * Environment variables:
29
- * - ISR_APP_URL: URL of the ISR deployment (preferred)
30
- * - VERCEL_DEPLOYMENT_URL: Fallback for backward compatibility
31
- *
32
- * @param options - Revalidation options
16
+ * Trigger cache revalidation on the ISR app and proxy.
17
+ * Called after uploading content to R2.
33
18
  */
34
19
  export async function triggerRevalidation(options: RevalidationOptions): Promise<void> {
35
20
  const { projectSlug, changedPaths, all } = options;
36
21
 
37
- // ISR_APP_URL is the preferred env var, VERCEL_DEPLOYMENT_URL is for backward compatibility
38
22
  const isrAppUrl = process.env.ISR_APP_URL || process.env.VERCEL_DEPLOYMENT_URL || 'https://docs.jamdesk.app';
39
- const secret = process.env.REVALIDATE_SECRET || '';
23
+ const secret = (process.env.REVALIDATE_SECRET || '').trim();
40
24
 
41
25
  const body: Record<string, unknown> = {
42
26
  project: projectSlug,
43
27
  };
44
28
 
45
- if (all) {
29
+ if (all || !changedPaths?.length) {
46
30
  body.all = true;
47
- } else if (changedPaths && changedPaths.length > 0) {
48
- // Convert file paths to URL paths (add leading slash)
49
- body.paths = changedPaths.map(p => `/${p}`);
50
31
  } else {
51
- // If no specific paths, revalidate all for this project
52
- body.all = true;
32
+ body.paths = changedPaths.map(p => `/${p}`);
53
33
  }
54
34
 
35
+ // Proxy failure is non-fatal — cache will expire on its own
36
+ const [isrResult] = await Promise.all([
37
+ revalidateIsrApp(isrAppUrl, secret, body),
38
+ revalidateProxy(secret, projectSlug),
39
+ ]);
40
+
41
+ // Only throw if ISR revalidation failed (it's the critical one)
42
+ if (!isrResult.ok) {
43
+ throw new Error(`Revalidation failed: ${isrResult.status} - ${isrResult.error}`);
44
+ }
45
+
46
+ log('info', 'Revalidation triggered successfully', {
47
+ projectSlug,
48
+ revalidated: isrResult.revalidated || ['all'],
49
+ });
50
+ }
51
+
52
+ async function revalidateIsrApp(
53
+ isrAppUrl: string,
54
+ secret: string,
55
+ body: Record<string, unknown>,
56
+ ): Promise<{ ok: boolean; status?: number; error?: string; revalidated?: string[] }> {
55
57
  const response = await fetch(`${isrAppUrl}/api/revalidate`, {
56
58
  method: 'POST',
57
59
  headers: {
@@ -63,32 +65,43 @@ export async function triggerRevalidation(options: RevalidationOptions): Promise
63
65
 
64
66
  if (!response.ok) {
65
67
  const error = await response.text();
66
- throw new Error(`Revalidation failed: ${response.status} - ${error}`);
68
+ return { ok: false, status: response.status, error };
67
69
  }
68
70
 
69
71
  const result = (await response.json()) as { success: boolean; revalidated?: string[] };
70
- log('info', 'Revalidation triggered successfully', {
71
- projectSlug,
72
- revalidated: result.revalidated || ['all'],
73
- });
72
+ return { ok: true, revalidated: result.revalidated };
73
+ }
74
+
75
+ /** Purge the proxy's Vercel CDN cache. Non-fatal on failure. */
76
+ async function revalidateProxy(secret: string, projectSlug: string): Promise<void> {
77
+ const proxyUrl = process.env.PROXY_REVALIDATE_URL;
78
+ if (!proxyUrl) return;
79
+
80
+ try {
81
+ const response = await fetch(`${proxyUrl}/api/revalidate`, {
82
+ method: 'POST',
83
+ headers: { 'Content-Type': 'application/json' },
84
+ body: JSON.stringify({ project: projectSlug, secret }),
85
+ });
86
+
87
+ if (!response.ok) {
88
+ const error = await response.text();
89
+ log('warn', 'Proxy revalidation failed (non-fatal)', {
90
+ projectSlug, status: response.status, error,
91
+ });
92
+ }
93
+ } catch (err) {
94
+ log('warn', 'Proxy revalidation error (non-fatal)', {
95
+ projectSlug, error: (err as Error).message,
96
+ });
97
+ }
74
98
  }
75
99
 
76
- /**
77
- * Manifest structure for comparing file changes.
78
- */
79
100
  export interface Manifest {
80
101
  files: Record<string, { hash: string }>;
81
102
  }
82
103
 
83
- /**
84
- * Compare manifests and return paths that changed.
85
- *
86
- * Used to determine which pages need revalidation after a build.
87
- *
88
- * @param oldManifest - Previous manifest (null for first build)
89
- * @param newManifest - New manifest after build
90
- * @returns Array of changed paths (without .mdx extension)
91
- */
104
+ /** Compare manifests and return paths that changed (without .mdx extension). */
92
105
  export function getChangedPaths(
93
106
  oldManifest: Manifest | null,
94
107
  newManifest: Manifest
@@ -118,15 +131,7 @@ export function getChangedPaths(
118
131
  return changed;
119
132
  }
120
133
 
121
- /**
122
- * Trigger revalidation for changed files between manifests.
123
- *
124
- * Convenience function that combines getChangedPaths and triggerRevalidation.
125
- *
126
- * @param projectSlug - Project identifier
127
- * @param oldManifest - Previous manifest (null for first build)
128
- * @param newManifest - New manifest after build
129
- */
134
+ /** Trigger revalidation for changed files between manifests. */
130
135
  export async function triggerRevalidationForChanges(
131
136
  projectSlug: string,
132
137
  oldManifest: Manifest | null,
@@ -14,6 +14,18 @@
14
14
  const nextConfig = {
15
15
  // Hide dev indicator (floating icon in bottom-left)
16
16
  devIndicators: false,
17
+ // Allow /_jd/ image paths with ?v= cache-busting query strings in <Image>
18
+ images: {
19
+ localPatterns: [
20
+ {
21
+ pathname: '/_jd/**',
22
+ },
23
+ {
24
+ pathname: '/**',
25
+ search: '',
26
+ },
27
+ ],
28
+ },
17
29
  // Keep swagger-parser external (uses Node.js APIs)
18
30
  serverExternalPackages: ['@apidevtools/swagger-parser'],
19
31
  // Turbopack config - only resolveAlias, NOT root (root causes caching issues)