jamdesk 1.0.22 → 1.1.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 (33) hide show
  1. package/dist/__tests__/unit/package-config.test.js +1 -1
  2. package/dist/__tests__/unit/package-config.test.js.map +1 -1
  3. package/dist/lib/deps.js +4 -4
  4. package/dist/lib/deps.js.map +1 -1
  5. package/package.json +3 -4
  6. package/vendored/app/[[...slug]]/page.tsx +31 -16
  7. package/vendored/app/api/og/route.tsx +13 -23
  8. package/vendored/app/api/raw-content/[...slug]/route.ts +28 -0
  9. package/vendored/app/layout.tsx +56 -16
  10. package/vendored/components/AIActionsMenu.tsx +677 -0
  11. package/vendored/components/mdx/ApiEndpoint.tsx +2 -1
  12. package/vendored/components/mdx/ImagePriorityProvider.tsx +53 -0
  13. package/vendored/components/mdx/MDXComponents.tsx +15 -0
  14. package/vendored/components/mdx/ZoomableImage.tsx +35 -27
  15. package/vendored/lib/analytics-script.ts +0 -8
  16. package/vendored/lib/contextual-defaults.ts +16 -0
  17. package/vendored/lib/docs-types.ts +12 -3
  18. package/vendored/lib/enhance-navigation.ts +1 -1
  19. package/vendored/lib/isr-build-executor.ts +41 -0
  20. package/vendored/lib/preprocess-mdx.ts +5 -3
  21. package/vendored/lib/r2-content.ts +2 -0
  22. package/vendored/lib/redirect-matcher.ts +31 -0
  23. package/vendored/lib/revalidation-helpers.ts +10 -0
  24. package/vendored/lib/revalidation-trigger.ts +7 -3
  25. package/vendored/lib/seo.ts +10 -20
  26. package/vendored/lib/static-artifacts.ts +43 -0
  27. package/vendored/lib/static-file-route.ts +11 -1
  28. package/vendored/schema/docs-schema.json +36 -3
  29. package/vendored/scripts/copy-files.cjs +47 -4
  30. package/vendored/components/snippets/generated/CodeLink.tsx +0 -25
  31. package/vendored/components/snippets/generated/HeaderAPI.tsx +0 -44
  32. package/vendored/components/snippets/generated/PlansAvailable.tsx +0 -53
  33. package/vendored/components/snippets/generated/SnippetIntro.tsx +0 -43
@@ -879,6 +879,24 @@
879
879
  "typography": {
880
880
  "type": "boolean",
881
881
  "description": "Enable typography enhancements: smart quotes (\u201ccurly\u201d), en-dashes (\u2013), em-dashes (\u2014), and ellipses (\u2026). Defaults to `false`"
882
+ },
883
+ "js": {
884
+ "anyOf": [
885
+ {
886
+ "type": "string",
887
+ "pattern": "^/",
888
+ "description": "Path to a custom JavaScript file relative to your docs directory (e.g., \"/script.js\")"
889
+ },
890
+ {
891
+ "type": "array",
892
+ "items": {
893
+ "type": "string",
894
+ "pattern": "^/"
895
+ },
896
+ "description": "Array of custom JavaScript file paths to include on every page"
897
+ }
898
+ ],
899
+ "description": "Custom JavaScript to include on every page. Specify a file path or array of paths relative to your docs directory"
882
900
  }
883
901
  },
884
902
  "additionalProperties": false,
@@ -1040,6 +1058,19 @@
1040
1058
  ],
1041
1059
  "additionalProperties": false
1042
1060
  },
