Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add @pinia-colada/sdk plugin #1680

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

josh-hemphill
Copy link

@josh-hemphill josh-hemphill commented Feb 7, 2025

There's some room for improvement, and people may want a different sdk style or abstracted, but I thought this was a good starting point to share and get some feedback on.

Right now it tries to detect whether to wrap endpoints in createQuery or createMutation based on first overrides if they exist, then if it's a GET or DELETE endpoint it'll assume createQuery, and finally if there's no body schema it will fall back to createQuery; there's OpenAPI extension that seems like it'd be a good indicator (x-readonly), but the extensions don't seem to be available yet, so I just commented that out with a ToDo.

Maybe closes #1242
closes #1159

Copy link

stackblitz bot commented Feb 7, 2025

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

Copy link

changeset-bot bot commented Feb 7, 2025

⚠️ No Changeset found

Latest commit: 7481efa

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link

vercel bot commented Feb 7, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
hey-api-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 7, 2025 0:04am

Copy link
Member

@mrlubos mrlubos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@josh-hemphill this is amazing! Let's figure out the details, but I'll be more than happy to merge this. I sent you a request on LinkedIn if you'd like to connect and talk about your experience writing this plugin + the details above

export const defaultConfig: Plugin.Config<Config> = {
_dependencies: ['@hey-api/typescript'],
_handler: handler,
exportFromIndex: true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not export by default just yet since we can't guarantee the build won't crash due to naming conflicts. Let people select this manually if they're sure their build will pass

_dependencies: ['@hey-api/typescript'],
_handler: handler,
exportFromIndex: true,
name: '@pinia-colada/sdk',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the name consistent with the underlying library, i.e. @pinia/colada. Unless you had a different reason for naming it this way?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured it was going to take more than one plugin to cover different implementations of @pinia/colada and Pinia itself wouldn't really have anything to do with this library. There's also Vue Data-Loaders that can be integrated for endpoints on top of the Pinia Colada SDK, but would require a much more complex interface, but still massively benefit as an openapi-ts plugin. Maybe a different directory structure would make sense, but the dependent relationship between implementations/plugins would be nice have communicated with the directory structure.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you link me to the docs or examples for data loaders integration with Pinia Colada? My impression is you'd still be installing a single package (@pinia/colada) so it makes sense to serve it with a single plugin

Copy link
Author

@josh-hemphill josh-hemphill Feb 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://uvr.esm.is/data-loaders/
https://uvr.esm.is/data-loaders/colada/
I think the initial implementation was part of Pinia Colada, but it's dependent on plugging into the Vue component mounting through the router, so it looks like it's more agnostic provided through the router repo now and "can" be used without Pinia Colada but I think that's still where the first-class support is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah so this is a separate plugin/workflow. I could be convinced there to have a separate plugin for that approach, but I stand behind making the core plugin match @pinia/colada in naming, that makes it easier for everyone to discover and use!

_handler: handler,
exportFromIndex: true,
name: '@pinia-colada/sdk',
output: 'queries',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file would then also be named colada if you agree with the change above. We might allow users to rename it one day, but for now I'd prefer consistency over customisation

* Group queries by tag into separate files?
* @default false
*/
groupByTag?: boolean;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain the reasoning behind offering this functionality?

Copy link
Author

@josh-hemphill josh-hemphill Feb 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It a preference that wasn't available with the current sdk plugin. It's very Vue in style though; it allows for a decent amount of lazy-loading and/or treeshaking if you're following the standard Vue import patterns, just importing for the contexts you need in individual Vue SFC files.
You can still import the root index file to get everything in one go, but can progressively add narrower import contexts to components to cut down on bundled component sizes.
And with Vite auto-import and type caching, a lot of the context narrowing can happen behind the scenes at build time if it has separate files to work with

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the context! I'd like to see this in snapshot tests, it will be way easier to reason through it. We will most likely want to add this to SDKs too, it's just a matter of priority

/**
* Hooks to customize query/mutation generation
*/
hooks?: QueryHooks;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question here as above

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lessons learned from trying to get things working with the old library, having even just some basic hooks available makes things a hundred times easier if you some funky endpoints and need to filter/exclude or translate some properties to something the this lib will understand (sometimes you just have one endpoint you need to edit on-read), it's not always canonical OpenAPI stuff that a PR could be made for. (Just trying to get a bunch people to export OpenAPI specs when they are close to retirement and don't want to deal with something new is enough without trying to convince them to adhere to standards for things are supposed work or be labeled 😅🙃)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same reply as above. We will most likely want to offer some consistency with these APIs as this requirement comes up with other plugins too and I've been purposefully avoiding it for now

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@josh-hemphill I'd prefer to flatten these options so instead of plugin.hooks.getQueryKey() it would be simply plugin.getQueryKey(). I'm not ready to define what a Hooks API is and this approach would remove that problem. I am working on other plugins and facing the same questions there. Thoughts?

Copy link
Author

@josh-hemphill josh-hemphill Feb 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought I was removing the hooks?
So add them at the root level? Do you mind if I try and find a name that better indicates it's a hook?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need since they're clearly useful for you! And I'm sure sooner or later someone else would want to customise these options too.

I will have a separate question about getQueryKey() later, but will wait for snapshots before going there

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The on* ones seem fine, but I'm thinking renaming the others to resloveQ* or something

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to see added some snapshot tests so we can see the final output + typecheck in CI

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I add a scenario to the openapi-ts\test\plugins.test.ts or add file snapshots to this directory, or both? Since I'm not sure the scenarios are specifically covering the behavior of this plugin, though not sure how much that matters.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please. Drop a few tests there running through various permutations of these configs, whatever you think is necessary to cover, and then pnpm openapi-ts test:update. I will likely need to refactor this again in the future, but it does the job for now

@mrlubos
Copy link
Member

mrlubos commented Feb 7, 2025

@josh-hemphill for the failing CI, you need to register this plugin in https://github.com/hey-api/openapi-ts/blob/2dc380eabc17c723654beb04ecd7bce6d33d3b49/packages/openapi-ts/src/plugins/index.ts and add it to types in https://github.com/hey-api/openapi-ts/blob/2dc380eabc17c723654beb04ecd7bce6d33d3b49/packages/openapi-ts/src/plugins/types.d.ts. I assume you've been importing it manually up to this point? This will make it so that it's readily available in the config.

@mrlubos
Copy link
Member

mrlubos commented Feb 7, 2025

Later, I will write documentation for the plugin once we've got the API finalised and test snapshots. I will also ask you to add pnpm changeset so you get the credit in the release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pinia Colada plugin Vue client / vue data loader plugin
2 participants