prismatic-io / embedded

Prismatic's library for embedding Prismatic.io into your application.
MIT License
24 stars 3 forks source link

Bug: it's impossible to call "prismatic.init()" from outside of the package in TypeScript #5

Closed Stalinko closed 1 year ago

Stalinko commented 1 year ago

Our app is written in TypeScript. That's why we installed this package via the recommended npm-way.

And this is where I've got into troubles:

import prismatic from '@prismatic-io/embedded';
const PRISMATIC_MARKETPLACE_CONFIGURATION = {
  theme: 'LIGHT',
};
prismatic.init(PRISMATIC_MARKETPLACE_CONFIGURATION);

This simple script is impossible because prismatic.init() function requires the argument of InitProps type and I get incompatible types error. But this type is not exported from outside of the package, hence I can't import it and use it. That's why I basically can't call the init-method if I develop in TypeScript. I was able to bypass the issue via "ts-ignore" but that's nasty.

Hopefully you can fix this issue and export all the types which are necessary to use your API methods. This is not the case only for init().

Stalinko commented 1 year ago

UPD Maybe it's important - we're using your package in TS 3.9 environment. IDK if it changes anything.

I had to make a fork of your repo to make it work in TS 3.9 (https://github.com/lumiform/prismatic-embedded/tree/ts3-support) but this fork almost doesn't differ from your code.

bkegley commented 1 year ago

@Stalinko Thanks for the report. I believe the issue is that TypeScript infers the value of PRISMATIC_MARKETPLACE_CONFIGURATION.theme as string instead of the string literal that you're hoping. To tell TS that you want it to use the string literal you'll need to add as const. It also works if you define the configuration inline as TS is expecting those enum values.

Both the following should get it to compile without the @ts--ignore:

import prismatic from '@prismatic-io/embedded';
const PRISMATIC_MARKETPLACE_CONFIGURATION = {
  theme: 'LIGHT' as const,
};
prismatic.init(PRISMATIC_MARKETPLACE_CONFIGURATION);
import prismatic from '@prismatic-io/embedded';

prismatic.init({
  theme: 'LIGHT'
});
Stalinko commented 1 year ago

hey @bkegley

very smart workaround, I didn't know it could be done with "as const" casting, but it really works.

However we already made a fork which exports that type) and solved the issue this way.

Probably you should address this case in your docs if you aren't going to export the types.

jasoncomes commented 1 year ago

Hey @Stalinko - When you have a chance, could you let us know if these types are sufficient enough for your setup. Types include, phases, translation, options, theme, and configuration screens.

https://github.com/prismatic-io/embedded/pull/9

Stalinko commented 1 year ago

hi @jasoncomes

looks good. I see you still don't export neither InitProps nor State, but you export Theme. I guess it would work if I declare the config like this:

const PRISMATIC_MARKETPLACE_CONFIGURATION = {
  theme: 'LIGHT' as Theme,
};

not super convenient, especially if we use not only "theme" property, but workable.

jasoncomes commented 1 year ago

@Stalinko so State is internal to embedded, think that might not necessarily need to be exported. However, I do like that idea of exposing each embedded method props interface, in addition to their granular types if needed phases, translation, options, theme, and configuration screens. I've added these, hopefully this helps out:

InitProps -> init(options: InitProps)
ShowMarketplaceProps -> showMarketplace(options: ShowMarketplaceProps)
ShowLogsProps -> showLogs(options: ShowLogsProps)
ShowIntegrationsProps -> showIntegrations(options: ShowIntegrationsProps)
ShowDesignerProps -> showDesigner(options: ShowDesignerProps)
ShowComponentsProps -> showComponents(options: ShowComponentsProps)
ShowComponentProps -> showComponent(options: ShowComponentProps)
SetConfigVarsProps -> setConfigVars(options: SetConfigVarsProps)
GraphqlRequestProps -> graphqlRequest(options: GraphqlRequestProps)
ConfigureInstanceProps -> configureInstance(options: ConfigureInstanceProps)
AuthenticateProps -> authenticate(options: AuthenticateProps)

https://github.com/prismatic-io/embedded/pull/9/commits/97330ee7c67544e84fe23b559951ace000c5ee11

Stalinko commented 1 year ago

that looks awesome @jasoncomes this is exactly what I was hinting about

and yes it solves the problem mentioned in this ticket thank you