sv-utils = what to do to content, sv = where and when to do it.
Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode().
The parser choice is baked into the transform type - you can't accidentally
parse a vite config as svelte because you never call a parser yourself.
Transforms are curried: call with the callback to get a (content: string) => string
function that plugs directly into sv.file().
import{transforms}from'@sveltejs/sv-utils';// use with sv.file() - curried form plugs in directlysv.file(files.viteConfig,transforms.script(({ast,js})=>{js.vite.addPlugin(ast,{code:'kitRoutes()'});}));// standalone usage / testingconstresult=transforms.script(({ast,js})=>{js.imports.addDefault(ast,{as:'foo',from:'foo'});})(fileContent);
().build(method)build():{}(),// appelé avant l'exécution — déclarer des dépendances, des prérequis d'environnement et des options dynamiquessetup(property)setup?:((workspace:Workspace&{dependsOn:(name:keyofOfficialAddons)=>void;unsupported:(reason:string)=>void;runsAfter:(name:keyofOfficialAddons)=>void;addOption:<Kextendsstring>(key:K,question:BaseQuestion<any>&Question<any>)=>void;})=>MaybePromise<void>)|undefined:({dependsOn(parameter)dependsOn:(name:keyofOfficialAddons)=>void
On what official addons does this addon depend on?
On what official addons does this addon depend on?
('eslint');// ajoute dynamiquement des options (par ex. basé sur l'état du workspace ou des données récupérées)addOptionany('theme',{question(property)question:string:'Which theme?',type(property)type:string:'select',default(property)default:string:'dark',options(property)options:{value:string;}[]:[{value(property)value:string:'dark'},{value(property)value:string:'light'}]});},// le travail effectif — ajouter, modifier des fichiers, déclarer des dépendancesrun(property)run:(workspace:Workspace&{options:OptionValues<{}>&Record<string,unknown>;sv:SvApi;cancel:(reason:string)=>void;})=>MaybePromise<void>:({sv(parameter)sv:SvApi,options(parameter)options:OptionValues<{}>&Record<string,unknown>
Add-on options (includes dynamically added options from setup)
,cancel(parameter)cancel:(reason:string)=>void
Cancel the addon at any time!
})=>{// ajouter une dépendancesv(parameter)sv:SvApi.devDependency(property)devDependency:(pkg:string,version:string)=>void('my-lib','^1.0.0');// créer ou ajouter des fichiers en utilisant des transformations de @sveltejs/sv-utilssv(parameter)sv:SvApi.file(property)file:(path:string,edit:(content:string)=>string|false)=>void
Edit a file in the workspace. (will create it if it doesn't exist)
Return false from the callback to abort - the original content is returned unchanged.
sv-utils = what to do to content, sv = where and when to do it.
Each transform wraps: parse -> callback({ast/data, utils}) -> generateCode().
The parser choice is baked into the transform type - you can't accidentally
parse a vite config as svelte because you never call a parser yourself.
Transforms are curried: call with the callback to get a (content: string) => string
function that plugs directly into sv.file().
import{transforms}from'@sveltejs/sv-utils';// use with sv.file() - curried form plugs in directlysv.file(files.viteConfig,transforms.script(({ast,js})=>{js.vite.addPlugin(ast,{code:'kitRoutes()'});}));// standalone usage / testingconstresult=transforms.script(({ast,js})=>{js.imports.addDefault(ast,{as:'foo',from:'foo'});})(fileContent);
Return false from the callback to abort - the original content is returned unchanged.
(({ast(parameter)ast:AST.Root,svelte(parameter)svelte:typeofindex_d_exports$4})=>{svelte(parameter)svelte:typeofindex_d_exports$4.addFragment(alias)index_d_exports$4.addFragment(ast:AST.Root,content:string,options?:{mode?:"append"|"prepend";language?:"ts"|"js";}):voidexportindex_d_exports$4.addFragment(ast(parameter)ast:AST.Root,'<p>Hello!</p>');}));// annuler à tout moment si quelque chose se passe mal // cancel('reason');
},// affiché après l'exécution de l'add-onnextSteps(property)nextSteps?:((workspace:Workspace&{options:OptionValues<{}>&Record<string,unknown>;})=>string[])|undefined:({options(parameter)options:OptionValues<{}>&Record<string,unknown>})=>['Lancer `npm run dev` pour commencer']});
L’objet sv dans run fournit file, dependency, devDependency, et execute. Pour les
transformations (l’édition de scripts, de composants Svelte, de CSS, de JSON,... basée sur des AST),
et les utilitaires de gestion de paquets, consultez @sveltejs/sv-utils.
Options typées dynamiques
Si votre add-on ajoute des options dynamiquement dans setup, (par ex, depuis un appel fetch),
vous pouvez fournir un paramètre de type à defineAddon pour obtenir un typage fort pour ces
options :
Add-on options (includes dynamically added options from setup)
.theme(property)theme:string;// string}});
Le paramètre de type fait correspondre le type (boolean, string, number) aux définitions des
questions. Sans ce paramètre, defineAddon reste strict et autorise uniquement des options définies
de manière statique.
defineAddonOptions
Permet de construire des options pour les add-ons. Chaîné avec .add() et finalisé par .build().
}from'sv';constoptionsconstoptions:{database:{readonlyquestion:"Quelle base de données ?";readonlytype:"select";readonlydefault:"postgresql";readonlyoptions:[{readonlyvalue:"postgresql";},{readonlyvalue:"mysql";},{readonlyvalue:"sqlite";}];};docker:{readonlyquestion:"Ajouter un fichier docker-compose ?";readonlytype:"boolean";readonlydefault:false;readonlycondition:(opts:OptionValues<Record<"database",{readonlyquestion:"Quelle base de données ?";readonlytype:"select";readonlydefault:"postgresql";readonlyoptions:[{readonlyvalue:"postgresql";},{readonlyvalue:"mysql";},{...;}];}>&Record<...>>)=>boolean;};}=defineAddonOptions(alias)defineAddonOptions():OptionBuilder<{}>importdefineAddonOptions
Options for an addon.
Will be prompted to the user if there are not answered by args when calling the cli.
().add(method)add<"database",{readonlyquestion:"Quelle base de données ?";readonlytype:"select";readonlydefault:"postgresql";readonlyoptions:[{readonlyvalue:"postgresql";},{readonlyvalue:"mysql";},{readonlyvalue:"sqlite";}];}>(key:"database",question:{readonlyquestion:"Quelle base de données ?";readonlytype:"select";readonlydefault:"postgresql";readonlyoptions:[{readonlyvalue:"postgresql";},{readonlyvalue:"mysql";},{readonlyvalue:"sqlite";}];}):OptionBuilder<Record<"database",{readonlyquestion:"Quelle base de données ?";readonlytype:"select";readonlydefault:"postgresql";readonlyoptions:[{readonlyvalue:"postgresql";},{readonlyvalue:"mysql";},{readonlyvalue:"sqlite";}];}>>
This type is a bit complex, but in usage, it's quite simple!
The idea is to add() options one by one, with the key and the question.
.add('demo',{question:'Do you want to add a demo?',type:'boolean',// string, number, select, multiselectdefault:true,// condition: (o) => o.previousOption === 'ok',})
('database',{question(property)question:"Quelle base de données ?":'Quelle base de données ?',type(property)type:"select":'select',default(property)default:"postgresql":'postgresql',options(property)options:[{readonlyvalue:"postgresql";},{readonlyvalue:"mysql";},{readonlyvalue:"sqlite";}]:[{value(property)value:"postgresql":'postgresql'},{value(property)value:"mysql":'mysql'},{value(property)value:"sqlite":'sqlite'}]}).add(method)add<"docker",{readonlyquestion:"Ajouter un fichier docker-compose ?";readonlytype:"boolean";readonlydefault:false;readonlycondition:(opts:OptionValues<Record<"database",{readonlyquestion:"Quelle base de données ?";readonlytype:"select";readonlydefault:"postgresql";readonlyoptions:[{readonlyvalue:"postgresql";},{readonlyvalue:"mysql";},{readonlyvalue:"sqlite";}];}>&Record<"docker",any>>)=>boolean;}>(key:"docker",question:{readonlyquestion:"Ajouter un fichier docker-compose ?";readonlytype:"boolean";readonlydefault:false;readonlycondition:(opts:OptionValues<Record<"database",{readonlyquestion:"Quelle base de données ?";readonlytype:"select";readonlydefault:"postgresql";readonlyoptions:[{readonlyvalue:"postgresql";},{readonlyvalue:"mysql";},{readonlyvalue:"sqlite";}];}>&Record<"docker",any>>)=>boolean;}):OptionBuilder<...>
This type is a bit complex, but in usage, it's quite simple!
The idea is to add() options one by one, with the key and the question.
.add('demo',{question:'Do you want to add a demo?',type:'boolean',// string, number, select, multiselectdefault:true,// condition: (o) => o.previousOption === 'ok',})
('docker',{question(property)question:"Ajouter un fichier docker-compose ?":'Ajouter un fichier docker-compose ?',type(property)type:"boolean":'boolean',default(property)default:false:false,// ne poser la question que lorsque la base de données n'est pas sqlitecondition(property)condition:(opts:OptionValues<Record<"database",{readonlyquestion:"Quelle base de données ?";readonlytype:"select";readonlydefault:"postgresql";readonlyoptions:[{readonlyvalue:"postgresql";},{readonlyvalue:"mysql";},{readonlyvalue:"sqlite";}];}>&Record<"docker",any>>)=>boolean:(opts(parameter)opts:OptionValues<Record<"database",{readonlyquestion:"Quelle base de données ?";readonlytype:"select";readonlydefault:"postgresql";readonlyoptions:[{readonlyvalue:"postgresql";},{readonlyvalue:"mysql";},{readonlyvalue:"sqlite";}];}>&Record<"docker",any>>)=>opts(parameter)opts:OptionValues<Record<"database",{readonlyquestion:"Quelle base de données ?";readonlytype:"select";readonlydefault:"postgresql";readonlyoptions:[{readonlyvalue:"postgresql";},{readonlyvalue:"mysql";},{readonlyvalue:"sqlite";}];}>&Record<"docker",any>>.database(property)database:"postgresql"|"mysql"|"sqlite"!=='sqlite'}).build(method)build():{database:{readonlyquestion:"Quelle base de données ?";readonlytype:"select";readonlydefault:"postgresql";readonlyoptions:[{readonlyvalue:"postgresql";},{readonlyvalue:"mysql";},{readonlyvalue:"sqlite";}];};docker:{readonlyquestion:"Ajouter un fichier docker-compose ?";readonlytype:"boolean";readonlydefault:false;readonlycondition:(opts:OptionValues<Record<"database",{readonlyquestion:"Quelle base de données ?";readonlytype:"select";readonlydefault:"postgresql";readonlyoptions:[{readonlyvalue:"postgresql";},{readonlyvalue:"mysql";},{...;}];}>&Record<...>>)=>boolean;};}();
Les options sont posées dans l’ordre. Le callback condition reçoit les réponses collectées jusque
là — renvoyez false pour éviter la question (sa valeur sera undefined).