create-specra 0.1.7 → 0.2.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/LICENSE.MD +16 -4
- package/README.md +53 -17
- package/dist/chunk-3DKWECRK.js +45 -0
- package/dist/chunk-3DKWECRK.js.map +1 -0
- package/dist/chunk-MA7QG54W.js +74 -0
- package/dist/chunk-MA7QG54W.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +33 -0
- package/dist/cli.js.map +1 -0
- package/dist/deploy-SCEMUQNS.js +141 -0
- package/dist/deploy-SCEMUQNS.js.map +1 -0
- package/dist/index.js +11 -11
- package/dist/index.js.map +1 -1
- package/dist/login-NKDRQXRE.js +71 -0
- package/dist/login-NKDRQXRE.js.map +1 -0
- package/dist/logout-H543QEKU.js +20 -0
- package/dist/logout-H543QEKU.js.map +1 -0
- package/dist/logs-YDAUCMAV.js +71 -0
- package/dist/logs-YDAUCMAV.js.map +1 -0
- package/dist/projects-3TAY7EDJ.js +42 -0
- package/dist/projects-3TAY7EDJ.js.map +1 -0
- package/package.json +7 -3
- package/templates/book-docs/docs/v1.0.0/concepts.mdx +89 -0
- package/templates/book-docs/docs/v1.0.0/content/_category_.json +7 -0
- package/templates/book-docs/docs/v1.0.0/content/formatting.mdx +128 -0
- package/templates/book-docs/docs/v1.0.0/content/reusable-content.mdx +116 -0
- package/templates/book-docs/docs/v1.0.0/content/structure.mdx +92 -0
- package/templates/book-docs/docs/v1.0.0/customization/_category_.json +7 -0
- package/templates/book-docs/docs/v1.0.0/customization/branding.mdx +115 -0
- package/templates/book-docs/docs/v1.0.0/customization/themes.mdx +81 -0
- package/templates/book-docs/docs/v1.0.0/introduction.mdx +38 -0
- package/templates/book-docs/docs/v1.0.0/quickstart.mdx +112 -0
- package/templates/book-docs/docs/v2.0.0/concepts.mdx +89 -0
- package/templates/book-docs/docs/v2.0.0/content/_category_.json +7 -0
- package/templates/book-docs/docs/v2.0.0/content/formatting.mdx +128 -0
- package/templates/book-docs/docs/v2.0.0/content/reusable-content.mdx +116 -0
- package/templates/book-docs/docs/v2.0.0/content/structure.mdx +92 -0
- package/templates/book-docs/docs/v2.0.0/customization/_category_.json +7 -0
- package/templates/book-docs/docs/v2.0.0/customization/branding.mdx +115 -0
- package/templates/book-docs/docs/v2.0.0/customization/themes.mdx +81 -0
- package/templates/book-docs/docs/v2.0.0/introduction.mdx +39 -0
- package/templates/book-docs/docs/v2.0.0/quickstart.mdx +112 -0
- package/templates/book-docs/gitignore +7 -0
- package/templates/book-docs/package.json +28 -0
- package/templates/book-docs/postcss.config.mjs +8 -0
- package/templates/book-docs/public/api-specs/openapi-example.json +259 -0
- package/templates/book-docs/public/api-specs/postman-example.json +205 -0
- package/templates/book-docs/public/api-specs/test-api.json +256 -0
- package/templates/book-docs/public/api-specs/users-api.json +264 -0
- package/templates/book-docs/specra.config.json +77 -0
- package/templates/book-docs/src/app.css +2 -0
- package/templates/book-docs/src/app.html +12 -0
- package/templates/book-docs/src/routes/+layout.server.ts +11 -0
- package/templates/book-docs/src/routes/+layout.svelte +21 -0
- package/templates/book-docs/src/routes/+page.server.ts +9 -0
- package/templates/book-docs/src/routes/docs/[version]/[...slug]/+page.server.ts +119 -0
- package/templates/book-docs/src/routes/docs/[version]/[...slug]/+page.svelte +129 -0
- package/templates/book-docs/svelte.config.js +8 -0
- package/templates/book-docs/tsconfig.json +12 -0
- package/templates/book-docs/vite.config.ts +6 -0
- package/templates/jbrains-docs/docs/v1.0.0/advanced/_category_.json +8 -0
- package/templates/jbrains-docs/docs/v1.0.0/advanced/async.mdx +95 -0
- package/templates/jbrains-docs/docs/v1.0.0/advanced/generics.mdx +126 -0
- package/templates/jbrains-docs/docs/v1.0.0/basics/_category_.json +8 -0
- package/templates/jbrains-docs/docs/v1.0.0/basics/control-flow.mdx +106 -0
- package/templates/jbrains-docs/docs/v1.0.0/basics/syntax.mdx +129 -0
- package/templates/jbrains-docs/docs/v1.0.0/basics/types.mdx +135 -0
- package/templates/jbrains-docs/docs/v1.0.0/getting-started.mdx +111 -0
- package/templates/jbrains-docs/docs/v1.0.0/home.mdx +37 -0
- package/templates/jbrains-docs/docs/v1.0.0/tools/_category_.json +8 -0
- package/templates/jbrains-docs/docs/v1.0.0/tools/build-tools.mdx +165 -0
- package/templates/jbrains-docs/docs/v1.0.0/tools/testing.mdx +112 -0
- package/templates/jbrains-docs/docs/v2.0.0/advanced/_category_.json +8 -0
- package/templates/jbrains-docs/docs/v2.0.0/advanced/async.mdx +95 -0
- package/templates/jbrains-docs/docs/v2.0.0/advanced/generics.mdx +126 -0
- package/templates/jbrains-docs/docs/v2.0.0/basics/_category_.json +8 -0
- package/templates/jbrains-docs/docs/v2.0.0/basics/control-flow.mdx +106 -0
- package/templates/jbrains-docs/docs/v2.0.0/basics/syntax.mdx +129 -0
- package/templates/jbrains-docs/docs/v2.0.0/basics/types.mdx +135 -0
- package/templates/jbrains-docs/docs/v2.0.0/getting-started.mdx +111 -0
- package/templates/jbrains-docs/docs/v2.0.0/home.mdx +37 -0
- package/templates/jbrains-docs/docs/v2.0.0/tools/_category_.json +8 -0
- package/templates/jbrains-docs/docs/v2.0.0/tools/build-tools.mdx +165 -0
- package/templates/jbrains-docs/docs/v2.0.0/tools/testing.mdx +112 -0
- package/templates/jbrains-docs/gitignore +7 -0
- package/templates/jbrains-docs/package.json +28 -0
- package/templates/jbrains-docs/postcss.config.mjs +8 -0
- package/templates/jbrains-docs/public/api-specs/openapi-example.json +259 -0
- package/templates/jbrains-docs/public/api-specs/postman-example.json +205 -0
- package/templates/jbrains-docs/public/api-specs/test-api.json +256 -0
- package/templates/jbrains-docs/public/api-specs/users-api.json +264 -0
- package/templates/jbrains-docs/specra.config.json +80 -0
- package/templates/jbrains-docs/src/app.css +2 -0
- package/templates/jbrains-docs/src/app.html +12 -0
- package/templates/jbrains-docs/src/routes/+layout.server.ts +11 -0
- package/templates/jbrains-docs/src/routes/+layout.svelte +21 -0
- package/templates/jbrains-docs/src/routes/+page.server.ts +9 -0
- package/templates/jbrains-docs/src/routes/docs/[version]/[...slug]/+page.server.ts +119 -0
- package/templates/jbrains-docs/src/routes/docs/[version]/[...slug]/+page.svelte +129 -0
- package/templates/jbrains-docs/svelte.config.js +8 -0
- package/templates/jbrains-docs/tsconfig.json +12 -0
- package/templates/jbrains-docs/vite.config.ts +6 -0
- package/templates/minimal/docs/v1.0.0/about.mdx +3 -3
- package/templates/minimal/docs/v2.0.0/about.mdx +3 -3
- package/templates/minimal/gitignore +7 -0
- package/templates/minimal/package.json +18 -24
- package/templates/minimal/specra.config.json +12 -63
- package/templates/minimal/src/app.css +2 -0
- package/templates/minimal/src/app.html +12 -0
- package/templates/minimal/src/routes/+layout.server.ts +11 -0
- package/templates/minimal/src/routes/+layout.svelte +21 -0
- package/templates/minimal/src/routes/+page.server.ts +9 -0
- package/templates/minimal/src/routes/docs/[version]/[...slug]/+page.server.ts +119 -0
- package/templates/minimal/src/routes/docs/[version]/[...slug]/+page.svelte +129 -0
- package/templates/minimal/svelte.config.js +8 -0
- package/templates/minimal/tsconfig.json +7 -36
- package/templates/minimal/vite.config.ts +6 -0
- package/templates/minimal/README.md +0 -132
- package/templates/minimal/app/api/mdx-watch/route.ts +0 -6
- package/templates/minimal/app/api/search/route.ts +0 -75
- package/templates/minimal/app/docs/[version]/[...slug]/loading.tsx +0 -7
- package/templates/minimal/app/docs/[version]/[...slug]/page.tsx +0 -205
- package/templates/minimal/app/docs/[version]/[...slug]/page.tsx.bak +0 -203
- package/templates/minimal/app/docs/[version]/not-found.tsx +0 -10
- package/templates/minimal/app/docs/[version]/page.tsx +0 -27
- package/templates/minimal/app/globals.css +0 -9
- package/templates/minimal/app/layout.tsx +0 -62
- package/templates/minimal/app/not-found.tsx +0 -10
- package/templates/minimal/app/page.tsx +0 -179
- package/templates/minimal/next.config.mjs +0 -1
- package/templates/minimal/package-lock.json +0 -7881
- package/templates/minimal/proxy_.ts +0 -22
- package/templates/minimal/scripts/generate-redirects.mjs +0 -128
- package/templates/minimal/scripts/generate-static-redirects.mjs +0 -115
- package/templates/minimal/scripts/index-search.ts +0 -182
- package/templates/minimal/scripts/test-search.ts +0 -83
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.0",
|
|
3
|
+
"title": "Users API",
|
|
4
|
+
"description": "Complete API reference for managing users in the system",
|
|
5
|
+
"baseUrl": "https://api.example.com/v1",
|
|
6
|
+
"env": {
|
|
7
|
+
"AUTH_TOKEN": "your_api_token_here"
|
|
8
|
+
},
|
|
9
|
+
"auth": {
|
|
10
|
+
"type": "bearer",
|
|
11
|
+
"description": "All requests require a valid API token in the Authorization header",
|
|
12
|
+
"tokenPrefix": "Bearer"
|
|
13
|
+
},
|
|
14
|
+
"globalHeaders": [
|
|
15
|
+
{
|
|
16
|
+
"name": "Authorization",
|
|
17
|
+
"value": "Bearer {AUTH_TOKEN}",
|
|
18
|
+
"description": "Your API authentication token"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "Content-Type",
|
|
22
|
+
"value": "application/json"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"endpoints": [
|
|
26
|
+
{
|
|
27
|
+
"title": "Get User by ID",
|
|
28
|
+
"method": "GET",
|
|
29
|
+
"path": "/users/:id",
|
|
30
|
+
"description": "Retrieve detailed information about a specific user",
|
|
31
|
+
"pathParams": [
|
|
32
|
+
{
|
|
33
|
+
"name": "id",
|
|
34
|
+
"type": "string",
|
|
35
|
+
"required": true,
|
|
36
|
+
"description": "The unique identifier of the user",
|
|
37
|
+
"example": "user_123"
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"queryParams": [
|
|
41
|
+
{
|
|
42
|
+
"name": "fields",
|
|
43
|
+
"type": "string",
|
|
44
|
+
"description": "Comma-separated list of fields to include",
|
|
45
|
+
"example": "name,email,created_at"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "include_metadata",
|
|
49
|
+
"type": "boolean",
|
|
50
|
+
"description": "Include additional metadata in the response",
|
|
51
|
+
"default": false
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"successResponse": {
|
|
55
|
+
"status": 200,
|
|
56
|
+
"description": "User retrieved successfully",
|
|
57
|
+
"example": {
|
|
58
|
+
"id": "user_123",
|
|
59
|
+
"name": "John Doe",
|
|
60
|
+
"email": "john@example.com",
|
|
61
|
+
"role": "admin",
|
|
62
|
+
"created_at": "2024-01-15T10:30:00Z",
|
|
63
|
+
"updated_at": "2024-01-20T14:22:00Z"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"errorResponses": [
|
|
67
|
+
{
|
|
68
|
+
"status": 404,
|
|
69
|
+
"description": "User not found",
|
|
70
|
+
"example": {
|
|
71
|
+
"error": "User not found",
|
|
72
|
+
"code": "USER_NOT_FOUND",
|
|
73
|
+
"message": "No user exists with the provided ID"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"status": 401,
|
|
78
|
+
"description": "Unauthorized",
|
|
79
|
+
"example": {
|
|
80
|
+
"error": "Unauthorized",
|
|
81
|
+
"code": "UNAUTHORIZED",
|
|
82
|
+
"message": "Invalid or missing authentication token"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
"examples": [
|
|
87
|
+
{
|
|
88
|
+
"title": "cURL",
|
|
89
|
+
"language": "bash",
|
|
90
|
+
"code": "curl -X GET \"https://api.example.com/v1/users/user_123\" \\\n -H \"Authorization: Bearer your_api_token_here\""
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"title": "JavaScript (fetch)",
|
|
94
|
+
"language": "javascript",
|
|
95
|
+
"code": "const response = await fetch('https://api.example.com/v1/users/user_123', {\n headers: {\n 'Authorization': 'Bearer your_api_token_here'\n }\n});\nconst user = await response.json();"
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"title": "List All Users",
|
|
101
|
+
"method": "GET",
|
|
102
|
+
"path": "/users",
|
|
103
|
+
"description": "Retrieve a paginated list of all users",
|
|
104
|
+
"queryParams": [
|
|
105
|
+
{
|
|
106
|
+
"name": "page",
|
|
107
|
+
"type": "number",
|
|
108
|
+
"description": "Page number for pagination",
|
|
109
|
+
"default": 1
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"name": "limit",
|
|
113
|
+
"type": "number",
|
|
114
|
+
"description": "Number of users per page",
|
|
115
|
+
"default": 20
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"name": "role",
|
|
119
|
+
"type": "string",
|
|
120
|
+
"description": "Filter users by role",
|
|
121
|
+
"example": "admin"
|
|
122
|
+
}
|
|
123
|
+
],
|
|
124
|
+
"successResponse": {
|
|
125
|
+
"status": 200,
|
|
126
|
+
"description": "List of users retrieved successfully",
|
|
127
|
+
"example": {
|
|
128
|
+
"data": [
|
|
129
|
+
{
|
|
130
|
+
"id": "user_123",
|
|
131
|
+
"name": "John Doe",
|
|
132
|
+
"email": "john@example.com",
|
|
133
|
+
"role": "admin"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"id": "user_124",
|
|
137
|
+
"name": "Jane Smith",
|
|
138
|
+
"email": "jane@example.com",
|
|
139
|
+
"role": "user"
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
"pagination": {
|
|
143
|
+
"page": 1,
|
|
144
|
+
"limit": 20,
|
|
145
|
+
"total": 42,
|
|
146
|
+
"pages": 3
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"title": "Create New User",
|
|
153
|
+
"method": "POST",
|
|
154
|
+
"path": "/users",
|
|
155
|
+
"description": "Create a new user account",
|
|
156
|
+
"body": {
|
|
157
|
+
"description": "User data to create",
|
|
158
|
+
"example": {
|
|
159
|
+
"name": "Alice Johnson",
|
|
160
|
+
"email": "alice@example.com",
|
|
161
|
+
"role": "user",
|
|
162
|
+
"password": "secure_password_123"
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
"successResponse": {
|
|
166
|
+
"status": 201,
|
|
167
|
+
"description": "User created successfully",
|
|
168
|
+
"example": {
|
|
169
|
+
"id": "user_125",
|
|
170
|
+
"name": "Alice Johnson",
|
|
171
|
+
"email": "alice@example.com",
|
|
172
|
+
"role": "user",
|
|
173
|
+
"created_at": "2024-01-21T09:15:00Z"
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
"errorResponses": [
|
|
177
|
+
{
|
|
178
|
+
"status": 400,
|
|
179
|
+
"description": "Validation error",
|
|
180
|
+
"example": {
|
|
181
|
+
"error": "Validation failed",
|
|
182
|
+
"code": "VALIDATION_ERROR",
|
|
183
|
+
"details": {
|
|
184
|
+
"email": "Email address already exists"
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
],
|
|
189
|
+
"examples": [
|
|
190
|
+
{
|
|
191
|
+
"title": "cURL",
|
|
192
|
+
"language": "bash",
|
|
193
|
+
"code": "curl -X POST \"https://api.example.com/v1/users\" \\\n -H \"Authorization: Bearer your_api_token_here\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"Alice Johnson\",\n \"email\": \"alice@example.com\",\n \"role\": \"user\",\n \"password\": \"secure_password_123\"\n }'"
|
|
194
|
+
}
|
|
195
|
+
]
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"title": "Update User",
|
|
199
|
+
"method": "PATCH",
|
|
200
|
+
"path": "/users/:id",
|
|
201
|
+
"description": "Update user information",
|
|
202
|
+
"pathParams": [
|
|
203
|
+
{
|
|
204
|
+
"name": "id",
|
|
205
|
+
"type": "string",
|
|
206
|
+
"required": true,
|
|
207
|
+
"description": "User ID to update"
|
|
208
|
+
}
|
|
209
|
+
],
|
|
210
|
+
"body": {
|
|
211
|
+
"description": "Fields to update (all optional)",
|
|
212
|
+
"example": {
|
|
213
|
+
"name": "John Updated",
|
|
214
|
+
"email": "john.updated@example.com",
|
|
215
|
+
"role": "moderator"
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
"successResponse": {
|
|
219
|
+
"status": 200,
|
|
220
|
+
"description": "User updated successfully",
|
|
221
|
+
"example": {
|
|
222
|
+
"id": "user_123",
|
|
223
|
+
"name": "John Updated",
|
|
224
|
+
"email": "john.updated@example.com",
|
|
225
|
+
"role": "moderator",
|
|
226
|
+
"updated_at": "2024-01-21T10:00:00Z"
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"title": "Delete User",
|
|
232
|
+
"method": "DELETE",
|
|
233
|
+
"path": "/users/:id",
|
|
234
|
+
"description": "Permanently delete a user account",
|
|
235
|
+
"pathParams": [
|
|
236
|
+
{
|
|
237
|
+
"name": "id",
|
|
238
|
+
"type": "string",
|
|
239
|
+
"required": true,
|
|
240
|
+
"description": "User ID to delete"
|
|
241
|
+
}
|
|
242
|
+
],
|
|
243
|
+
"successResponse": {
|
|
244
|
+
"status": 204,
|
|
245
|
+
"description": "User deleted successfully"
|
|
246
|
+
},
|
|
247
|
+
"errorResponses": [
|
|
248
|
+
{
|
|
249
|
+
"status": 404,
|
|
250
|
+
"description": "User not found"
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"status": 403,
|
|
254
|
+
"description": "Forbidden - Cannot delete this user",
|
|
255
|
+
"example": {
|
|
256
|
+
"error": "Forbidden",
|
|
257
|
+
"code": "CANNOT_DELETE_ADMIN",
|
|
258
|
+
"message": "Cannot delete the primary admin account"
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
}
|
|
263
|
+
]
|
|
264
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./node_modules/specra/config/specra.config.schema.json",
|
|
3
|
+
"site": {
|
|
4
|
+
"title": "My Docs",
|
|
5
|
+
"description": "Documentation for my project",
|
|
6
|
+
"url": "http://localhost:5173",
|
|
7
|
+
"baseUrl": "/",
|
|
8
|
+
"language": "en",
|
|
9
|
+
"organizationName": "my-org",
|
|
10
|
+
"projectName": "my-project",
|
|
11
|
+
"activeVersion": "v1.0.0"
|
|
12
|
+
},
|
|
13
|
+
"theme": {
|
|
14
|
+
"defaultMode": "light",
|
|
15
|
+
"respectPrefersColorScheme": true
|
|
16
|
+
},
|
|
17
|
+
"navigation": {
|
|
18
|
+
"showSidebar": true,
|
|
19
|
+
"collapsibleSidebar": true,
|
|
20
|
+
"sidebarStyle": "flush",
|
|
21
|
+
"showBreadcrumbs": true,
|
|
22
|
+
"showTableOfContents": false,
|
|
23
|
+
"tocPosition": "right",
|
|
24
|
+
"tocMaxDepth": 3,
|
|
25
|
+
"tabGroups": [
|
|
26
|
+
{
|
|
27
|
+
"id": "language",
|
|
28
|
+
"label": "Language"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "multiplatform",
|
|
32
|
+
"label": "Multiplatform"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
"social": {
|
|
37
|
+
"github": "https://github.com/your-org/your-repo"
|
|
38
|
+
},
|
|
39
|
+
"search": {
|
|
40
|
+
"enabled": false
|
|
41
|
+
},
|
|
42
|
+
"banner": {
|
|
43
|
+
"enabled": true,
|
|
44
|
+
"message": "Docs v2.0.0 is now available!",
|
|
45
|
+
"type": "info",
|
|
46
|
+
"dismissible": true
|
|
47
|
+
},
|
|
48
|
+
"footer": {
|
|
49
|
+
"copyright": "Copyright © 2025 My Project. All rights reserved.",
|
|
50
|
+
"links": [
|
|
51
|
+
{
|
|
52
|
+
"title": "Documentation",
|
|
53
|
+
"items": [
|
|
54
|
+
{
|
|
55
|
+
"label": "Getting Started",
|
|
56
|
+
"href": "/docs/v1.0.0/getting-started"
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"title": "Community",
|
|
62
|
+
"items": [
|
|
63
|
+
{
|
|
64
|
+
"label": "GitHub",
|
|
65
|
+
"href": "https://github.com/your-org/your-repo"
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
"features": {
|
|
72
|
+
"showLastUpdated": true,
|
|
73
|
+
"showReadingTime": false,
|
|
74
|
+
"showAuthors": false,
|
|
75
|
+
"showTags": true,
|
|
76
|
+
"versioning": true,
|
|
77
|
+
"showVersionBadge": true,
|
|
78
|
+
"i18n": false
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<link rel="icon" href="%sveltekit.assets%/favicon.svg" type="image/svg+xml" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
+
%sveltekit.head%
|
|
8
|
+
</head>
|
|
9
|
+
<body data-sveltekit-preload-data="hover" class="font-sans antialiased">
|
|
10
|
+
<div style="display: contents">%sveltekit.body%</div>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getConfig, initConfig } from 'specra';
|
|
2
|
+
import specraConfig from '../../specra.config.json';
|
|
3
|
+
import type { LayoutServerLoad } from './$types';
|
|
4
|
+
import type { SpecraConfig } from 'specra';
|
|
5
|
+
|
|
6
|
+
initConfig(specraConfig as unknown as Partial<SpecraConfig>);
|
|
7
|
+
|
|
8
|
+
export const load: LayoutServerLoad = async () => {
|
|
9
|
+
const config = getConfig();
|
|
10
|
+
return { config };
|
|
11
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import '../app.css';
|
|
3
|
+
import { LayoutProviders } from 'specra/components';
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
import type { LayoutData } from './$types';
|
|
6
|
+
|
|
7
|
+
let { data, children }: { data: LayoutData; children: Snippet } = $props();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<svelte:head>
|
|
11
|
+
<title>{data?.config?.site?.title || 'Documentation'}</title>
|
|
12
|
+
<meta name="description" content={data?.config?.site?.description || 'Modern documentation platform'} />
|
|
13
|
+
</svelte:head>
|
|
14
|
+
|
|
15
|
+
{#if data?.config}
|
|
16
|
+
<LayoutProviders config={data.config}>
|
|
17
|
+
{@render children?.()}
|
|
18
|
+
</LayoutProviders>
|
|
19
|
+
{:else}
|
|
20
|
+
{@render children?.()}
|
|
21
|
+
{/if}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { redirect } from '@sveltejs/kit';
|
|
2
|
+
import { getConfig } from 'specra';
|
|
3
|
+
import type { PageServerLoad } from './$types';
|
|
4
|
+
|
|
5
|
+
export const load: PageServerLoad = async () => {
|
|
6
|
+
const config = getConfig();
|
|
7
|
+
const activeVersion = config.site?.activeVersion || 'v1.0.0';
|
|
8
|
+
redirect(302, `/docs/${activeVersion}/home`);
|
|
9
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import {
|
|
2
|
+
extractTableOfContents,
|
|
3
|
+
getAdjacentDocs,
|
|
4
|
+
isCategoryPage,
|
|
5
|
+
getCachedVersions,
|
|
6
|
+
getCachedAllDocs,
|
|
7
|
+
getCachedDocBySlug,
|
|
8
|
+
getI18nConfig,
|
|
9
|
+
getConfig,
|
|
10
|
+
} from 'specra';
|
|
11
|
+
import type { PageServerLoad } from './$types';
|
|
12
|
+
|
|
13
|
+
export const load: PageServerLoad = async ({ params }) => {
|
|
14
|
+
const { version, slug: slugArray } = params;
|
|
15
|
+
const slug = slugArray;
|
|
16
|
+
|
|
17
|
+
const i18nConfig = getI18nConfig();
|
|
18
|
+
const slugParts = slug.split('/');
|
|
19
|
+
let locale: string | undefined;
|
|
20
|
+
if (i18nConfig && i18nConfig.locales.includes(slugParts[0])) {
|
|
21
|
+
locale = slugParts[0];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const allDocs = await getCachedAllDocs(version, locale);
|
|
25
|
+
const versions = getCachedVersions();
|
|
26
|
+
const config = getConfig();
|
|
27
|
+
const isCategory = isCategoryPage(slug, allDocs);
|
|
28
|
+
const doc = await getCachedDocBySlug(slug, version);
|
|
29
|
+
|
|
30
|
+
let title = 'Page Not Found';
|
|
31
|
+
let description = 'The requested documentation page could not be found.';
|
|
32
|
+
let ogUrl = `/docs/${version}/${slug}`;
|
|
33
|
+
|
|
34
|
+
if (doc) {
|
|
35
|
+
title = doc.meta.title || doc.title;
|
|
36
|
+
description = doc.meta.description || `Documentation for ${title}`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Category page without doc content
|
|
40
|
+
if (!doc && isCategory) {
|
|
41
|
+
const categoryDoc = allDocs.find((d) => d.slug.startsWith(slug + '/'));
|
|
42
|
+
const categoryTabGroup = categoryDoc?.meta?.tab_group || categoryDoc?.categoryTabGroup;
|
|
43
|
+
const categoryTitle = slug
|
|
44
|
+
.split('/')
|
|
45
|
+
.pop()
|
|
46
|
+
?.replace(/-/g, ' ')
|
|
47
|
+
.replace(/\b\w/g, (l) => l.toUpperCase()) || 'Category';
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
version,
|
|
51
|
+
slug,
|
|
52
|
+
allDocs,
|
|
53
|
+
versions,
|
|
54
|
+
config,
|
|
55
|
+
isCategory: true,
|
|
56
|
+
isNotFound: false,
|
|
57
|
+
doc: null,
|
|
58
|
+
categoryTitle,
|
|
59
|
+
categoryDescription: 'Browse the documentation in this section.',
|
|
60
|
+
categoryTabGroup,
|
|
61
|
+
toc: [],
|
|
62
|
+
previous: null,
|
|
63
|
+
next: null,
|
|
64
|
+
title,
|
|
65
|
+
description,
|
|
66
|
+
ogUrl,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Not found
|
|
71
|
+
if (!doc) {
|
|
72
|
+
return {
|
|
73
|
+
version,
|
|
74
|
+
slug,
|
|
75
|
+
allDocs,
|
|
76
|
+
versions,
|
|
77
|
+
config,
|
|
78
|
+
isCategory: false,
|
|
79
|
+
isNotFound: true,
|
|
80
|
+
doc: null,
|
|
81
|
+
categoryTitle: null,
|
|
82
|
+
categoryDescription: null,
|
|
83
|
+
categoryTabGroup: undefined,
|
|
84
|
+
toc: [],
|
|
85
|
+
previous: null,
|
|
86
|
+
next: null,
|
|
87
|
+
title,
|
|
88
|
+
description,
|
|
89
|
+
ogUrl,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Normal doc page
|
|
94
|
+
const toc = extractTableOfContents(doc.meta.content || doc.content);
|
|
95
|
+
const { previous, next } = getAdjacentDocs(slug, allDocs);
|
|
96
|
+
const showCategoryIndex = isCategory && !!doc;
|
|
97
|
+
const matchingDoc = allDocs.find((d) => d.slug === slug);
|
|
98
|
+
const currentPageTabGroup = doc.meta?.tab_group || matchingDoc?.categoryTabGroup;
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
version,
|
|
102
|
+
slug,
|
|
103
|
+
allDocs,
|
|
104
|
+
versions,
|
|
105
|
+
config,
|
|
106
|
+
isCategory: showCategoryIndex,
|
|
107
|
+
isNotFound: false,
|
|
108
|
+
doc,
|
|
109
|
+
categoryTitle: null,
|
|
110
|
+
categoryDescription: null,
|
|
111
|
+
categoryTabGroup: currentPageTabGroup,
|
|
112
|
+
toc,
|
|
113
|
+
previous: previous ? { title: previous.meta.title, slug: previous.slug } : null,
|
|
114
|
+
next: next ? { title: next.meta.title, slug: next.slug } : null,
|
|
115
|
+
title,
|
|
116
|
+
description,
|
|
117
|
+
ogUrl,
|
|
118
|
+
};
|
|
119
|
+
};
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
TableOfContents,
|
|
4
|
+
Header,
|
|
5
|
+
DocLayout,
|
|
6
|
+
CategoryIndex,
|
|
7
|
+
HotReloadIndicator,
|
|
8
|
+
DevModeBadge,
|
|
9
|
+
MdxHotReload,
|
|
10
|
+
MdxContent,
|
|
11
|
+
NotFoundContent,
|
|
12
|
+
SearchHighlight,
|
|
13
|
+
MobileDocLayout,
|
|
14
|
+
mdxComponents,
|
|
15
|
+
} from 'specra/components';
|
|
16
|
+
import type { PageData } from './$types';
|
|
17
|
+
|
|
18
|
+
let { data }: { data: PageData } = $props();
|
|
19
|
+
|
|
20
|
+
let allDocsCompat: any[] = $derived(data.allDocs);
|
|
21
|
+
let previousDoc = $derived(data.previous ?? undefined);
|
|
22
|
+
let nextDoc = $derived(data.next ?? undefined);
|
|
23
|
+
let categoryTitle = $derived(data.categoryTitle ?? undefined);
|
|
24
|
+
let categoryDescription = $derived(data.categoryDescription ?? undefined);
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<svelte:head>
|
|
28
|
+
<title>{data.title}</title>
|
|
29
|
+
<meta name="description" content={data.description} />
|
|
30
|
+
<meta property="og:title" content={data.title} />
|
|
31
|
+
<meta property="og:description" content={data.description} />
|
|
32
|
+
<meta property="og:url" content={data.ogUrl} />
|
|
33
|
+
<meta property="og:type" content="article" />
|
|
34
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
35
|
+
<meta name="twitter:title" content={data.title} />
|
|
36
|
+
<meta name="twitter:description" content={data.description} />
|
|
37
|
+
</svelte:head>
|
|
38
|
+
|
|
39
|
+
{#if !data.doc && data.isCategory}
|
|
40
|
+
<MobileDocLayout
|
|
41
|
+
docs={allDocsCompat}
|
|
42
|
+
version={data.version}
|
|
43
|
+
config={data.config}
|
|
44
|
+
activeTabGroup={data.categoryTabGroup}
|
|
45
|
+
>
|
|
46
|
+
{#snippet header()}
|
|
47
|
+
<Header currentVersion={data.version} versions={data.versions} config={data.config} />
|
|
48
|
+
{/snippet}
|
|
49
|
+
<CategoryIndex
|
|
50
|
+
categoryPath={data.slug}
|
|
51
|
+
version={data.version}
|
|
52
|
+
allDocs={allDocsCompat}
|
|
53
|
+
title={categoryTitle}
|
|
54
|
+
description={categoryDescription}
|
|
55
|
+
config={data.config}
|
|
56
|
+
/>
|
|
57
|
+
</MobileDocLayout>
|
|
58
|
+
<MdxHotReload />
|
|
59
|
+
<HotReloadIndicator />
|
|
60
|
+
<DevModeBadge />
|
|
61
|
+
{:else if data.isNotFound}
|
|
62
|
+
<MobileDocLayout
|
|
63
|
+
docs={allDocsCompat}
|
|
64
|
+
version={data.version}
|
|
65
|
+
config={data.config}
|
|
66
|
+
>
|
|
67
|
+
{#snippet header()}
|
|
68
|
+
<Header currentVersion={data.version} versions={data.versions} config={data.config} />
|
|
69
|
+
{/snippet}
|
|
70
|
+
<NotFoundContent version={data.version} />
|
|
71
|
+
</MobileDocLayout>
|
|
72
|
+
<MdxHotReload />
|
|
73
|
+
<HotReloadIndicator />
|
|
74
|
+
<DevModeBadge />
|
|
75
|
+
{:else if data.doc}
|
|
76
|
+
<MobileDocLayout
|
|
77
|
+
docs={allDocsCompat}
|
|
78
|
+
version={data.version}
|
|
79
|
+
config={data.config}
|
|
80
|
+
activeTabGroup={data.categoryTabGroup}
|
|
81
|
+
>
|
|
82
|
+
{#snippet header()}
|
|
83
|
+
<Header currentVersion={data.version} versions={data.versions} config={data.config} />
|
|
84
|
+
{/snippet}
|
|
85
|
+
{#snippet toc()}
|
|
86
|
+
{#if !data.isCategory}
|
|
87
|
+
<TableOfContents items={data.toc} config={data.config} />
|
|
88
|
+
{/if}
|
|
89
|
+
{/snippet}
|
|
90
|
+
|
|
91
|
+
{#if data.isCategory}
|
|
92
|
+
{#snippet categoryContent()}
|
|
93
|
+
{#if data.doc?.contentNodes}
|
|
94
|
+
<MdxContent nodes={data.doc.contentNodes} components={mdxComponents} />
|
|
95
|
+
{:else if data.doc?.content}
|
|
96
|
+
{@html data.doc.content}
|
|
97
|
+
{/if}
|
|
98
|
+
{/snippet}
|
|
99
|
+
<CategoryIndex
|
|
100
|
+
categoryPath={data.slug}
|
|
101
|
+
version={data.version}
|
|
102
|
+
allDocs={allDocsCompat}
|
|
103
|
+
title={data.doc.meta.title}
|
|
104
|
+
description={data.doc.meta.description}
|
|
105
|
+
content={categoryContent}
|
|
106
|
+
config={data.config}
|
|
107
|
+
/>
|
|
108
|
+
{:else}
|
|
109
|
+
<SearchHighlight />
|
|
110
|
+
<DocLayout
|
|
111
|
+
meta={data.doc.meta}
|
|
112
|
+
previousDoc={previousDoc}
|
|
113
|
+
nextDoc={nextDoc}
|
|
114
|
+
version={data.version}
|
|
115
|
+
slug={data.slug}
|
|
116
|
+
config={data.config}
|
|
117
|
+
>
|
|
118
|
+
{#if data.doc.contentNodes}
|
|
119
|
+
<MdxContent nodes={data.doc.contentNodes} components={mdxComponents} />
|
|
120
|
+
{:else}
|
|
121
|
+
{@html data.doc.content}
|
|
122
|
+
{/if}
|
|
123
|
+
</DocLayout>
|
|
124
|
+
{/if}
|
|
125
|
+
</MobileDocLayout>
|
|
126
|
+
<MdxHotReload />
|
|
127
|
+
<HotReloadIndicator />
|
|
128
|
+
<DevModeBadge />
|
|
129
|
+
{/if}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./.svelte-kit/tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"allowJs": true,
|
|
5
|
+
"checkJs": true,
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"forceConsistentCasingInFileNames": true,
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"strict": true
|
|
11
|
+
}
|
|
12
|
+
}
|