Supercharge Sanity Scripts: Reusability With CLI & JSON

by Admin 56 views
Supercharge Sanity Scripts: Reusability with CLI & JSON

Hey there, fellow developers! Ever found yourself staring at a script, knowing it could be super useful for different projects, but it's bogged down with hardcoded values? You know the drill—changing a URL here, tweaking a filename there, and before you know it, you're spending more time editing than actually running the thing. Well, guess what? We're diving deep into making our Sanity CMS submission scripts not just work, but shine with reusability and flexibility. This isn't just about getting a job done; it's about making your life easier, saving you precious time, and building tools that are genuinely versatile. Our goal here is to transform those rigid, one-off scripts into powerful, adaptable utilities that can handle any gallery submission without breaking a sweat, all by embracing the magic of command-line arguments and smart configuration files. We're going to talk about generate-screenshots.mjs and create-featured-submissions.mjs specifically, which are currently a bit stubborn with their hardcoded setups. By the end of this journey, you'll have a clear path to making these scripts, and any others in your arsenal, truly dynamic and ready for anything you throw at them. So, grab your favorite coding beverage, because we're about to make some awesome changes that will seriously boost your developer workflow!

The Core Challenge: Hardcoded Headaches in Sanity Submission Scripts

Let's be real, guys, we've all been there. You're building something cool, maybe a gallery for a client or a portfolio showcase, and you need to automate parts of the submission process to your Sanity CMS. You whip up a script, it works, and you move on. But then, a new project comes along, or you need to update an existing one, and suddenly, that slick script becomes a pain in the neck. Why? Because it's full of hardcoded values. Imagine trying to manage multiple demo sites, each with its own URL, name, and specific blurb, when your script is stubbornly pointing to just one. That's exactly the pickle we're in with our current scripts/generate-screenshots.mjs and scripts/create-featured-submissions.mjs.

Think about it: right now, if you peek into generate-screenshots.mjs, you'll see a JavaScript array like this, just sitting there, defining every single detail:

// Currently hardcoded in generate-screenshots.mjs
const sites = [
  {
    name: 'swiss-metro',
    url: 'https://gsinghjay.github.io/swiss_metro/',
    filename: 'swiss-metro-screenshot.png'
  }
];

Now, this works perfectly fine for swiss-metro. But what happens when you want to capture screenshots for ten other projects? Or what if the URL changes? You'd have to manually open the file, edit the array, save it, and then run the script. This isn't just inefficient; it's a recipe for human error. You might forget to update one detail, or accidentally delete a comma, and suddenly your script is throwing errors, leaving you scratching your head. This hardcoded approach severely limits the script's reusability and flexibility, making it a chore rather than a tool. Every new submission or update means delving into the code, which is far from ideal for a smooth development workflow, especially when working in a team or on a large-scale project. We want to avoid that manual, repetitive work and free ourselves up to focus on more interesting challenges, right? That's precisely why breaking free from hardcoded configurations is not just a nice-to-have, but a must-have for modern, efficient development.

Unleashing Flexibility: Our Proposed Solutions for Reusable Sanity Scripts

Alright, folks, it's time to talk about how we're going to ditch those hardcoded values and inject some serious flexibility into our Sanity submission scripts. We've got a few awesome options on the table, and the cool thing is, you can pick the one that best suits your style or even combine them for ultimate power! Each approach brings its own set of advantages, transforming our static scripts into dynamic, versatile tools ready for any Sanity CMS gallery challenge. Let's break down these game-changing strategies and see how they empower you to handle future submissions with ease and efficiency.

Option A: The Simplicity of JSON Configuration Files

Let's kick things off with arguably the easiest and often most practical approach for batch operations: using a JSON configuration file. Imagine having a single, readable file that holds all the details for your gallery submissions, completely separate from your script logic. This is a fantastic way to manage multiple submissions or complex configurations without touching a line of JavaScript every single time. The beauty of JSON is its universal readability; it's human-friendly, machine-parseable, and just generally a joy to work with. Our idea here is to create a file, let's say scripts/submissions-config.json, which will act as the single source of truth for all your submission data and settings. This means no more digging through generate-screenshots.mjs or create-featured-submissions.mjs to tweak a URL or change a description. All that information lives neatly in one place.

Picture this: your submissions-config.json could look something like this:

{
  "submissions": [
    {
      "id": "submission-example-1",
      "name": "example-style-one",
      "demoUrl": "https://example.com/demo-one",
      "styleRef": "example-style-one",
      "featuredBlurb": "A captivating description for example one..."
    },
    {
      "id": "submission-example-2",
      "name": "example-style-two",
      "demoUrl": "https://example.com/demo-two",
      "styleRef": "example-style-two",
      "featuredBlurb": "Another amazing project, showcasing cutting-edge design..."
    }
  ],
  "settings": {
    "viewport": { "width": 1280, "height": 800 },
    "screenshotDir": "./screenshots",
    "quality": 85
  }
}

See how clean that is? You've got an array of submissions, each with its own id, name, demoUrl, styleRef (which likely links to a Sanity document), and featuredBlurb. Plus, we've got a settings object that can define global parameters like the screenshot viewport dimensions, the screenshotDir where your images will be saved, and even image quality. Your scripts, instead of having hardcoded sites arrays, would simply read and parse this JSON file. In Node.js, that's as simple as using fs.readFileSync and JSON.parse(). This way, you can add new submissions, modify existing ones, or adjust screenshot settings without ever touching the core script logic. It’s perfect for when you need to process a batch of items with consistent settings, making your workflow incredibly streamlined and less prone to errors. Just update the JSON, and your scripts are instantly aware of the changes. This separation of concerns—data from logic—is a cornerstone of maintainable and scalable software development. It means fewer late-night debugging sessions and more time focusing on building cool stuff, which, let's be honest, is what we all want!

