Skip to content

Commit

Permalink
Add cookie chunker methods to ssr (#662)
Browse files Browse the repository at this point in the history
* Add cookie chunker methods and expose them

* Fix chunkCount to get the correct number of chunks
  • Loading branch information
silentworks authored Oct 31, 2023
1 parent f14c13e commit 841fce0
Show file tree
Hide file tree
Showing 9 changed files with 206 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/cool-seas-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@supabase/ssr': patch
---

Add cookie chunker methods and expose them to the SDK
5 changes: 5 additions & 0 deletions .changeset/new-dodos-joke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@supabase/auth-helpers-shared': patch
---

Fix chunkCount to get the correct number of chunks
2 changes: 1 addition & 1 deletion packages/shared/src/chunker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export function createChunks(key: string, value: string, chunkSize?: number): Ch
const re = chunkSize !== undefined ? createChunkRegExp(chunkSize) : MAX_CHUNK_REGEXP;

// check the length of the string to work out if it should be returned or chunked
const chunkCount = Math.ceil(value.length / MAX_CHUNK_SIZE);
const chunkCount = Math.ceil(value.length / (chunkSize ?? MAX_CHUNK_SIZE));

if (chunkCount === 1) {
return [{ name: key, value }];
Expand Down
7 changes: 5 additions & 2 deletions packages/ssr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
],
"scripts": {
"lint": "tsc",
"build": "tsup"
"build": "tsup",
"test": "vitest run",
"test:watch": "vitest"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -41,7 +43,8 @@
"@types/cookie": "^0.5.1",
"@types/ramda": "^0.29.3",
"tsconfig": "workspace:*",
"tsup": "^6.7.0"
"tsup": "^6.7.0",
"vitest": "^0.34.6"
},
"peerDependencies": {
"@supabase/supabase-js": "^2.33.1"
Expand Down
94 changes: 94 additions & 0 deletions packages/ssr/src/utils/chunker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
interface Chunk {
name: string;
value: string;
}

function createChunkRegExp(chunkSize: number) {
return new RegExp('.{1,' + chunkSize + '}', 'g');
}

const MAX_CHUNK_SIZE = 3600;
const MAX_CHUNK_REGEXP = createChunkRegExp(MAX_CHUNK_SIZE);

/**
* create chunks from a string and return an array of object
*/
export function createChunks(key: string, value: string, chunkSize?: number): Chunk[] {
const re = chunkSize !== undefined ? createChunkRegExp(chunkSize) : MAX_CHUNK_REGEXP;

// check the length of the string to work out if it should be returned or chunked
const chunkCount = Math.ceil(value.length / (chunkSize ?? MAX_CHUNK_SIZE));

if (chunkCount === 1) {
return [{ name: key, value }];
}

const chunks: Chunk[] = [];
// split string into a array based on the regex
const values = value.match(re);
values?.forEach((value, i) => {
const name: string = `${key}.${i}`;
chunks.push({ name, value });
});

return chunks;
}

// Get fully constructed chunks
export function combineChunks(
key: string,
retrieveChunk: (name: string) => string | null | undefined = () => {
return null;
}
) {
const value = retrieveChunk(key);

// pkce code verifier
if (key.endsWith('-code-verifier') && value) {
return value;
}

if (value) {
return value;
}

let values: string[] = [];
for (let i = 0; ; i++) {
const chunkName = `${key}.${i}`;
const chunk = retrieveChunk(chunkName);

if (!chunk) {
break;
}

values.push(chunk);
}

return values.length ? values.join('') : null;
}

export function deleteChunks(
key: string,
retrieveChunk: (name: string) => string | null | undefined = () => {
return null;
},
removeChunk: (name: string) => void = () => {}
) {
const value = retrieveChunk(key);

if (value) {
removeChunk(key);
return;
}

for (let i = 0; ; i++) {
const chunkName = `${key}.${i}`;
const chunk = retrieveChunk(chunkName);

if (!chunk) {
break;
}

removeChunk(chunkName);
}
}
1 change: 1 addition & 0 deletions packages/ssr/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './helpers';
export * from './constants';
export * from './chunker';
46 changes: 46 additions & 0 deletions packages/ssr/tests/chunker.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { describe, expect, it } from 'vitest';
import { combineChunks, createChunks } from '../src/utils/chunker';
import { CHUNK_STRING } from './helper';

describe('chunker', () => {
it('should not chunk and return one item', () => {
const chunked = createChunks('my-chunks', 'hello-world');
expect(chunked.length).toBe(1);
});

it('should chunk and return two chunks', () => {
const chunked = createChunks('my-chunks', CHUNK_STRING, 2000);
const combined = combineChunks('my-chunks', (name) => {
let chunk = chunked.find((chunk) => {
return chunk.name === name;
});
return chunk?.value;
});
expect(chunked.length).toBe(2);
expect(combined).toBe(CHUNK_STRING);
});

it('should chunk and return twelve chunks', () => {
const chunked = createChunks('my-chunks', CHUNK_STRING, 320);
const combined = combineChunks('my-chunks', (name) => {
let chunk = chunked.find((chunk) => {
return chunk.name === name;
});
return chunk?.value;
});
expect(chunked.length).toBe(12);
expect(combined).toBe(CHUNK_STRING);
});

it('should chunk and return one hundred and one chunks', () => {
const chunked = createChunks('my-chunks', CHUNK_STRING, 36);
const combined = combineChunks('my-chunks', (name) => {
let chunk = chunked.find((chunk) => {
return chunk.name === name;
});
return chunk?.value;
});
expect(chunked.length).toBe(101);
expect(combined).toBe(CHUNK_STRING);
});
});
2 changes: 2 additions & 0 deletions packages/ssr/tests/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const CHUNK_STRING =
'zDq8KDAdv4PwF3UOp3mnEyx1xY71CaY4ZJdPTG8HpLHy3bCYs1x3vwPXdUqY75d0LYHL8KhxgrKqBEK531igiQNk1KqUKmMsabNlwcaF5E2gXA79vpwlxvi1wecwmKGVig4mJ0dzEEXKNsLgyQCsjKOpI7Nw2gnGAKKFdHle1SJeuFj9PyAHx9stMvQFpRQhoLRt3iI0uFA.axN9TdbRmcyIVYroYWoIVHJCvQceRtCjF8dDpmEqD4PRhvuGPue3fLQITp90RXJ3Fchvz7uhJcyjPWchXFNSKQsxVd02bt1RizkNijBglwZQAWHB8qIBQ2XQ7iRXjWOjbOyOQk6I2tr99FWDOKVD5XElchlu0GgQNsxQoC6Q3twecZKWenvYNAhjoPQZCxzOdg4kFBGrCZzOJp6cIZD8Mu4XCnlZTXzDCqyLPusfUvgzABe87pj8h9seo2yllyq8CtQaGysRE849qcoLRQVeBFSEm6FHvJw3QJla9K25wiBTfxVWr7JzIE7za5IrNQUyHqGnlC577AX1TPrqPWyIMGNs5nxrEHJdUNrHV3PD0iXob7WWsjFFc9HS3m2BSPCn4gnNgfHVkewlf1sYm8C0notbKvBV4MPloXdxEtC1QM79ElTr1VrhHWRT2RewabZYcQuTh4kl2BbZCZ3yjlrJ0Sj2Ndl4pyk95nOU3JaboyPJtAjMDc6625OJFRHL9USACMojBSVOzYhSUk6gV2TYkBjzY4L5KytYDc0ONey8LnXUVLwzZLVVFuiuiXO1WQf7DY0TBttEr1tsApBMYveSR39o73yPeTnVikjRpJtEfqhgwU22afFfiaTqnaRU51WDjW0o7ncHONI9PxhAxKjOwcZzjqnrHu9lN6n2dbRLGArqKyFdRaVETsNRxREJv4E57blQqAgCClSIJvvBWcIvMphjDPixgZFzd2hJbCfo9XfHiw0KK5OgVBGuoV6Z2xYa9PFi9FYtshvswHSUXia05bmBF395M30dyzbBpeVAgnJDroB2EflfrydMTmlk3cgfam3b9cRydTalqzLlRQsYIsUnj244KTKG0gkeeewkqUCEi8coALaVHEJSe4WWVjrUoq2wY2XM8cvXv33OFrxwmkKdGFuXWGdXOyF4pcsUD2DMI75FkGpUaEdkTNjWgn1Y003lSsSRXj6LhAflPzDyn5aIXfkgjLlk4x4pWa7xFpbHlv7QGW5S9G9OPYVjx5gRO1vQW1zzOvzZEHwLe1dZjZ7wZJbhJJwShWV7lQuECXcqdNlYMtuNDvhuKflvZh2vfsLryXlkgPH5VB7ES0MAl1VIqKZFChlUiRbrQHsgRZaFkWAnB1npipKt0kmFuu4H0587aHrsvQBkPCfOYUK0jFbOibpEksiaPdGCw3CL9UCOO2ObzrAJCLbvs5qRbjZ9fhDDS6MVabflCqchwOC2PAeD0B4MRVC2K7zCy7NTSTnnTH9Pu8OXVq1wYqAMbW0cbM8G7hq1CigFdwsMDjDjObveRbeGn9ei38FWrLCTyI2kbIi0oI7jdpg176Y1brt7eOdJ0aIUzQyN8ALP46LPDG2ZC5vPh5Qk0HXIBFg8FRdLCHTWKU6FtOiQKwDTzzNQyjtfMJNko6JQYrlph9eC8nSGmzx2VN5MGOoJrkBpVRNX5eWD0phPls0guTRm3ce81s4FlKG70FqDZVNCbaRtTfc818QgI7xgWmMtDpcnyl0tlTbbdiUBGEHSIJ9TdEtckq2ZtE3bQm2g1OIBcp3SyFMuT26gxPtLUl0X88zv2V99cHmcQ5CHu1ZwAa8EabVyrS69KwGmxkjdhXQGAKGDQRN71dOHiOKGRNUrBjqhtW3uSvVuvlQBg9H5lYAWvnk4q4nCNJpTkV5DG1EfkP91FznHoY5LYVlfsdnWO5KQLHAx14SHT74wMlwYjEkenbUGJL05ZatifLENgxVBLP8k5nZxy77aZ33EgCI9U0cb4KVALcFPWylWCsQahOmUFHiCzH5oEhHIROmme1blTnlw9jdAlXczVIB7TZB4FrWMhdEHj8AnavFnVjvqlneoM9bsDOdmMzzyAmROpHGDXmjr41bmXXAwEXCN2AObGcMNOLuY1RoIISsWVS8UZAvaAOwfT7M69Db5z9bdOEmBhHk05yldK448NyNyPOHh3nFeol02cMZUpNgyz7zAVZACxcHxNOfFj1n3pJ6oXO0NkSclZhTwPmqN7iv3D6LfFvLDFPonBcTFSLStHy8YaGwxSV8YgD2wRqpqJBxvWOIXnxLD7w9E6X5fZE8id3KbRX52yDmsRdBuslAZgfmA3S0HCzDKoKwE6ZErwdbSHDuNXcHArIccYkGCV2cZk1anyz3WMWfNAjtcYr5IPueqPvnl272dUarETDZC1KUXl2f1u8iX0PN2k115V5KdmAYX0dAKZoY1K9JyJn9HDyPiKgg0m5ZvbHlHTuPV8SHDAQfGsbQQEUEjx9qVjPwKwYO3niDj8yRK1FO1R7Cq27sDE3gYNarKoGOCy2HGptxnmI537yUeMMfsAtPUWiz98NKHWTpBEFNZGEXyYI86n60IWmgW5r4QGFbWUnypiJVVLuLwTEP1MF4PQZapkWPDLhN77gIxTXS8xrhKWoe3LZljrybqu27aWIR1SbboOjkR1LJkOoQU0JdZoLGWCjy0n2d0B0k6Ji6sZrSdr7CmyotnopPuTJ4sGfdGfHKRg92bDOZ6qkfM3eQWQulQSH1xNgriwJfoceeBmZCv2SuqbxwAtTL8mk2aeW2mMHPdMZHEEdPBNCl8QXCnRaHh0JiKgotIZ1xd6qKdjkBIScnrZv41B0AB2BbcNIB8OlmIK4UE4cpysMXFByXqv08Z7JzrBcTroHuITUPUWZrq1duCHKKesd6gdfJCeTHvgC3RJg8tY44DG1VrrSWJMj7wZ6vBmLTB5OtXUgxvbzb6GfBwjpTcm3cSrse23Tt8T26FeqgTO5oQWpZsjxRsYjPUVbqNwpKCrJPSWPfOgOAbA1JliLgcdxvaUHtOY3RtOWff6BQuYD5MCtiD4PIymoAwFL3TNLLkNN51VIq0nI3VIRKqHf9fM2y74UzZnNPpWU4Vbaq21i2i40tDzMxyeT67i276AXKPwJvPzSkyLWYayAinV6nYtdyiQY273m5hKlDyYJhwuuZLyDy21Hr1uKObu9CoZNOxNuU3ON54Aoh56AbYxv4EL9C15ZJKTdqbaf2GVPFqHn7CIqv4Od8xfwCUr0N6cP.lww9VHv5CCETYEFj9Q1emgiZI2nXZuvHbyJmIbYgMF9w533oG8ZEsdiKo81LAflQeUHYbbxOXTtroR2bdax0VYgjZ2qg5YeOnekqbgyDXwvmsOMktvg4x7JBJiHjzKK2kSPX0cCAhcU17ydRx19xq1gOUBup1j4kqEBbvKFKt67cfqZhT4kiERgbOt6mIyurSzUPgAhBNiqUJPM3872jVtweoum6mAfSgnG4H1qs2oNZjrbGi6Xv1H5WPALAdNzDwca0evrbbufUCKDX0XO27UTAFh9k4UFf0Dk1pPgKhomuWsfsJAJDvo2ZimmkXrlUo8OfihbpGCLMbEDRpxyIcIGTUQ30WeCyaHo2ds2hs2sh';
60 changes: 47 additions & 13 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 841fce0

Please sign in to comment.