@@ -4,7 +4,8 @@ import { TiddlerFields, TW } from "tiddlywiki";
44import * as fs from "fs" ;
55import * as path from "path" ;
66import { truthy } from "@tiddlywiki/server" ;
7- import { importBags , importRecipes , indexImportedBagsByName } from "../new-managers/wiki-import" ;
7+ import { importBags , importRecipes , indexImportedBagsByName , toMappingRows , WikiImportWriter } from "../new-managers/wiki-import" ;
8+ import { RecipeDefinition } from "../new-managers/wiki-actions" ;
89
910export const info : CommandInfo = {
1011 name : "load-wiki-folder" ,
@@ -13,12 +14,14 @@ export const info: CommandInfo = {
1314 [ "path" , "Path to the folder containing a tiddlywiki.info file" ] ,
1415 ] ,
1516 options : [
16- [ "bag-name <string>" , "Name of the bag to load tiddlers into" ] ,
17- [ "bag-description <string>" , "Description of the bag" ] ,
1817 [ "recipe-name <string>" , "Name of the recipe to create" ] ,
1918 [ "recipe-description <string>" , "Description of the recipe" ] ,
19+ [ "bag-name <string>" , "Name of the bag to load tiddlers into" ] ,
20+ [ "bag-description <string>" , "Description of the bag" ] ,
2021 [ "template-name <string>" , "Template for this recipe" ] ,
21- [ "overwrite" , "Confirm that you want to overwrite existing content" ]
22+ [ "owner-roles <string>" , "Roles to set on the recipes and bags." ] ,
23+ [ "overwrite" , "Confirm that you want to overwrite existing content" ] ,
24+ [ "skip-existing" , "Confirm that you want to skip existing content" ] ,
2225 ] ,
2326} ;
2427// tiddlywiki --load ./mywiki.html --savewikifolder ./mywikifolder
@@ -27,8 +30,10 @@ export class Command extends BaseCommand<[string], {
2730 "bag-description" ?: string [ ] ;
2831 "recipe-name" ?: string [ ] ;
2932 "recipe-description" ?: string [ ] ;
33+ "owner-roles" ?: string [ ] ;
3034 "template-name" ?: string [ ] ;
3135 "overwrite" ?: boolean ;
36+ "skip-existing" ?: boolean ;
3237} > {
3338
3439
@@ -51,79 +56,113 @@ export class Command extends BaseCommand<[string], {
5156 const templateName = this . options [ "template-name" ] ?. [ 0 ] ?? "Blank Template" ;
5257
5358 const overwrite = ! ! this . options [ "overwrite" ] ;
59+ const skipExisting = ! ! this . options [ "skip-existing" ] ;
5460
5561 const bagName = this . options [ "bag-name" ] [ 0 ] ;
5662 const bagDescription = this . options [ "bag-description" ] [ 0 ] ;
5763 const recipeName = this . options [ "recipe-name" ] [ 0 ] ;
5864 const recipeDescription = this . options [ "recipe-description" ] [ 0 ] ;
59- const templateId = await getTemplateIdByName ( this . config . engine , templateName ) ;
60- if ( ! templateId ) {
65+
66+ const ownerRoles = this . options [ "owner-roles" ] ?? [ ] ;
67+
68+ if ( ! templateName ) {
6169 throw new Error ( `Template ${ templateName } does not exist.` ) ;
6270 }
6371
64- const existingRecipe = await this . config . engine . recipe . findUnique ( {
65- where : { slug : recipeName } ,
66- select : { id : true } ,
67- } ) ;
68- const existingBag = await this . config . engine . bag . findUnique ( {
69- where : { name : bagName } ,
70- select : { id : true } ,
71- } ) ;
72+ this . config . engine . $transaction ( async prisma => {
73+ const importer = new WikiImportWriter ( prisma , false ) ;
7274
73- if ( ! overwrite && ( existingRecipe || existingBag ) ) {
74- console . log ( `Recipe or bag already exists for ${ recipeName } . Use --overwrite to overwrite it. Skipping.` ) ;
75- return ;
76- }
75+ const existingRecipe = await prisma . recipe . findUnique ( {
76+ where : { slug : recipeName } ,
77+ select : { id : true } ,
78+ } ) ;
79+ const existingBag = await prisma . bag . findUnique ( {
80+ where : { name : bagName } ,
81+ select : { id : true } ,
82+ } ) ;
83+ if ( ( existingRecipe || existingBag ) ) {
84+ if ( ! overwrite && ! skipExisting ) {
85+ throw `Recipe or bag already exists for ${ recipeName } . Use --overwrite to overwrite it or --skip-existing to continue.` ;
86+ }
87+ if ( skipExisting ) {
88+ console . log ( `Recipe or bag already exists for ${ recipeName } . Use --overwrite to overwrite it or --skip-existing to continue.` ) ;
89+ return ;
90+ }
91+ }
7792
78- const { pluginTitles, tiddlers } = loadWikiFolder ( {
79- wikiPath : this . params [ 0 ] ,
80- bagName,
81- bagDescription,
82- recipeName,
83- recipeDescription,
84- $tw : this . $tw ,
85- cache : this . config . pluginCache ,
86- } ) ;
93+ const template = await prisma . template . findUnique ( {
94+ where : { name : templateName } ,
95+ select : { id : true , definition : true , type : true }
96+ } ) ;
8797
88- if ( overwrite ) {
89- await deleteExistingWikiFolderSeedData ( this . config . engine , { recipeName, bagName } ) ;
90- }
98+ if ( ! template ) {
99+ throw `The specified template name '${ templateName } ' could not be found.` ;
100+ }
101+
102+ const { pluginTitles, tiddlers } = loadWikiFolder ( {
103+ recipeName,
104+ recipeDescription,
105+ bagName,
106+ bagDescription,
107+ wikiPath : this . params [ 0 ] ,
108+ cache : this . config . pluginCache ,
109+ $tw : this . $tw ,
110+ } ) ;
91111
92- const bagSeed = await importBags ( this . config . engine , [ {
112+ const [ bag ] = await importer . importBags ( [ {
93113 name : bagName ,
94114 description : bagDescription ,
95- permissions : [ ] ,
115+ permissions : ownerRoles . map ( roleId => ( { level : "C_admin" , roleId } ) ) ,
96116 } ] ) ;
97- const bag = indexImportedBagsByName ( bagSeed ) . get ( bagName )
98- ?? await this . config . engine . bag . findUnique ( { where : { name : bagName } , select : { id : true , name : true } } ) ;
99117
100- if ( ! bag ) {
101- throw new Error ( `Failed to create bag ${ bagName } ` ) ;
102- }
118+ if ( ! bag ) {
119+ throw new Error ( `Failed to create bag ${ bagName } ` ) ;
120+ }
103121
104- await importRecipes ( this . config . engine , [ {
105- slug : recipeName ,
106- templateId,
107- definition : {
108- displayName : recipeName ,
109- description : recipeDescription ,
110- readonlyBags : [ ] ,
111- writablePrefixBags : { "" : bagName } ,
112- plugins : pluginTitles ,
113- } ,
114- plugins : pluginTitles ,
115- permissions : [ ] ,
116- compiledBags : [ {
117- bagId : bag . id ,
118- priority : 0 ,
119- isWritable : true ,
120- prefix : "" ,
121- } ] ,
122- } ] ) ;
122+ switch ( template . type ) {
123+ case "simpleV1" : {
124+ const recipeDefinition : RecipeDefinition = {
125+ displayName : recipeName ,
126+ description : recipeDescription ,
127+ plugins : pluginTitles ,
128+ readonlyBags : [ ] ,
129+ writablePrefixBags : toMappingRows ( { "" : bagName } ) ,
130+ } ;
131+ const {
132+ bags : compiledBags , plugins : compiledPlugins
133+ } = await importer . compileRecipeSimpleV1 ( recipeDefinition , template . definition ) ;
134+ const [ recipe ] = await importer . importRecipes ( [ {
135+ compiledBags,
136+ plugins : compiledPlugins ,
137+ definition : recipeDefinition ,
138+ permissions : ownerRoles . map ( roleId => ( { level : "B_write" , roleId } ) ) ,
139+ slug : recipeName ,
140+ templateId : template . id ,
141+ } ] ) ;
142+ await saveLoadedTiddlers ( this . config . engine , bag . id , tiddlers ) ;
143+ }
144+ }
145+
146+
147+ // const compiledRecipe = await importer.compileRecipe({
148+ // slug: recipeName,
149+ // definition: {
150+ // displayName: recipeName,
151+ // description: recipeDescription,
152+ // readonlyBags: [],
153+ // writablePrefixBags: { "": bagName },
154+ // plugins: pluginTitles,
155+ // },
156+ // permissions: ownerRoles.map(roleId => ({ level: "B_write", roleId })),
157+ // }, template);
123158
124- await saveLoadedTiddlers ( this . config . engine , bag . id , tiddlers ) ;
125159
126- console . log ( info . name , "complete:" , this . params [ 0 ] )
160+
161+
162+
163+ console . log ( info . name , "complete:" , this . params [ 0 ] )
164+ } ) ;
165+
127166 return null ;
128167 }
129168
@@ -162,46 +201,9 @@ function loadWikiFolder({ $tw, cache, ...options }: {
162201
163202}
164203
165- async function getTemplateIdByName ( prisma : PrismaEngineClient , templateName : string ) {
166- const templates = await prisma . template . findMany ( {
167- select : { id : true , definition : true } ,
168- } ) ;
169- return templates . find ( ( template ) => template . definition . name === templateName ) ?. id ?? null ;
170- }
171-
172- async function deleteExistingWikiFolderSeedData ( prisma : PrismaEngineClient , { recipeName, bagName } : {
173- recipeName : string ;
174- bagName : string ;
175- } ) {
176- await prisma . $transaction ( async ( tx ) => {
177- const existingRecipe = await tx . recipe . findUnique ( {
178- where : { slug : recipeName } ,
179- select : { id : true , template_id : true } ,
180- } ) ;
181-
182- if ( existingRecipe ) {
183- await tx . recipe . delete ( { where : { id : existingRecipe . id } } ) ;
184- const templateUsageCount = await tx . recipe . count ( { where : { template_id : existingRecipe . template_id } } ) ;
185- if ( ! templateUsageCount ) {
186- await tx . template . delete ( { where : { id : existingRecipe . template_id } } ) ;
187- }
188- }
189-
190- const existingBag = await tx . bag . findUnique ( {
191- where : { name : bagName } ,
192- select : { id : true } ,
193- } ) ;
194-
195- if ( existingBag ) {
196- await tx . bag . delete ( { where : { id : existingBag . id } } ) ;
197- }
198- } ) ;
199-
200- }
201-
202- async function saveLoadedTiddlers ( prisma : PrismaEngineClient , bagId : string , tiddlers : TiddlerFields [ ] ) {
204+ async function saveLoadedTiddlers ( prisma : PrismaEngineClient , bag_id : string , tiddlers : TiddlerFields [ ] ) {
203205 await prisma . $transaction ( async ( tx ) => {
204- await tx . tiddler . deleteMany ( { where : { bag_id : bagId } } ) ;
206+ await tx . tiddler . deleteMany ( { where : { bag_id } } ) ;
205207
206208 for ( const tiddler of tiddlers ) {
207209 const title = tiddler . title ;
@@ -214,12 +216,16 @@ async function saveLoadedTiddlers(prisma: PrismaEngineClient, bagId: string, tid
214216 . filter ( ( [ , value ] ) => value !== undefined )
215217 . map ( ( [ fieldName , fieldValue ] ) => [ fieldName , typeof fieldValue === "string" ? fieldValue : `${ fieldValue } ` ] )
216218 ) ;
219+ const event = await tx . tiddlerEvent . create ( {
220+ data : { bag_id, title, type : "save" }
221+ } ) ;
217222
218223 await tx . tiddler . upsert ( {
219- where : { bag_id_title : { bag_id : bagId , title } } ,
220- update : { fields, revision : BigInt ( 0 ) } ,
221- create : { bag_id : bagId , title, fields, revision : BigInt ( 0 ) } ,
224+ where : { bag_id_title : { bag_id, title } } ,
225+ update : { fields, revision : event . seq } ,
226+ create : { bag_id, title, fields, revision : event . seq } ,
222227 } ) ;
228+
223229 }
224230 } ) ;
225231
0 commit comments