Skip to content

Commit

Permalink
Merge a17385c into b6c0fe4
Browse files Browse the repository at this point in the history
  • Loading branch information
chregu committed Feb 26, 2023
2 parents b6c0fe4 + a17385c commit 944dc97
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 36 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 3.13.0 - [26-02-2023]

- Added variables support to `rokka.render.getUrlFromUrl` and `rokka.render.getUrl`

# 3.12.0 - [26-02-2023]

- Added `rokka.render.getUrlFromUrl(rokkaUrl, stack, options)` to change a rokka render URL string to other stacks/options.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ Get URL for rendering an image.
rokka.render.getUrl('myorg', 'c421f4e8cefe0fd3aab22832f51e85bacda0a47a', 'png', 'mystack')
```

#### rokka.render.getUrlFromUrl(rokkaUrl, [stack], options) → string
#### rokka.render.getUrlFromUrl(rokkaUrl, stack, options) → string

Get URL for rendering an image from a rokka render URL.

Expand Down
121 changes: 87 additions & 34 deletions src/apis/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,41 @@ export interface UrlComponents {
}

type GetUrlComponentsType = (urlObject: URL) => UrlComponents | false

type WithRequiredProperty<Type, Key extends keyof Type> = Type & {
[Property in Key]-?: Type[Property]
}
interface ImagesByAlbumOptions {
favorites?: boolean
}

interface GetUrlFromUrlOptions {
stackoptions?: StackOptions
filename?: string
format?: string
variables?: VariablesInterface
removeSafeUrlFromQuery?: boolean
clearVariables?: boolean
}

interface GetUrlOptions {
filename?: string
stackoptions?: StackOptions
variables?: VariablesInterface
removeSafeUrlFromQuery?: boolean
}

export interface Render {
getUrl(
organization: string,
hash: string,
format: string,
stack: string | object,
options?: { filename?: string; stackoptions?: StackOptions },
options?: GetUrlOptions,
): string
getUrlFromUrl(
rokkaUrl: string,
stack: string | object,
options?: {
stackoptions?: StackOptions
filename?: string
format?: string
},
options?: GetUrlFromUrlOptions,
): string
imagesByAlbum: (
organization: string,
Expand All @@ -72,10 +86,13 @@ export interface Render {
getUrlComponents: GetUrlComponentsType
}

interface StackComponents {
variables: VariablesInterface
stackString: string
}

// currently only gets stack variables
const getStackComponents = (
stack: string,
): { variables: VariablesInterface; stackString: string } => {
const getStackComponents = (stack: string): StackComponents => {
// split by slashes
// TODO: if we parse operations and options, only the stuff before the first / is a dynamic operation
// otherwise it's just new options for that operation
Expand Down Expand Up @@ -163,6 +180,21 @@ const stringifyBool = (value: string | boolean | number): string | number => {
}
return value
}

const getStackVariables = (
urlComponents: UrlComponents,
urlObject: URL,
stackComponents: StackComponents,
variables: VariablesInterface,
) => {
const variablesFromPath = stackComponents.variables
const vQuery = urlObject.searchParams.get('v')
const vQueryParsed: VariablesInterface =
vQuery !== null ? JSON.parse(vQuery) : {}

return Object.assign(variablesFromPath, vQueryParsed, variables)
}

/**
* ### Render
*
Expand All @@ -181,7 +213,7 @@ export default (state: State): { render: Render } => {
* @param {string} hash image hash
* @param {string} format image format: `jpg`, `png` or `gif`
* @param {string|array} [stack] optional stack name or an array of stack operation objects
* @param {{filename:string|undefined, stackoptions: StackOptions|undefined }} options Optional. filename: Adds the filename to the URL, stackoptions: Adds stackoptions to the URL
* @param {{filename:string|undefined, stackoptions: StackOptions|undefined, variables: VariablesInterface|undefined, clearVariables:boolean|undefined, removeSafeUrlFromQuery: boolean|undefined}} options Optional. filename: Adds the filename to the URL, stackoptions: Adds stackoptions to the URL
* @return {string}
*/
getUrl: (organization, hash, format, stack, options) => {
Expand All @@ -201,7 +233,16 @@ export default (state: State): { render: Render } => {
if (options?.filename) {
hash = `${hash}/${options.filename}`
}
return `${host}/${stackString}/${hash}.${format}`

const url = `${host}/${stackString}/${hash}.${format}`
if (options?.variables && Object.keys(options.variables).length > 0) {
return render.addStackVariables(
url,
options.variables,
options.removeSafeUrlFromQuery || false,
)
}
return url
},

/**
Expand All @@ -212,35 +253,49 @@ export default (state: State): { render: Render } => {
* ```
*
* @param {string} rokkaUrl rokka render URL
* @param {string|array} [stack] optional stack name or an array of stack operation objects
* @param {{filename:string|undefined, stackoptions: StackOptions|undefined, format: string|undefined }} options Optional. filename: Adds or changes the filename to the URL, stackoptions: Adds stackoptions to the URL, format: Changes the format
* @param {string|array} stack stack name or an array of stack operation objects
* @param {{filename:string|undefined, stackoptions: StackOptions|undefined, format: string|undefined, variables: VariablesInterface|undefined, clearVariables:boolean|undefined, removeSafeUrlFromQuery: boolean|undefined}} options Optional. filename: Adds or changes the filename to the URL, stackoptions: Adds stackoptions to the URL, format: Changes the format
* @return {string}
*/
getUrlFromUrl: (
rokkaUrl: string,
stack: string | object,
options: {
stackoptions?: StackOptions
filename?: string
format?: string
} = {},
options: GetUrlFromUrlOptions = {},
): string => {
const url = new URL(rokkaUrl)

const components = render.getUrlComponents(url)
if (!components) {
return rokkaUrl
}
const resolvedOptions: {
stackoptions: StackOptions
filename?: string
format: string
} = {

const resolvedOptions: WithRequiredProperty<
GetUrlFromUrlOptions,
| 'stackoptions'
| 'format'
| 'removeSafeUrlFromQuery'
| 'clearVariables'
| 'variables'
> = {
stackoptions: {},
filename: components.filename,
format: components.format,
removeSafeUrlFromQuery: false,
clearVariables: true,
variables: {},
...options,
}
let variables = resolvedOptions.variables
if (!resolvedOptions.clearVariables) {
const stackComponents = getStackComponents(components.stack)
variables = getStackVariables(
components,
url,
stackComponents,
resolvedOptions.variables,
)
}

const renderHostUrl = new URL(state.renderHost)
const replaceHost = renderHostUrl.host.replace('{organization}', '')
return render.getUrl(
Expand All @@ -251,6 +306,8 @@ export default (state: State): { render: Render } => {
{
filename: resolvedOptions.filename,
stackoptions: resolvedOptions.stackoptions,
variables: variables,
removeSafeUrlFromQuery: resolvedOptions.removeSafeUrlFromQuery,
},
)
},
Expand Down Expand Up @@ -347,7 +404,7 @@ export default (state: State): { render: Render } => {
*
* @param {string} url The url the stack variables are added to
* @param {object} variables The variables to add
* @param {bool} [removeSafeUrlFromQuery=false] If true, removes some safe characters from the query
* @param {boolean} [removeSafeUrlFromQuery=false] If true, removes some safe characters from the query
* @return {string}
*/
addStackVariables: (
Expand All @@ -365,18 +422,14 @@ export default (state: State): { render: Render } => {

const stackComponents = getStackComponents(urlComponents.stack)

const variablesFromPath = stackComponents.variables
const vQuery = urlObject.searchParams.get('v')
const vQueryParsed: VariablesInterface =
vQuery !== null ? JSON.parse(vQuery) : {}

const returnVariables = Object.assign(
variablesFromPath,
vQueryParsed,
const returnVariables = getStackVariables(
urlComponents,
urlObject,
stackComponents,
variables,
)

// put variales into url string or v parameter, depending on characters in it
// put variables into url string or v parameter, depending on characters in it
if (Object.keys(returnVariables).length > 0) {
const jsonVariables: VariablesInterface = {}
let urlVariables = ''
Expand Down
43 changes: 42 additions & 1 deletion tests/apis/render.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,49 @@ describe('render', () => {
expect(url3).toBe(
'https://myorg.rokka.io/dynamic/resize-width-200/o-af-1/c421f4e8cefe0fd3aab22832f51e85bacda0a47a/bar.jpg',
)
})
const url4 = rokka().render.getUrlFromUrl(
'https://myorg.rokka.io/dynamic/resize-width-100/v-foo-bar/c421f4e8cefe0fd3aab22832f51e85bacda0a47a/foo.jpg?v={"baz":"hello-world"}',
'newStack',
{
removeSafeUrlFromQuery: true,
clearVariables: false,
variables: { hi: 'ho' },
},
)
expect(url4).toBe(
'https://myorg.rokka.io/newStack/v-foo-bar-hi-ho/c421f4e8cefe0fd3aab22832f51e85bacda0a47a/foo.jpg?v={"baz":"hello-world"}',
)

const url5 = rokka().render.getUrlFromUrl(
'https://myorg.rokka.io/dynamic/resize-width-100/v-foo-bar/c421f4e8cefe0fd3aab22832f51e85bacda0a47a/foo.jpg?v={"baz":"hello-world"}',
'newStack',
{
removeSafeUrlFromQuery: true,
variables: { hi: 'ho' },
},
)
expect(url5).toBe(
'https://myorg.rokka.io/newStack/v-hi-ho/c421f4e8cefe0fd3aab22832f51e85bacda0a47a/foo.jpg',
)
})
it('render.addStackVariables', async () => {
const url = rokka().render.addStackVariables(
'https://myorg.rokka.io/dynamic/resize-width-100/c421f4e8cefe0fd3aab22832f51e85bacda0a47a/foo.jpg',
{ foo: 'bar', baz: 'hello-world' },
true,
)
expect(url).toBe(
'https://myorg.rokka.io/dynamic/resize-width-100/v-foo-bar/c421f4e8cefe0fd3aab22832f51e85bacda0a47a/foo.jpg?v={"baz":"hello-world"}',
)
const url2 = rokka().render.addStackVariables(
'https://myorg.rokka.io/dynamic/resize-width-100/v-foo-bar/c421f4e8cefe0fd3aab22832f51e85bacda0a47a/foo.jpg?v={"baz":"hello-world"}',
{ lal: 'lol' },
true,
)
expect(url2).toBe(
'https://myorg.rokka.io/dynamic/resize-width-100/v-foo-bar-lal-lol/c421f4e8cefe0fd3aab22832f51e85bacda0a47a/foo.jpg?v={"baz":"hello-world"}',
)
})
it('render.getUrl using custom operations', async () => {
const rka = rokka()
const operations = [
Expand Down

0 comments on commit 944dc97

Please sign in to comment.