1061
+ "crisp": {
1062
+ "type": "object",
1063
+ "properties": {
1064
+ "websiteId": {
1065
+ "type": "string",
1066
+ "minLength": 8
1067
+ }
1068
+ },
1069
+ "required": [
1070
+ "websiteId"
1071
+ ],
1072
+ "additionalProperties": false
1073
+ },
1043
1074
  "intercom": {
1044
1075
  "type": "object",
1045
1076
  "properties": {
@@ -1248,6 +1279,10 @@
1248
1279
  "contextual": {
1249
1280
  "type": "object",
1250
1281
  "properties": {
1282
+ "enabled": {
1283
+ "type": "boolean",
1284
+ "description": "Enable or disable the AI Actions menu. Default: true"
1285
+ },
1251
1286
  "options": {
1252
1287
  "type": "array",
1253
1288
  "items": {
@@ -1259,6 +1294,7 @@
1259
1294
  "view",
1260
1295
  "chatgpt",
1261
1296
  "claude",
1297
+ "gemini",
1262
1298
  "perplexity",
1263
1299
  "mcp",
1264
1300
  "cursor",
@@ -1330,9 +1366,6 @@
1330
1366
  "description": "Contextual menu options available on documentation pages"
1331
1367
  }
1332
1368
  },
1333
- "required": [
1334
- "options"
1335
- ],
1336
1369
  "additionalProperties": false,
1337
1370
  "description": "Configure contextual menu options for page actions (copy, view source, AI chat, etc.)"
1338
1371
  },
@@ -3,7 +3,7 @@
3
3
  * Copy Static Assets Script
4
4
  *
5
5
  * Copies static assets from project's images directory to public/images.
6
- * Also copies custom style.css and script.js if they exist in project root.
6
+ * Also copies custom style.css and JS files if they exist in project root.
7
7
  * Supports project-specific builds via PROJECT_NAME environment variable.
8
8
  *
9
9
  * File type and size restrictions:
@@ -17,7 +17,8 @@
17
17
  *
18
18
  * Custom Files (optional):
19
19
  * projects/<name>/style.css -> public/custom.css (overrides theme styles)
20
- * projects/<name>/script.js -> public/custom.js (custom JavaScript)
20
+ * projects/<name>/*.js -> public/custom.js (custom JavaScript, concatenated)
21
+ * - Configured via styling.js in docs.json, or auto-detected from project root
21
22
  *
22
23
  */
23
24
 
@@ -94,7 +95,6 @@ async function copyCustomFiles() {
94
95
 
95
96
  const customFiles = [
96
97
  { src: 'style.css', dest: 'custom.css', configKey: '_hasCustomCss' },
97
- { src: 'script.js', dest: 'custom.js', configKey: '_hasCustomJs' },
98
98
  { src: 'sitemap.xml', dest: 'sitemap.xml', configKey: '_hasCustomSitemap' },
99
99
  { src: 'robots.txt', dest: 'robots.txt', configKey: '_hasCustomRobots' },
100
100
  ];
@@ -125,7 +125,50 @@ async function copyCustomFiles() {
125
125
  docsConfig[configKey] = false;
126
126
  }
127
127
  }
128
-
128
+
129
+ // Handle custom JavaScript (supports styling.js config + auto-detection)
130
+ const customJsDest = path.join(publicDir, 'custom.js');
131
+ let jsFiles = [];
132
+
133
+ if (docsConfig.styling?.js) {
134
+ // Use configured paths from styling.js
135
+ const configured = Array.isArray(docsConfig.styling.js)
136
+ ? docsConfig.styling.js
137
+ : [docsConfig.styling.js];
138
+ jsFiles = configured.map(p => p.replace(/^\//, ''));
139
+ } else {
140
+ // Auto-detect .js files in project root
141
+ try {
142
+ jsFiles = fs.readdirSync(projectDir)
143
+ .filter(f => f.endsWith('.js') && fs.statSync(path.join(projectDir, f)).isFile())
144
+ .sort();
145
+ } catch { /* ignore */ }
146
+ }
147
+
148
+ if (jsFiles.length > 0) {
149
+ const jsContents = [];
150
+ for (const file of jsFiles) {
151
+ const srcPath = path.join(projectDir, file);
152
+ if (fs.existsSync(srcPath)) {
153
+ jsContents.push(fs.readFileSync(srcPath, 'utf8'));
154
+ }
155
+ }
156
+ if (jsContents.length > 0) {
157
+ fs.writeFileSync(customJsDest, jsContents.join('\n'));
158
+ docsConfig._hasCustomJs = true;
159
+ console.log(` ✓ Custom JS (${jsFiles.join(', ')}) -> custom.js`);
160
+ } else {
161
+ // All configured files missing — clean up stale custom.js
162
+ if (fs.existsSync(customJsDest)) fs.removeSync(customJsDest);
163
+ docsConfig._hasCustomJs = false;
164
+ }
165
+ } else {
166
+ if (fs.existsSync(customJsDest)) {
167
+ fs.removeSync(customJsDest);
168
+ }
169
+ docsConfig._hasCustomJs = false;
170
+ }
171
+
129
172
  // Write updated docs.json with custom file flags
130
173
  await fs.writeJson(docsJsonPath, docsConfig, { spaces: 2 });
131
174
  }
@@ -1,25 +0,0 @@
1
- // Auto-generated file - do not edit manually
2
- // @ts-nocheck
3
-
4
- import React from 'react';
5
-
6
- // Import built-in MDX components that snippets can use
7
- import { Note, Info, Warning, Tip, Check, Danger, Callout } from '@/components/mdx/Callouts';
8
- import { Card } from '@/components/mdx/Card';
9
- import { CardGroup } from '@/components/mdx/CardGroup';
10
- import { ParamField } from '@/components/mdx/ParamField';
11
- import { ResponseField } from '@/components/mdx/ResponseField';
12
- import { Accordion, AccordionGroup } from '@/components/mdx/Accordion';
13
- import { CodeGroup } from '@/components/mdx/CodeGroup';
14
- import { Steps, Step } from '@/components/mdx/Steps';
15
-
16
-
17
- const CodeLink = ({ title, href }: any) => {
18
- return (
19
- <Card title={`${title}`} href={`${href}`} horizontal icon="code">
20
- {" "}
21
- </Card>
22
- );
23
- };
24
-
25
- export default CodeLink;
@@ -1,44 +0,0 @@
1
- // Auto-generated file - do not edit manually
2
- // @ts-nocheck
3
-
4
- import React from 'react';
5
-
6
- // Import built-in MDX components that snippets can use
7
- import { Note, Info, Warning, Tip, Check, Danger, Callout } from '@/components/mdx/Callouts';
8
- import { Card } from '@/components/mdx/Card';
9
- import { CardGroup } from '@/components/mdx/CardGroup';
10
- import { ParamField } from '@/components/mdx/ParamField';
11
- import { ResponseField } from '@/components/mdx/ResponseField';
12
- import { Accordion, AccordionGroup } from '@/components/mdx/Accordion';
13
- import { CodeGroup } from '@/components/mdx/CodeGroup';
14
- import { Steps, Step } from '@/components/mdx/Steps';
15
-
16
-
17
- const HeaderAPI = ({ noProfileKey, profileKeyRequired }: any) => (
18
- <>
19
- <ParamField header="Authorization" type="string" required>
20
- <a href="/apis/overview#authorization">API Key</a> of the Primary Profile.
21
- <br />
22
- <br />
23
- Format: <code>Authorization: Bearer API_KEY</code>
24
- </ParamField>
25
- {!noProfileKey &&
26
- (profileKeyRequired ? (
27
- <ParamField header="Profile-Key" type="string" required>
28
- <a href="/apis/overview#profile-key-format">Profile Key</a> of a User Profile.
29
- <br />
30
- <br />
31
- Format: <code>Profile-Key: PROFILE_KEY</code>
32
- </ParamField>
33
- ) : (
34
- <ParamField header="Profile-Key" type="string">
35
- <a href="/apis/overview#profile-key-format">Profile Key</a> of a User Profile.
36
- <br />
37
- <br />
38
- Format: <code>Profile-Key: PROFILE_KEY</code>
39
- </ParamField>
40
- ))}
41
- </>
42
- );
43
-
44
- export default HeaderAPI;
@@ -1,53 +0,0 @@
1
- // Auto-generated file - do not edit manually
2
- // @ts-nocheck
3
-
4
- import React from 'react';
5
-
6
- // Import built-in MDX components that snippets can use
7
- import { Note, Info, Warning, Tip, Check, Danger, Callout } from '@/components/mdx/Callouts';
8
- import { Card } from '@/components/mdx/Card';
9
- import { CardGroup } from '@/components/mdx/CardGroup';
10
- import { ParamField } from '@/components/mdx/ParamField';
11
- import { ResponseField } from '@/components/mdx/ResponseField';
12
- import { Accordion, AccordionGroup } from '@/components/mdx/Accordion';
13
- import { CodeGroup } from '@/components/mdx/CodeGroup';
14
- import { Steps, Step } from '@/components/mdx/Steps';
15
-
16
-
17
- const PlansAvailable = ({ plans, maxPackRequired }: any) => {
18
- let displayPlans = plans;
19
-
20
- if (plans.length === 1) {
21
- const lowerCasePlan = plans[0].toLowerCase();
22
- if (lowerCasePlan === "basic") {
23
- displayPlans = ["Basic", "Premium", "Business", "Enterprise"];
24
- } else if (lowerCasePlan === "business") {
25
- displayPlans = ["Business", "Enterprise"];
26
- } else if (lowerCasePlan === "premium") {
27
- displayPlans = ["Premium", "Business", "Enterprise"];
28
- }
29
- }
30
-
31
- return (
32
-
33
- <Note>
34
- Available on {displayPlans.length === 1 ? "the " : ""}
35
- {displayPlans.join(", ").replace(/\b\w/g, (l) => l.toUpperCase())}{" "}
36
- {displayPlans.length > 1 ? "plans" : "plan"}.
37
-
38
- {maxPackRequired && (
39
-
40
- <a href="https://www.acme.com/docs/additional/maxpack"
41
- className="flex items-center mt-2 cursor-pointer"
42
- >
43
- <span className="px-1.5 py-0.5 rounded text-sm" style={{backgroundColor: '#C264B6', color: 'white', fontSize: '12px'}}>
44
- Max Pack required
45
- </span>
46
- </a>
47
- )}
48
- </Note>
49
-
50
- );
51
- };
52
-
53
- export default PlansAvailable;
@@ -1,43 +0,0 @@
1
- // Auto-generated file - do not edit manually
2
- // @ts-nocheck
3
-
4
- import React from 'react';
5
-
6
- // Import built-in MDX components that snippets can use
7
- import { Note, Info, Warning, Tip, Check, Danger, Callout } from '@/components/mdx/Callouts';
8
- import { Card } from '@/components/mdx/Card';
9
- import { CardGroup } from '@/components/mdx/CardGroup';
10
- import { ParamField } from '@/components/mdx/ParamField';
11
- import { ResponseField } from '@/components/mdx/ResponseField';
12
- import { Accordion, AccordionGroup } from '@/components/mdx/Accordion';
13
- import { CodeGroup } from '@/components/mdx/CodeGroup';
14
- import { Steps, Step } from '@/components/mdx/Steps';
15
-
16
-
17
- // Helper component for rendering plain MDX snippets
18
- // Content is from project snippets (controlled source), not user input
19
- const PlainMdxSnippet = ({ content }: { content: string }) => {
20
- const formattedContent = content
21
- .split('\n\n')
22
- .map((paragraph) => {
23
- let html = paragraph.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
24
- html = html.replace(/\*([^*]+)\*/g, '<em>$1</em>');
25
- html = html.replace(/\`([^\`]+)\`/g, '<code>$1</code>');
26
- return html;
27
- })
28
- .filter(p => p.trim());
29
-
30
- return (
31
- <div className="snippet-content">
32
- {formattedContent.map((p, i) => (
33
- <p key={i} dangerouslySetInnerHTML={{ __html: p }} />
34
- ))}
35
- </div>
36
- );
37
- };
38
-
39
- const SnippetIntro = () => {
40
- return <PlainMdxSnippet content={"One of the core principles of software development is DRY (Don't Repeat\nYourself). This is a principle that apply to documentation as\nwell. If you find yourself repeating the same content in multiple places, you\nshould consider creating a custom snippet to keep your content in sync."} />;
41
- };
42
-
43
- export default SnippetIntro;