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

Merge context type declarations for wrappers #70

Open
maxakuru opened this issue Sep 30, 2021 · 3 comments
Open

Merge context type declarations for wrappers #70

maxakuru opened this issue Sep 30, 2021 · 3 comments
Labels
enhancement New feature or request question Further information is requested

Comments

@maxakuru
Copy link
Member

Right now using universal in Typescript means you need to manually set main()'s parameter types. This is expected, not much we can do about it, but the pain point is when you're using wrappers that extend the context.

This works great:

import { UniversalContext, Request } from '@adobe/helix-universal';

export function main (req: Request, ctx: UniversalContext) {
  ...
}

This doesn't:

import { UniversalContext, Request } from '@adobe/helix-universal';
import wrap from '@adobe/helix-shared-wrap';
import { logger } from '@adobe/helix-universal-logger';

function _main(req: Request, ctx: UniversalContext) {
  ctx.log.info("woo"); // Type error, ctx.log doesn't exist
}

export const main = wrap(_main).with(logger);

Ignoring the last line which has its own type errors, the context doesn't "know" about the logger wrapper. Workaround could be to import each context and make a custom interface merging them, but that would be repeated every time it's used.

The context APIs seem pretty useful to expose, so I'm proposing a namespace that would be exposed, allowing wrapper functions to extend the context as they need.

Assuming @adobe/helix-universal-logger adds an extension to the namespace like this:

// index.d.ts
declare module '@adobe/helix-universal' {
  namespace HelixUniversal {
    export interface UniversalContext {
      info: (...msgs: any[]) => void;
      // ...
    }
  }
}

TS clients could then use:

import { HelixUniversal, Request } from '@adobe/helix-universal';
import wrap from '@adobe/helix-shared-wrap';
import { logger } from '@adobe/helix-universal-logger';

async function _main(req: Request, ctx: HelixUniversal.UniversalContext) {
  ctx.log.info("woo"); // 👍 
}

export const main = wrap(_main).with(logger);

wdyt @tripodsan @trieloff ?

@maxakuru maxakuru added enhancement New feature or request question Further information is requested labels Sep 30, 2021
@tripodsan
Copy link
Contributor

tripodsan commented Oct 1, 2021

@maxakuru
Copy link
Member Author

maxakuru commented Oct 1, 2021

that's ok for me. but maybe call the namespace just Helix ?

agreed, that makes sense

also see:

since this isn't something a client would wrap, would there be anywhere other than the Admin codebase that context.data is accessible? does Admin's context (or any service's context, I suppose) get forwarded to other services somehow?

we could an index signature of [key: string]: unknown would mean "the service can add any additional key-values without a type error", and if the service wants to strongly type their added types, they can extend with the same module declaration syntax

these seem like wrappers, I can open PRs to add their types

@maxakuru
Copy link
Member Author

maxakuru commented Oct 4, 2021

added in #71
keeping this open as a reminder to add the wrapper types

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants