@tanstack/cta-framework-solid 0.28.0 → 0.29.1
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/ADD-ON-AUTHORING.md +211 -1
- package/package.json +2 -2
package/ADD-ON-AUTHORING.md
CHANGED
|
@@ -79,7 +79,7 @@ The code is integrated into these locations with these application architectures
|
|
|
79
79
|
Code in `assets/src/components/my-provider.tsx`:
|
|
80
80
|
|
|
81
81
|
```ts
|
|
82
|
-
export default function MyProvider({ children }: { children:
|
|
82
|
+
export default function MyProvider({ children }: { children: JSX.Element }) {
|
|
83
83
|
return <SomeKindOfProvider>{children}</SomeKindOfProvider>
|
|
84
84
|
}
|
|
85
85
|
```
|
|
@@ -153,3 +153,213 @@ If you don't want a header link you can omit the `url` and `name` properties.
|
|
|
153
153
|
You **MUST** specify routes in the `info.json` file if your add-on supports the `code-router` mode. This is because the `code-routers` setup needs to import the routes in order to add them to the router.
|
|
154
154
|
|
|
155
155
|
By convension you should prefix demo routes with `demo` to make it clear that they are demo routes so they can be easily identified and removed.
|
|
156
|
+
|
|
157
|
+
# Add-on Options
|
|
158
|
+
|
|
159
|
+
The CTA framework supports configurable add-ons through an options system that allows users to customize add-on behavior during creation. This enables more flexible and reusable add-ons that can adapt to different use cases.
|
|
160
|
+
|
|
161
|
+
## Overview
|
|
162
|
+
|
|
163
|
+
Add-on options allow developers to create configurable add-ons where users can select from predefined choices that affect:
|
|
164
|
+
|
|
165
|
+
- Which files are included in the generated project
|
|
166
|
+
- Template variable values used during file generation
|
|
167
|
+
- Package dependencies that get installed
|
|
168
|
+
- Configuration file contents
|
|
169
|
+
|
|
170
|
+
## Configuration Format
|
|
171
|
+
|
|
172
|
+
Options are defined in the `info.json` file using the following schema:
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
{
|
|
176
|
+
"name": "My Add-on",
|
|
177
|
+
"description": "A configurable add-on",
|
|
178
|
+
"options": {
|
|
179
|
+
"optionName": {
|
|
180
|
+
"type": "select",
|
|
181
|
+
"label": "Display Label",
|
|
182
|
+
"description": "Optional description shown to users",
|
|
183
|
+
"default": "defaultValue",
|
|
184
|
+
"options": [
|
|
185
|
+
{ "value": "option1", "label": "Option 1" },
|
|
186
|
+
{ "value": "option2", "label": "Option 2" }
|
|
187
|
+
]
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Option Types
|
|
194
|
+
|
|
195
|
+
#### Select Options
|
|
196
|
+
|
|
197
|
+
The `select` type allows users to choose from a predefined list of options:
|
|
198
|
+
|
|
199
|
+
```json
|
|
200
|
+
"database": {
|
|
201
|
+
"type": "select",
|
|
202
|
+
"label": "Database Provider",
|
|
203
|
+
"description": "Choose your database provider",
|
|
204
|
+
"default": "postgres",
|
|
205
|
+
"options": [
|
|
206
|
+
{ "value": "postgres", "label": "PostgreSQL" },
|
|
207
|
+
{ "value": "mysql", "label": "MySQL" },
|
|
208
|
+
{ "value": "sqlite", "label": "SQLite" }
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Properties:**
|
|
214
|
+
|
|
215
|
+
- `type`: Must be `"select"`
|
|
216
|
+
- `label`: Display text shown to users
|
|
217
|
+
- `description`: Optional help text
|
|
218
|
+
- `default`: Default value that must match one of the option values
|
|
219
|
+
- `options`: Array of value/label pairs
|
|
220
|
+
|
|
221
|
+
## Template Usage
|
|
222
|
+
|
|
223
|
+
Option values are available in EJS templates through the `addOnOption` variable:
|
|
224
|
+
|
|
225
|
+
```ejs
|
|
226
|
+
<!-- Access option value -->
|
|
227
|
+
<% if (addOnOption.myAddOnId.database === 'postgres') { %>
|
|
228
|
+
PostgreSQL specific code
|
|
229
|
+
<% } %>
|
|
230
|
+
|
|
231
|
+
<!-- Use option value in output -->
|
|
232
|
+
const driver = '<%= addOnOption.myAddOnId.database %>'
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
The structure is: `addOnOption.{addOnId}.{optionName}`
|
|
236
|
+
|
|
237
|
+
### Template Conditional Logic
|
|
238
|
+
|
|
239
|
+
Within template files, use `ignoreFile()` to skip file generation:
|
|
240
|
+
|
|
241
|
+
```ejs
|
|
242
|
+
<% if (addOnOption.database.database !== 'postgres') { ignoreFile() } %>
|
|
243
|
+
import { PrismaClient } from '@prisma/client'
|
|
244
|
+
|
|
245
|
+
declare global {
|
|
246
|
+
var __prisma: PrismaClient | undefined
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export const prisma = globalThis.__prisma || new PrismaClient()
|
|
250
|
+
|
|
251
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
252
|
+
globalThis.__prisma = prisma
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Complete Example: Database Add-on
|
|
257
|
+
|
|
258
|
+
Here's how you could implement a configurable database add-on for Solid:
|
|
259
|
+
|
|
260
|
+
### Examples
|
|
261
|
+
|
|
262
|
+
Configuration in `info.json`:
|
|
263
|
+
|
|
264
|
+
```json
|
|
265
|
+
{
|
|
266
|
+
"name": "Database Integration",
|
|
267
|
+
"description": "Add database support with configurable providers to your Solid application.",
|
|
268
|
+
"modes": ["file-router"],
|
|
269
|
+
"options": {
|
|
270
|
+
"database": {
|
|
271
|
+
"type": "select",
|
|
272
|
+
"label": "Database Provider",
|
|
273
|
+
"description": "Choose your database provider",
|
|
274
|
+
"default": "postgres",
|
|
275
|
+
"options": [
|
|
276
|
+
{ "value": "postgres", "label": "PostgreSQL" },
|
|
277
|
+
{ "value": "mysql", "label": "MySQL" },
|
|
278
|
+
{ "value": "sqlite", "label": "SQLite" }
|
|
279
|
+
]
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Code in `assets/src/routes/demo.database.tsx.ejs`:
|
|
286
|
+
|
|
287
|
+
```ejs
|
|
288
|
+
import { createSignal, onMount } from 'solid-js'
|
|
289
|
+
|
|
290
|
+
export default function DatabaseDemo() {
|
|
291
|
+
const [status, setStatus] = createSignal('Connecting...')
|
|
292
|
+
|
|
293
|
+
onMount(async () => {
|
|
294
|
+
try {
|
|
295
|
+
// Database-specific connection logic
|
|
296
|
+
<% if (addOnOption.database.database === 'postgres') { %>
|
|
297
|
+
const { prisma } = await import('../db')
|
|
298
|
+
await prisma.$connect()
|
|
299
|
+
setStatus('Connected to PostgreSQL!')
|
|
300
|
+
<% } else if (addOnOption.database.database === 'mysql') { %>
|
|
301
|
+
const { prisma } = await import('../db')
|
|
302
|
+
await prisma.$connect()
|
|
303
|
+
setStatus('Connected to MySQL!')
|
|
304
|
+
<% } else if (addOnOption.database.database === 'sqlite') { %>
|
|
305
|
+
const { prisma } = await import('../db')
|
|
306
|
+
await prisma.$connect()
|
|
307
|
+
setStatus('Connected to SQLite!')
|
|
308
|
+
<% } %>
|
|
309
|
+
} catch (error) {
|
|
310
|
+
setStatus(`Connection failed: ${error.message}`)
|
|
311
|
+
}
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
return (
|
|
315
|
+
<div>
|
|
316
|
+
<h1>Database Demo</h1>
|
|
317
|
+
<p>Database Type: <%= addOnOption.database.database %></p>
|
|
318
|
+
<p>Status: {status()}</p>
|
|
319
|
+
</div>
|
|
320
|
+
)
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Code in `package.json.ejs`:
|
|
325
|
+
|
|
326
|
+
```ejs
|
|
327
|
+
{
|
|
328
|
+
"prisma": "^6.16.3",
|
|
329
|
+
"@prisma/client": "^6.16.3"<% if (addOnOption.database.database === 'postgres') { %>,
|
|
330
|
+
"pg": "^8.11.0",
|
|
331
|
+
"@types/pg": "^8.10.0"<% } else if (addOnOption.database.database === 'mysql') { %>,
|
|
332
|
+
"mysql2": "^3.6.0"<% } else if (addOnOption.database.database === 'sqlite') { %><% } %>
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## CLI Usage
|
|
337
|
+
|
|
338
|
+
### Interactive Mode
|
|
339
|
+
|
|
340
|
+
When using the CLI interactively, users are prompted for each option:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
create-tsrouter-app my-solid-app
|
|
344
|
+
# User selects database add-on
|
|
345
|
+
# CLI prompts: "Database Integration: Database Provider" with options
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Non-Interactive Mode
|
|
349
|
+
|
|
350
|
+
Options can be specified via JSON configuration:
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
create-tsrouter-app my-solid-app --add-ons database --add-on-config '{"database":{"database":"mysql"}}'
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## Best Practices
|
|
357
|
+
|
|
358
|
+
1. **Use descriptive labels** - Make option purposes clear to users
|
|
359
|
+
2. **Provide sensible defaults** - Choose the most common use case
|
|
360
|
+
3. **Group related files** - Use consistent prefixing for option-specific files
|
|
361
|
+
4. **Document options** - Include descriptions to help users understand choices
|
|
362
|
+
5. **Test all combinations** - Ensure each option value generates working code
|
|
363
|
+
6. **Use validation** - The system validates options against the schema automatically
|
|
364
|
+
7. **Consider Solid patterns** - Use Solid-specific patterns like signals and resources
|
|
365
|
+
8. **Framework compatibility** - Ensure generated code works with Solid's reactivity system
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/cta-framework-solid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.1",
|
|
4
4
|
"description": "CTA Framework for Solid",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"author": "Jack Herrington <jherr@pobox.com>",
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@tanstack/cta-engine": "0.
|
|
25
|
+
"@tanstack/cta-engine": "0.29.1"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^24.6.0",
|