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.
- package/dist/__tests__/unit/package-config.test.js +1 -1
- package/dist/__tests__/unit/package-config.test.js.map +1 -1
- package/dist/lib/deps.js +4 -4
- package/dist/lib/deps.js.map +1 -1
- package/package.json +3 -4
- package/vendored/app/[[...slug]]/page.tsx +31 -16
- package/vendored/app/api/og/route.tsx +13 -23
- package/vendored/app/api/raw-content/[...slug]/route.ts +28 -0
- package/vendored/app/layout.tsx +56 -16
- package/vendored/components/AIActionsMenu.tsx +677 -0
- package/vendored/components/mdx/ApiEndpoint.tsx +2 -1
- package/vendored/components/mdx/ImagePriorityProvider.tsx +53 -0
- package/vendored/components/mdx/MDXComponents.tsx +15 -0
- package/vendored/components/mdx/ZoomableImage.tsx +35 -27
- package/vendored/lib/analytics-script.ts +0 -8
- package/vendored/lib/contextual-defaults.ts +16 -0
- package/vendored/lib/docs-types.ts +12 -3
- package/vendored/lib/enhance-navigation.ts +1 -1
- package/vendored/lib/isr-build-executor.ts +41 -0
- package/vendored/lib/preprocess-mdx.ts +5 -3
- package/vendored/lib/r2-content.ts +2 -0
- package/vendored/lib/redirect-matcher.ts +31 -0
- package/vendored/lib/revalidation-helpers.ts +10 -0
- package/vendored/lib/revalidation-trigger.ts +7 -3
- package/vendored/lib/seo.ts +10 -20
- package/vendored/lib/static-artifacts.ts +43 -0
- package/vendored/lib/static-file-route.ts +11 -1
- package/vendored/schema/docs-schema.json +36 -3
- package/vendored/scripts/copy-files.cjs +47 -4
- package/vendored/components/snippets/generated/CodeLink.tsx +0 -25
- package/vendored/components/snippets/generated/HeaderAPI.tsx +0 -44
- package/vendored/components/snippets/generated/PlansAvailable.tsx +0 -53
- 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
|
|
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
|
|
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;
|