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

Adding a component to extract values from a remote file #2554

Merged
merged 2 commits into from
Sep 29, 2023

Conversation

vcampitelli
Copy link
Contributor

@vcampitelli vcampitelli commented Sep 25, 2023

Instead of hard-coding values from an external file (e.g. kickstart.json), we can now use the <RemoteValue> component with a selector to extract the value from it.

Usage

The syntax for the component (which will cover most cases) is:

import RemoteValue from '../../components/RemoteValue/RemoteValue.astro';

* Your client Id is <code><RemoteValue url="https://some.github.repo/kickstart.json" selector="$.variables.applicationId" /></code>

Props

  • url (required): remote URL to fetch the file from
  • selector (required): parsed-dependent syntax to extract the value from the remote file
  • parser (optional): value from the Parser enum object exported by the component
    • If not defined, the component will use the file extension from the URL
  • defaultValue (optional): default value if we cannot retrieve the element (otherwise, we'll render "not available")
    • This is recommended in case you ever change the remote file and the selector doesn't work anymore.
  • codeRenderer (optional): to render the value inside a <Code> component as described in Rendering inside a code component
  • codeLang (optional): lang attribute to be passed to the <Code> component as described in Rendering inside a code component

Parsers

Currently, we only support JSON files, but the component is ready to support other extensions in the future (e.g. YAML or XML files), so in the future we could have something like this:

import RemoteValue, {Parser} from '../../components/RemoteValue/RemoteValue.astro';

<RemoteValue url="https://some.github.repo/file.yaml"
    parser={Parser.YAML}
    selector="some.yaml.selector.in.the.future"
    />

Selectors

The selector can either be a string or a function.

Selector Strings

When using string, you need to check the specific documentation for the parser we use. As we only have JSON right now, please check jsonpath-plus, which implements an XPath-based syntax.

Selector Functions

When using function, we'll pass the parsed file (e.g. the JSON object) as an argument and the function should return the value.

Selector Examples

So these elements will render the same value:

<RemoteValue url="https://some.github.repo/kickstart.json"
    selector={(element) => element.requests.find(e => e.url === '/api/application/#{applicationId}').body.application.oauthConfiguration.clientSecret}
    />

<RemoteValue url="https://some.github.repo/kickstart.json"
    selector="$.requests.[?(@.url === '/api/application/#{applicationId}')].body.application.oauthConfiguration.clientSecret"
    />

Common rendering scenarios

Rendering inside a <Code> component

Unfortunately, Astro doesn't support passing component directly as props, so it doesn't allow us to do something like <Code code=`CLIENT_SECRET=${clientSecret} some command`}. I tried a couple of different approaches (e.g. using astro's <slot> to render children elements) and ended up with this:

<RemoteValue
    url="https://some.github.repo/kickstart.json"
    selector="$.variables.applicationId"
    codeLang="shell"
    codeRenderer={(value) => `CLIENT_ID=${value} some-command-to-run`} />

This will be converted to:

<Code lang="shell" code="CLIENT_ID=value-extracted-from-file some-command-to-run" />

Rendering inside inline backticks

Use HTML's <code> element instead of backticks:

# This won't work
`<RemoteValue url="..."/>`

# Use this instead
<code><RemoteValue url="..."/></code>

Reusing components

Even though astro caches fetch requests (and we cache the parsed object), you can reuse components like this:

import RemoteValue from '../../components/RemoteValue/RemoteValue.astro';
export const clientId = (<RemoteValue url="https://some.github.repo/kickstart.json" selector="$.variables.applicationId" />);

* Your client Id is <code>{clientId}</code>

@vcampitelli vcampitelli self-assigned this Sep 25, 2023
@mooreds mooreds self-requested a review September 26, 2023 15:00
Copy link
Contributor

@mooreds mooreds left a comment

Choose a reason for hiding this comment

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

LGTM. Tested and it does what it says.

@mooreds
Copy link
Contributor

mooreds commented Sep 28, 2023

Please merge this @vcampitelli !

@vcampitelli vcampitelli merged commit cbe4b02 into master Sep 29, 2023
@vcampitelli vcampitelli deleted the feature/remote-json-code-component branch September 29, 2023 00:52
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.

2 participants