Repository: koishijs/novelai-bot
File: src/index.ts (TypeScript)

Code before:
                hires_fix: options.hiresFix ?? config.hiresFix ?? false,
                steps: parameters.steps,
                n: parameters.n_samples,
              },
              nsfw: nsfw !== 'disallow',
              trusted_workers: config.trustedWorkers,
              censor_nsfw: nsfw === 'censor',
              models: [options.model],
              source_image: image?.base64,
              source_processing: image ? 'img2img' : undefined,
              // support r2 upload
              // https://github.com/koishijs/novelai-bot/issues/163
              r2: true,
            }
          }
          case 'comfyui': {
            const workflowText2Image = config.workflowText2Image ? resolve(ctx.baseDir, config.workflowText2Image) : '../data/default-comfyui-t2i-wf.json'
            const workflowImage2Image = config.workflowImage2Image ? resolve(ctx.baseDir, config.workflowImage2Image) : '../data/default-comfyui-i2i-wf.json'
            const workflow = image ? workflowImage2Image : workflowText2Image
            logger.debug('workflow:', workflow)
            const prompt= require(workflow)

            // have to upload image to the comfyui server first
            if (image) {
              const body = new FormData();
              const capture = /^data:([\w/-]+);base64,(.*)$/.exec(image.dataUrl)
              const [, mime,] = capture
              
              let name = Date.now().toString() 
              const ext = mime === 'image/jpeg' ? 'jpg' : mime === 'image/png' ? 'png' : '';
              if (ext) name += `.${ext}`
              const imageFile = new Blob([image.buffer], {type:mime})
              body.append("image", imageFile, name);
              const res = await ctx.http(trimSlash(config.endpoint) + "/upload/image", {
                method: 'POST',
                headers: {
                  ...config.headers,
                },
                data: body,
              })
              if (res.status === 200) {
                const data = res.data;
                let imagePath = data.name;
                if (data.subfolder) imagePath = data.subfolder + "/" + imagePath;
      
                for (const nodeId in prompt) {
                  if (prompt[nodeId].class_type === 'LoadImage') {
                    prompt[nodeId].inputs.image = imagePath
                    break
                  }
                }

Review comment (suggestion):
```suggestion
              const capture = /^data:([\w/.+-]+);base64,(.*)$/.exec(image.dataUrl)
```

ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types

Code after:
                karras: options.sampler.includes('_ka'),
                hires_fix: options.hiresFix ?? config.hiresFix ?? false,
                steps: parameters.steps,
                n: parameters.n_samples,
              },
              nsfw: nsfw !== 'disallow',
              trusted_workers: config.trustedWorkers,
              censor_nsfw: nsfw === 'censor',
              models: [options.model],
              source_image: image?.base64,
              source_processing: image ? 'img2img' : undefined,
              // support r2 upload
              // https://github.com/koishijs/novelai-bot/issues/163
              r2: true,
            }
          }
          case 'comfyui': {
            const workflowText2Image = config.workflowText2Image ? resolve(ctx.baseDir, config.workflowText2Image) : resolve(__dirname,'../data/default-comfyui-t2i-wf.json')
            const workflowImage2Image = config.workflowImage2Image ? resolve(ctx.baseDir, config.workflowImage2Image) : resolve(__dirname,'../data/default-comfyui-i2i-wf.json')
            const workflow = image ? workflowImage2Image : workflowText2Image
            logger.debug('workflow:', workflow)
            const prompt = JSON.parse(await readFile(workflow, 'utf8'))

            // have to upload image to the comfyui server first
            if (image) {
              const body = new FormData()
              const capture = /^data:([\w/.+-]+);base64,(.*)$/.exec(image.dataUrl)
              const [, mime,] = capture
              
              let name = Date.now().toString() 
              const ext = mime === 'image/jpeg' ? 'jpg' : mime === 'image/png' ? 'png' : ''
              if (ext) name += `.${ext}`
              const imageFile = new Blob([image.buffer], {type:mime})
              body.append("image", imageFile, name)
              const res = await ctx.http(trimSlash(config.endpoint) + '/upload/image', {
                method: 'POST',
                headers: {
                  ...config.headers,
                },
                data: body,
              })
              if (res.status === 200) {
                const data = res.data
                let imagePath = data.name
                if (data.subfolder) imagePath = data.subfolder + '/' + imagePath
      
                for (const nodeId in prompt) {
                  if (prompt[nodeId].class_type === 'LoadImage') {
                    prompt[nodeId].inputs.image = imagePath
                    break
                  }