• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

imRohan / Pantry / 434c2b94e661a9a67f58ec8c5596020ce2924136-PR-224

07 Feb 2026 10:56PM UTC coverage: 97.003% (+0.05%) from 96.949%
434c2b94e661a9a67f58ec8c5596020ce2924136-PR-224

Pull #224

github

web-flow
Merge 9314c971f into 84b962fce
Pull Request #224: Introduce Public Baskets

51 of 55 branches covered (92.73%)

Branch coverage included in aggregate %.

65 of 66 new or added lines in 4 files covered. (98.48%)

305 of 312 relevant lines covered (97.76%)

4.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.23
/src/models/publicBlock.ts
1
import crypto = require('crypto')
1✔
2
import {
1✔
3
  IsNotEmpty,
4
  IsString,
5
  validate,
6
} from 'class-validator'
7

8

9
import { IPublicBlock } from '../interfaces/publicBlock'
10

11
import * as dataStore from '../services/dataStore'
1✔
12
import Block from './block'
1✔
13

14
class PublicBlock {
15

16
  @IsNotEmpty()
17
  @IsString()
18
  private accountUUID: string
1✔
19
  @IsNotEmpty()
20
  @IsString()
21
  private blockName: string
1✔
22
  @IsNotEmpty()
23
  @IsString()
24
  private id: string
1✔
25
  @IsNotEmpty()
26
  @IsString()
27
  private redisKey: string
1✔
28
  public block: Block
29

30

31
  private readonly lifeSpanDays = Number(process.env.BLOCK_LIFESPAN)
4✔
32
  private readonly lifeSpan = Number(86400 * this.lifeSpanDays)
4✔
33

34
  public constructor(accountUUID: string, blockName: string, id: string = null) {
2✔
35
    this.accountUUID = accountUUID
4✔
36
    this.blockName = blockName
4✔
37
    this.id = id ?? this.generateHash()
4✔
38
    this.redisKey = `public_block:${this.id}`
4✔
39
    this.block = null
4✔
40
  }
41

42
  public static async get(id: string): Promise<PublicBlock> {
43
    const _publicBlock = new PublicBlock(null, null, id)
2✔
44
    await _publicBlock.hydrate()
2✔
45
    await _publicBlock.saveToRedis()
1✔
46
    return _publicBlock
1✔
47
  }
48

49
  public async store(): Promise<string> {
50
    const _errors = await validate(this)
2✔
51
    if (_errors.length > 0) {
2!
NEW
52
      throw new Error(`Validation failed: ${_errors}`)
×
53
    }
54

55
    await this.refreshBlock()
2✔
56
    await this.saveToRedis()
1✔
57
    return this.id
1✔
58
  }
59

60
  private async saveToRedis(): Promise<void> {
61
    const _stringifiedPublicBlock = this.generateRedisPayload()
2✔
62
    await dataStore.set(this.redisKey, _stringifiedPublicBlock, this.lifeSpan)
2✔
63
  }
64

65
  private async hydrate(): Promise<void> {
66
    const _stringifiedPublicBlock = await dataStore.get(this.redisKey)
2✔
67

68
    if (!_stringifiedPublicBlock) {
2✔
69
      throw new Error(`${this.id} does not exist`)
1✔
70
    }
71
    const _publicBlockContents: IPublicBlock = JSON.parse(_stringifiedPublicBlock)
1✔
72
    const { accountUUID, blockName } = _publicBlockContents
1✔
73

74
    this.accountUUID = accountUUID
1✔
75
    this.blockName = blockName
1✔
76
    await this.refreshBlock()
1✔
77
  }
78

79
  private async refreshBlock(): Promise<void> {
80
    try {
3✔
81
      this.block = await Block.get(this.accountUUID, this.blockName)
3✔
82
    } catch {
83
      throw new Error('basket not found, please contact the Pantry owner')
1✔
84
    }
85
  }
86

87
  private generateHash(): string {
88
    const _key = `${this.accountUUID}${this.blockName}`
2✔
89
    const _hash = crypto.createHash('md5').update(_key).digest('hex')
2✔
90
    return _hash
2✔
91
  }
92

93
  private generateRedisPayload(): string {
94
    const _publicBlock: IPublicBlock = {
2✔
95
      accountUUID: this.accountUUID,
96
      blockName: this.blockName,
97
      id: this.id,
98
    }
99
    return JSON.stringify(_publicBlock)
2✔
100
  }
101
}
102

103
export default PublicBlock
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc