Skip to content

Commit

Permalink
feat: support named deploy-scoped stores (#181)
Browse files Browse the repository at this point in the history
  • Loading branch information
eduardoboucas authored Jul 1, 2024
1 parent a765139 commit 7b24ef8
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 3 deletions.
74 changes: 74 additions & 0 deletions src/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1384,6 +1384,80 @@ describe('Deploy scope', () => {
expect(mockStore.fulfilled).toBeTruthy()
})

test('Returns a named deploy-scoped store if `getDeployStore` receives a string parameter', async () => {
const mockToken = 'some-token'
const mockStoreName = 'my-store'
const mockStore = new MockFetch()
.get({
headers: { authorization: `Bearer ${mockToken}` },
response: new Response(value),
url: `${edgeURL}/${siteID}/deploy:${deployID}:${mockStoreName}/${key}`,
})
.get({
headers: { authorization: `Bearer ${mockToken}` },
response: new Response(value),
url: `${edgeURL}/${siteID}/deploy:${deployID}:${mockStoreName}/${key}`,
})

globalThis.fetch = mockStore.fetch

const context = {
deployID,
edgeURL,
siteID,
token: mockToken,
}

env.NETLIFY_BLOBS_CONTEXT = Buffer.from(JSON.stringify(context)).toString('base64')

const deployStore = getDeployStore(mockStoreName)

const string = await deployStore.get(key)
expect(string).toBe(value)

const stream = await deployStore.get(key, { type: 'stream' })
expect(await streamToString(stream as unknown as NodeJS.ReadableStream)).toBe(value)

expect(mockStore.fulfilled).toBeTruthy()
})

test('Returns a named deploy-scoped store if `getDeployStore` receives an object with a `name` property', async () => {
const mockToken = 'some-token'
const mockStoreName = 'my-store'
const mockStore = new MockFetch()
.get({
headers: { authorization: `Bearer ${mockToken}` },
response: new Response(value),
url: `${edgeURL}/${siteID}/deploy:${deployID}:${mockStoreName}/${key}`,
})
.get({
headers: { authorization: `Bearer ${mockToken}` },
response: new Response(value),
url: `${edgeURL}/${siteID}/deploy:${deployID}:${mockStoreName}/${key}`,
})

globalThis.fetch = mockStore.fetch

const context = {
deployID,
edgeURL,
siteID,
token: mockToken,
}

env.NETLIFY_BLOBS_CONTEXT = Buffer.from(JSON.stringify(context)).toString('base64')

const deployStore = getDeployStore({ name: mockStoreName })

const string = await deployStore.get(key)
expect(string).toBe(value)

const stream = await deployStore.get(key, { type: 'stream' })
expect(await streamToString(stream as unknown as NodeJS.ReadableStream)).toBe(value)

expect(mockStore.fulfilled).toBeTruthy()
})

test('Throws if the deploy ID fails validation', async () => {
const mockToken = 'some-token'
const mockStore = new MockFetch()
Expand Down
9 changes: 8 additions & 1 deletion src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ interface BaseStoreOptions {

interface DeployStoreOptions extends BaseStoreOptions {
deployID: string
name?: string
}

interface NamedStoreOptions extends BaseStoreOptions {
Expand Down Expand Up @@ -74,7 +75,13 @@ export class Store {
if ('deployID' in options) {
Store.validateDeployID(options.deployID)

this.name = DEPLOY_STORE_PREFIX + options.deployID
let name = DEPLOY_STORE_PREFIX + options.deployID

if (options.name) {
name += `:${options.name}`
}

this.name = name
} else if (options.name.startsWith(LEGACY_STORE_INTERNAL_PREFIX)) {
const storeName = options.name.slice(LEGACY_STORE_INTERNAL_PREFIX.length)

Expand Down
6 changes: 4 additions & 2 deletions src/store_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ type ExperimentalRegion =

interface GetDeployStoreOptions extends Partial<ClientOptions> {
deployID?: string
name?: string
experimentalRegion?: ExperimentalRegion
}

/**
* Gets a reference to a deploy-scoped store.
*/
export const getDeployStore = (options: GetDeployStoreOptions = {}): Store => {
export const getDeployStore = (input: GetDeployStoreOptions | string = {}): Store => {
const context = getEnvironmentContext()
const options = typeof input === 'string' ? { name: input } : input
const deployID = options.deployID ?? context.deployID

if (!deployID) {
Expand Down Expand Up @@ -47,7 +49,7 @@ export const getDeployStore = (options: GetDeployStoreOptions = {}): Store => {

const client = new Client(clientOptions)

return new Store({ client, deployID })
return new Store({ client, deployID, name: options.name })
}

interface GetStoreOptions extends Partial<ClientOptions> {
Expand Down

0 comments on commit 7b24ef8

Please sign in to comment.