Skip to content

Rename wasp-config userSpec to tsAppSpec for clarity and consistency #2737

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

Open
FranjoMindek opened this issue May 12, 2025 · 7 comments · May be fixed by #2762
Open

Rename wasp-config userSpec to tsAppSpec for clarity and consistency #2737

FranjoMindek opened this issue May 12, 2025 · 7 comments · May be fixed by #2762
Assignees
Labels
refactoring Keeping that code clean!

Comments

@FranjoMindek
Copy link
Contributor

We've had an discussion around the current naming of userSpec, #2690 (comment). The end conses was that the name is misleading and potentially confusing.

Problems with userSpec:

  • The word “user” is ambiguous in the context of Wasp. In most places, “user” refers to the auth user or the app user, not the Wasp developer.
  • There’s nothing else in the codebase using “user” to refer to Wasp developers, so this usage is inconsistent.
  • The name doesn’t clearly convey the role of the structure — it’s not intuitive that this is a TypeScript-friendly representation of AppSpec.

Agreed direction:

  • Rename userSpectsAppSpec (short for TypeScript App Spec), as that is what it effectively is: a representation of AppSpec tailored for usage in TypeScript.
  • Keep appSpec as-is. It is the canonical form and should not be renamed to something like hsAppSpec, since its connection to Haskell is an implementation detail.
@FranjoMindek
Copy link
Contributor Author

As quoted from another PR:

I think this is great to ponder together with #2737. We have a pattern of matching UserApi.XYZConfig to AppSpec.XYZ

If we want to follow that, then UserApi.App is confusingly named and should be changed. Problem is that UserApi.App is the most imprtant type, as it's the class which is exported for user to use.

It could be a WaspApp or something similar?

const waspApp = new WaspApp();

But this requires a lot of thought, since this type is very important. Should be a group thing.

It might be worthwhile to look into renaming the UserApi.App

@Martinsos Martinsos added the refactoring Keeping that code clean! label May 14, 2025
@FranjoMindek FranjoMindek self-assigned this May 14, 2025
@sodic
Copy link
Contributor

sodic commented May 15, 2025

It might be worthwhile to look into renaming the UserApi.App

The only thing we should ask, without considering anything else, is What do we want the user to see?

After we decide on that, we should adapt our internal code to work with it. We're the ones who should pay the price for good user DX.

It's generally never desirable do design the public API to make it easier on ourselves. We sometimes make exceptions when the approaches greatly differ in complexity, but that's not the case here.
Btw the price for good DX in this case is pretty cheap, we can easily reexport the class under a different name.

What do we want the user to see?

For me, it's new App().

@FranjoMindek
Copy link
Contributor Author

FranjoMindek commented May 16, 2025

Should be user DX first, I agree.
I know that @Martinsos got really confused around having AppSpec.App, UserApi.App and UserApi.AppConfig, hence we brought it up.

If our DX is suffering here we can maybe try different module system:

  1. appSpec.ts -> AppSpec.App
  2. userApi.ts -> UserApi.App
  3. tsAppSpec.ts (a bit weird since it's also part of user api) -> TSAppSpec.AppConfig

In other words, extract ts app spec stuff out of the userApi.ts into its own module.
Let userApi.ts handle user facing exports only.

@sodic
Copy link
Contributor

sodic commented May 16, 2025

The confusion comes from the userApi exporting both App (the class for users) and AppConfig (a TS spec equivalent of AppSpec.App). When mapUserSpecToAppSpecDecls imports everything from userApi.ts under the User namespace, it has access to both User.App and User.AppConfig.

The main problem:

  • The general mapping pattern is: User.FooConfig maps to AppSpec.Foo.
  • Even though User.AppConfig and AppSpec.App follow this pattern, since the User scope also contains User.App, it's easy to mistakenly think that User.App (instead of User.AppConfig) is supposed to map to AppSpec.App.

We can solve this by internally separating the User configs from the App class. The module mapUserSpecToAppSpecDecls then doesn't have to import the App class and the confusion is gone.

At the same time, I don't want to lose information that the App is a part of user (public) API.

So here's an idea:

src/
  userApi/
    App.ts // App class
    tsAppSpec.ts // Everything else from current userApi.ts, types exposed to the user
  index.ts // Reexports everything from userApi/
  mapUserSpecToAppSpecDecls.ts // Imports only `userApi/tsAppSpec.ts`
  appSpec.ts // Remains unchanged

@FranjoMindek
Copy link
Contributor Author

I agree with the given direction.
The change above + rename should fix most of our own DX issues, while allowing us to keep users DX clean.

@FranjoMindek
Copy link
Contributor Author

@Martinsos would like if we could rename userApi folder not to include "user" in name. I know you had publicApi idea? @sodic

@sodic
Copy link
Contributor

sodic commented May 16, 2025

That works for me. User is an overloaded term in our domain, and public is clear.

@FranjoMindek FranjoMindek linked a pull request May 16, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactoring Keeping that code clean!
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants