Release notes
The latest Snaplet product updates from the Snaplet team.
30 November 2023 - v0.76.0
🌟 New Features
Snaplet Generate becomes @snaplet/seed
: You can now use the full power of Snaplet Seed everywhere in your codebase! Here is a sneak peek:
// seed.mtsimport { SnapletClient } from "@snaplet/seed";const snaplet = new SnapletClient();await snaplet.users(x => x(3, () => ({ posts: (x) => x(10)})));
To know more about @snaplet/seed
, read our quick start guide (opens in a new tab).
🚨 Breaking change in 'snaplet generate'
With the publishing of @snaplet/seed
, there is no more generate.run
function in the Snaplet configuration file.
The snaplet generate
command is repurposed to generate the code needed to use @snaplet/seed
.
You can follow this migration guide: https://docs.snaplet.dev/migrations/seed#from-0760-and-above (opens in a new tab)
Thank you for being a part of our journey! 💚
7 November 2023 - v0.74.0
🚨 Breaking change: Preview databases
Preview Database Handling Overhaul. We've revamped how we handle preview databases. It's crucial that if you're using preview databases that you upgrade your Snaplet CLI to the latest version to ensure compatibility. Run snaplet upgrade
to upgrade.
7 November 2023 - v0.73.1
🛠️ CLI improvements
This version introduces several fixes to enhance your command-line interface experience.
Restoration Behavior on Interruption: If you press Ctrl+C during a restoration prompt, it defaults to a 'no' response to continue the restoration process without interruption.
Integer Collision Generation: The generate
command has been improved to produce a larger number of values with very low conflict probabilities.
Snapshot Support in PDB Creation: We've made it easier to identify early on if a snapshot won't restore successfully into a preview database by marking unsupported snapshots during PDB creation.
2 November 2023 - v0.73.0
🚨 Generate seeds breaking change
We've made a change to the way Snaplet generates seeds, which breaks previous data generations. We previously introduced a hash based on the plan's inputs to our seeding mechanism, but after user feedback, it's clear that it's not the right approach. The issue with this approach is that if you alter your plan, the modification will impact all the models involved in the plan. As such, we've decided to roll it back.
If you're interested in the specifics, read on.
Let's take this example:
await snaplet.users([ { name: 'John' }, // user id will be 42 { name: 'Jane' }, // user id will be 59 { name: 'Bob' }, // user id will be 14])
If you add an email to Bob
, the user ids will change for all the users:
await snaplet.users([ { name: 'John' }, // user id will be 98 { name: 'Jane' }, // user id will be 35 { name: 'Bob', email: 'bob@acme.com' }, // user id will be 74])
This is because the seeds injected to each field generate functions which were constructed like this:
<hash of the plan inputs>/0/users/0/id
Now that we removed the hash, a field's value is entirely dependent on the model's location in the plan (basically its path):
0/users/0/id
So altering your plans will no longer impact the other models and fields ouputs.
It unfortunately means that your generated data output will change with this release.
🚨 Alias strategy is now opt-in
We recently introduced aliases to customize the data client.
At the time we shipped this feature, we also decided to apply a default alias strategy to the data client. Based on feedback we've decided to revert this change and make it opt-in instead so it's more predictable for you. This is also a breaking change.
To opt-in, you now need to set the inflection
option to true
:
defineConfig({ generate: { alias: { inflection: true, }, },});
31 October 2023 - v0.72.0
🛠️ Copycat improvements
You can't scramble an omlette without breaking some eggs 🍳. We've made improvements to @snaplet/copycat (opens in a new tab) that introduce breaking changes with how Copycat "scrambles" data during transformation:
- For the same input column value from your database, new snapshots will now be have different resulting values compared to what they used to be in previous snapshots.
- Snaplet generate will generate values that are different to what they used to be.
What this means is that if your tests were expecting to see deterministic values from your Copycat changes, these tests may break, as Copycat generates new deterministic values for all transformations. As such, this new improvement gets a 🚨 breaking change 🚨 flag.
We've made this change in part to improvement the performace of Copycat, and so, the good news is if you've experienced slow snapshot captures in the past when capturing large column values, you may see an improvement in the time it now takes for your snapshots to capture.
Capturing snapshots or generating with Snaplet will still be deterministic though! The data will only change with the next snapshot you capture or the next time you generate data - after which point it will remain the same across as long as the inputs do not change.
If you rely on Snaplet generating data or transforming data that does not change if the inputs do not change, this release might affect you. More specifically, this change will affect you if you are:
- Using "auto"-transform mode (if you have transform:
{ $mode: 'auto' }
in your Snaplet configuration as shown in the Data Editor on app.snaplet.dev). - Using Copycat in your Snaplet configuration to generate data or transform data when capturing snapshots.
- Using our generate feature.
October 30 2023 - v0.71.0
🐛 Snapshot capture bug fix
We squashed a long-standing bug 🐛 which impacts the snapshot files format for users using older versions of the Snaplet CLI.
If you captured a snapshot with a version of Snaplet CLI prior to 0.71.0, you can either:
Capture a new snapshot, which will save it to the new fixed format (recommended):
npx snaplet@latest snapshot capture
Or run the restore command with the last version of Snaplet CLI before the fix:
npx snaplet@0.70.1 snapshot restore
As this is a 🚨 breaking change 🚨 we added a notice in the console when running snaplet snapshot restore
pointing to this migration note (opens in a new tab).
If you're having trouble with this change, come ask us for help on Discord (opens in a new tab).
25 October 2023 - v0.70.0
🧹 Removing deprecated commands
Out with the old! In this release we wave goodbye to the following deprecated commands:
👋 snaplet snapshot subset
👋 snaplet subset command
👋 snaplet config setup
Note that the removal of the above commands is is a 🚨 breaking change.
🎁 New feature - JSDoc comments
We added JSDoc comments everywhere in the data client so it's easier to discover its API and understand the options and your database schema.
23 October 2023 - v0.69.0
🎁 New feature - Introducing aliases
We are super excited to introduce a new configuration option for Generate called alias
, which allows you to take full control over how your models, fields and relationships are named. We shipped a sensible default implementation which should cover the majority of the use cases but if you need more customization, you can!
The default rules for the aliases:
- Model names: pluralized and camelCased.
- Scalar field names: camelCased.
- Parent field names (one to one relationships): singularized and camelCased.
- Child field names (one to many relationships): pluralized and camelCased.
Don't forget to update your types after you have updated the CLI by running:
snaplet config generate
🛠️ Aliases strategy applied by default
With the introduction of alias above, and we will apply a default strategy so the client's code looks better and is easier to reason about.
If you want to opt-out, you can by setting the new inflection option to false
:
/// <reference path=".snaplet/snaplet.d.ts" />import { defineConfig } from 'snaplet';export default defineConfig({ generate: { alias: { inflection: false, }, async run(snaplet) { await snaplet.User((x) => x(3)) }, },});
🧹 Removal of the object form shortcut for one-to-many relationships -
We've changed the signature for one-to-many relationship, we removed the object form when you only want to generate 1 element. It was confusing to be able to use both object and array.
// previously// create a single usersnaplet.User({})// create a user with a postsnaplet.User({ Post: {}})// from 0.69.0 onwards// create a single usersnaplet.User([{}])// create a user with a postsnaplet.User([{ Post: [{}]}])
Note that this is a 🚨 breaking change and you'll need to use aliases going forward.
Questions? Come ask us for help on Discord (opens in a new tab).*
18 October 2023 - v0.68.0
🚨 Breaking Change: pipe
and merge
We've changed the signature for the pipe
and merge
operators to take in an array of plans instead of using variadic arguments for plans:
// previouslysnaplet.$pipe(snaplet.User({}), snaplet.Post({}))snaplet.$merge(snaplet.User({}), snaplet.Post({}))snaplet.User({}).pipe(snaplet.Post({}))snaplet.User({}).merge(snaplet.Post({}))// from 0.68.1 onwardssnaplet.$pipe([snaplet.User({}), snaplet.Post({})])snaplet.$merge([snaplet.User({}), snaplet.Post({}))snaplet.User({}).pipe([snaplet.Post({})])snaplet.User({}).merge([snaplet.Post({})])
🎁 New Feature: options supported for pipe
and merge
operators
As you may expect, with this change, we now also support options to be provided for these operators in our Generate API.
snaplet.$merge([/* ... plans */], { models: { Post: { data: { // This title will be used for all plans // being combined by this merge title: 'A title for posts in the merged plans' } } }})
Options given to these operators will be passed down to the plans they are combining. If these plans provide their own options, they will take precedence over the corresponding pipe/merge options.
🐛 Bug fixes - Generate
We were were not detecting identity columns correctly, and generate
was not able to generate and insert rows for tables with identity columns. Snaplet generate
is now able to correctly detect if it is dealing with an identity column, and uses OVERRIDING SYSTEM VALUE
when outputting INSERT
statements in order to work with these columns.
16 October 2023 - v0.67.0
🚨 Breaking Change: Better seeding values
For Snaplet generate
we've modified the seed
values generated to be more logically consistent and aligned with users' expectations.
By way of demonstration, before this release, the same id would be returned for these two users:
await snaplet.User({ email: 'alice@acme.com' })await snaplet.User({ email: 'bob@acme.com' })
Doen't make much sense, right? This was because the seed value injected per column was only relying on your plan's paths (here the seed for the User's id would be 0/User/id
).
We produce a hash based on the inputs you provide to snaplet.<modelName>(inputs)
so the output will always depends on the inputs. It's the same behaviour as Snaplet Copycat (opens in a new tab), and we think it's more predictable and logical that way.
🎁 New Features: generate
improvements
We've added the --output
option to generate
so you can safely write the SQL statement to a file without being bothered by eventual other messages logged to stdout (like our auto upgrade message). Read more (opens in a new tab).
We've also added more ways of handling tags
attached to a snapshot to the CLI. Read more (opens in a new tab).
12 October 2023 - v0.66.0
✅ Generate
in Beta
A major milestone for our generate
feature, which officially enters beta status!
With this release, we have totally reworked the generate
API so it can be both more powerful and flexible. It goes from alpha to beta status, and we'd love to hear your feedback!
If you've been using generate
you'll need to migrate to use the latest version. We have a migration guide here (opens in a new tab).
Just getting started? If you want to know more about how to generate data you can refer to our quick start guide (opens in a new tab) or our generate
core concept (opens in a new tab) page where we dig deeper into generate
and its options.
Happy generating!