Option B: Mastering Dynamic Control with CLI Arguments

For those times when you need surgical precision or want to run a script with ad-hoc, on-the-fly parameters, Command Line Interface (CLI) arguments are your absolute best friend. While JSON files are amazing for batch configurations, CLI arguments give you immediate, direct control over how your script behaves for a single operation. This approach is all about enabling dynamic execution, letting you dictate specific values directly from your terminal, without needing to open or edit any files. Imagine being able to generate a screenshot for a specific URL with a custom width, or upload a single submission based on its ID, all through a simple command. That, my friends, is the power of CLI arguments!

Instead of loading a config file, your scripts would listen for flags and values passed when you execute them. For instance, generating a single screenshot could look like this:

node scripts/generate-screenshot.mjs \
  --url "https://myawesomewebsite.com/demo" \
  --name "my-new-style" \
  --width 1920 \
  --height 1080 \
  --output-dir "./temp-screenshots"

And for uploading a particular submission:

node scripts/create-submission.mjs \
  --id "project-galaxy" \
  --screenshot "./screenshots/galaxy-screenshot.png" \
  --style-ref "galaxy-style" \
  --blurb "A stunning new project showcasing stellar design..."

To implement this, Node.js offers util.parseArgs as a built-in gem for argument parsing, making it straightforward to define your expected arguments, their types, and whether they're mandatory. If you're building a more complex CLI tool with subcommands and intricate options, you might even consider a popular external library like Commander.js. Regardless of the tool, the core idea is to process --flag value pairs. Crucially, your scripts need robust validation and error handling. What if a required argument, like --url, is missing? Your script should gracefully inform the user, perhaps by printing a clear error message and then displaying helpful usage information, which brings us to the importance of the --help flag. A well-implemented --help flag is like providing a mini-manual directly in the terminal, guiding users on how to properly use your script. It's about creating a user-friendly experience, preventing frustration, and making your scripts intuitive to operate. This level of dynamic control is incredibly powerful for testing, debugging, and executing one-off tasks, making your scripts truly versatile and a joy to use in any scenario.

Option C: Elevating Developer Experience with NPM Scripts

Alright, let's talk about taking our newfound flexibility to the next level and making it super convenient for everyone on the team. While JSON config files and CLI arguments give us the power, NPM Scripts provide the ultimate wrapper for a stellar Developer Experience (DX). Think of NPM scripts as aliases or shortcuts for those longer, more complex commands we just talked about. They live right in your package.json file, making them easily discoverable, shareable, and runnable with simple, memorable commands. This approach is all about streamlining workflows, ensuring consistency, and making your submission process feel like a breeze.

By adding a few lines to your package.json, you can create custom commands that execute your refactored Node.js scripts. This is where the magic happens, especially when you combine it with CLI arguments or JSON configuration files. Here's how it might look in your package.json:

{
  "name": "mywebclass",
  "version": "1.0.0",
  "description": "A web class project with Sanity CMS",
  "main": "index.js",
  "scripts": {
    "submission:screenshot": "node scripts/generate-screenshot.mjs --config ./scripts/submissions-config.json",
    "submission:screenshot:single": "node scripts/generate-screenshot.mjs",
    "submission:upload": "node scripts/create-submission.mjs --config ./scripts/submissions-config.json",
    "submission:upload:single": "node scripts/create-submission.mjs",
    "submission:full": "npm run submission:screenshot && npm run submission:upload",
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "next": "latest",
    "react": "latest",
    "react-dom": "latest"
  }
}

Notice the new submission: prefixed scripts? Now, instead of typing out node scripts/generate-screenshot.mjs --url "...", you can simply run npm run submission:screenshot:single -- --url "https://example.com/single" --name "my-single-style". The -- after submission:screenshot:single tells npm to pass the subsequent arguments directly to your Node.js script, making it incredibly flexible. Even better, you can create scripts that default to using your JSON config, like npm run submission:screenshot which might automatically process all entries in submissions-config.json. But the real power move here is submission:full. This script combines multiple steps: npm run submission:screenshot && npm run submission:upload. With one simple command, npm run submission:full, you can generate all necessary screenshots and then upload them to Sanity! This creates a seamless, one-command workflow that's perfect for CI/CD pipelines or simply making your development process as smooth as silk. NPM scripts foster a consistent way of interacting with your project's utilities, which is invaluable for onboarding new team members and maintaining project health over time. It's all about making powerful actions accessible and easy to remember, boosting productivity and collaboration across the board.

What Success Looks Like: Acceptance Criteria for Our Refactor

Okay, team, now that we've explored the exciting possibilities, let's nail down what constitutes a successful refactor. These aren't just arbitrary checkboxes; they're vital benchmarks that ensure our work is robust, user-friendly, and truly adds value. Meeting these acceptance criteria means we've built something genuinely useful and maintainable, not just for ourselves, but for anyone who interacts with these scripts in the future. It’s about ensuring our new, flexible scripts are reliable, intuitive, and integrate seamlessly into our existing development environment.

First and foremost, the core objective: Scripts must read configuration from a file OR accept CLI arguments. This is the heart of our refactoring effort. Whether you opt for a JSON configuration, CLI arguments, or a combination, the scripts need to be able to dynamically consume external input rather than relying on hardcoded values. This ensures adaptability and reusability, which is precisely what we're aiming for. It means our scripts can handle different scenarios and different projects without requiring code changes every single time.

Next, and equally critical: No hardcoded URLs or submission data in the script files themselves. This is the