feat: rewrite items and collections API for better typings
Types of changes
- [ ] Bug fix (a non-breaking change which fixes an issue)
- [ ] New feature (a non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing functionality to change)
Description
Besides all changes in https://github.com/Intevel/nuxt-directus/pull/77, this PR changes the usage of most methods in the useDirectusCollections and useDirectusItems in order to provide better typings. By providing a collection ID first (i.e. createItems('news', { items: { title: 'Hi' }} instead of createItems({ collection: 'news', items: { title: 'Hi' }}) we can make TypeScript aware of the correct collection types in the remaining parameters. This makes sure we can type check item data in createItems and updateItem.
In my opinion, this also improves the API, because users have to type less code, e.g. getCollection({ collection: 'news' }) simply becomes getCollection('news').
Checklist:
- [x] My change requires a change to the documentation.
- [x] I have updated the documentation accordingly.
- [ ] I have added tests to cover my changes (if not applicable, please state why)
Deploy Preview for nuxt-directus canceled.
| Name | Link |
|---|---|
| Latest commit | 3d981f87636f5f1ea78bd78a0803ea5c4379ab2e |
| Latest deploy log | https://app.netlify.com/sites/nuxt-directus/deploys/635656978aaed00008227389 |
@Anoesj Can you remove your pnpm changes. I want to stay with yarn.
Of course, no problem! I'll come back to this soon.
Actually, do you have specific reasons to stay with Yarn v1? I don't want to start the classic package manager fight here, but it seems to me like Yarn v1 is very 2018-esque, where pnpm is under active development, more performant and getting a lot of traction in the FOSS world. If you do have your reasons, could you add back Yarn v1 yourself? Just remove pnpm-lockfile.yaml and run your Yarn install command.
I want to switch to Yarn Berry soon.
In that case, it sounds like the best way to go forward is for you to proceed with Yarn Berry right now. Just delete pnpm-lock.yaml and run your Yarn install command and commit that to this PR. However, I would argue that pnpm is perfect for this package, but it's up to you.
Why do you think that pnpm will be better in this case?
I did not mean 'better' per se, just a good fit. pnpm is being used more and more in Vue development (Vite, Vue, Nuxt, Pinia all use pnpm), mainly because it's performant, secure, uses less disk space, has great monorepo features and is easy to learn when you're used to npm commands. As this is a Nuxt module, it makes sense to follow their package manager of choice. This can help to attract Nuxt contributors to help maintain and improve this package.
Some resources:
- https://2022.stateofjs.com/en-US/libraries/monorepo-tools/ (pnpm ranked 1st)
- https://2022.stateofjs.com/en-US/awards/ (pnpm ranked 3rd for Most Adopted Technology)
- https://github.com/microsoft/vscode/issues/162803 (found this while looking for discussions on this very topic)
- https://refine.dev/blog/pnpm-vs-npm-and-yarn/ (a bit more info about
pnpm)
pnpm: fast, save disk space (a lot)
pnpm uses symlinks and prevent nested node_modules hells, handle workspaces like a charm, know how to resolve dependencies when updating packages unlike npm and yarn
- https://2022.stateofjs.com/en-US/libraries/monorepo-tools/ (pnpm ranked 1st)
- https://2022.stateofjs.com/en-US/awards/ (pnpm ranked 3rd for Most Adopted Technology)
I was looking at those links 😄
It would be cool if we could finish this PR, we are switching to pnpm. ❤️
@Anoesj
That's great to hear! To finish the PR, it would be nice to have a TypeScript guru review this PR thoroughly. Do you know any people that could help review and improve this where needed?
By providing a collection ID first (i.e. createItems('news', { items: { title: 'Hi' }} instead of createItems({ collection: 'news', items: { title: 'Hi' }}) we can make TypeScript aware of the correct collection types in the remaining parameters. This makes sure we can type check item data in createItems and updateItem.
@Anoesj It is also possible to add type checking without introducing a breaking change:
async function getItems <
C extends keyof Collections,
D extends DirectusItemRequest<Collections>[C]
> (
collection: C | D & { collection: C },
data?: D
) {
collection can be either the DirectusItemRequest object or the collection string.
In the function body you would need to check the type of collection:
let name = collection as string
if (typeof collection === 'object') {
name = collection.collection
data = collection
}
This way you can call getItems with getItems('collection') and still use the old api getItems({ collection: 'collection', params })
Sorry, busy times here, so I haven't gotten around to make any changes regarding backwards compatibility. If anyone else wants to take a shot at it, be my guest!
@Intevel Thanks for this great lib ! Have you planned to work on finalizing this PR ?
@Intevel Thanks for this great lib ! Have you planned to work on finalizing this PR ?
@Anoesj What do you think?