1- import { dateToUnix , genRandStr , params , WorkerError } from "../common.js" ;
1+ import { dateToUnix , WorkerError } from "../common.js" ;
22
33export type PasteMetadata = {
4+ schemaVersion : number ,
45 passwd : string ,
56
67 lastModifiedAtUnix : number ,
78 createdAtUnix : number ,
89 willExpireAtUnix : number ,
910
11+ accessCounter : number , // a counter representing how frequent it is accessed, to administration usage
1012 filename ?: string ,
1113}
1214
@@ -19,17 +21,50 @@ export async function getPaste(env: Env, short: string): Promise<PasteWithMetada
1921 let item = await env . PB . getWithMetadata < PasteMetadata > ( short , { type : "arrayBuffer" } ) ;
2022
2123 if ( item . value === null ) {
22- throw new WorkerError ( 404 , `paste of name ' ${ short } ' not found` )
24+ return null
2325 } else if ( item . metadata === null ) {
2426 throw new WorkerError ( 500 , `paste of name '${ short } ' has no metadata` )
2527 } else {
2628 if ( item . metadata . willExpireAtUnix < new Date ( ) . getTime ( ) / 1000 ) {
27- throw new WorkerError ( 404 , `paste of name ' ${ short } ' not found` )
29+ return null
2830 }
31+
32+ // update counter with probability 1%
33+ if ( Math . random ( ) < 0.01 ) {
34+ item . metadata . accessCounter += 1
35+ try {
36+ env . PB . put ( short , item . value , {
37+ metadata : item . metadata ,
38+ expiration : item . metadata . willExpireAtUnix ,
39+ } )
40+ } catch ( e ) {
41+ // ignore rate limit message
42+ if ( ! ( e as Error ) . message . includes ( "KV PUT failed: 429 Too Many Requests" ) ) {
43+ throw e
44+ }
45+ }
46+ }
47+
2948 return { paste : item . value , metadata : item . metadata }
3049 }
3150}
3251
52+ // we separate usage of getPasteMetadata and getPaste to make access metric more reliable
53+ export async function getPasteMetadata ( env : Env , short : string ) : Promise < PasteMetadata | null > {
54+ let item = await env . PB . getWithMetadata < PasteMetadata > ( short , { type : "stream" } ) ;
55+
56+ if ( item . value === null ) {
57+ return null
58+ } else if ( item . metadata === null ) {
59+ throw new WorkerError ( 500 , `paste of name '${ short } ' has no metadata` )
60+ } else {
61+ if ( item . metadata . willExpireAtUnix < new Date ( ) . getTime ( ) / 1000 ) {
62+ return null
63+ }
64+ return item . metadata
65+ }
66+ }
67+
3368export async function updatePaste (
3469 env : Env ,
3570 pasteName : string ,
@@ -41,16 +76,19 @@ export async function updatePaste(
4176 passwd : string ,
4277 filename ?: string ,
4378 } ) {
44- const putOptions : { metadata : PasteMetadata , expirationTtl : number } = {
79+ const expirationUnix = dateToUnix ( options . now ) + options . expirationSeconds
80+ const putOptions : KVNamespacePutOptions = {
4581 metadata : {
82+ schemaVersion : 0 ,
4683 filename : options . filename || originalMetadata . filename ,
4784 passwd : options . passwd ,
4885
4986 lastModifiedAtUnix : dateToUnix ( options . now ) ,
5087 createdAtUnix : originalMetadata . createdAtUnix ,
51- willExpireAtUnix : dateToUnix ( options . now ) + options . expirationSeconds ,
88+ willExpireAtUnix : expirationUnix ,
89+ accessCounter : originalMetadata . accessCounter ,
5290 } ,
53- expirationTtl : options . expirationSeconds ,
91+ expiration : expirationUnix ,
5492 }
5593
5694 await env . PB . put ( pasteName , content , putOptions )
@@ -66,16 +104,19 @@ export async function createPaste(
66104 passwd : string ,
67105 filename ?: string ,
68106 } ) {
69- const putOptions : { metadata : PasteMetadata , expirationTtl : number } = {
107+ const expirationUnix = dateToUnix ( options . now ) + options . expirationSeconds
108+ const putOptions : KVNamespacePutOptions = {
70109 metadata : {
110+ schemaVersion : 0 ,
71111 filename : options . filename ,
72112 passwd : options . passwd ,
73113
74114 lastModifiedAtUnix : dateToUnix ( options . now ) ,
75115 createdAtUnix : dateToUnix ( options . now ) ,
76- willExpireAtUnix : dateToUnix ( options . now ) + options . expirationSeconds ,
116+ willExpireAtUnix : expirationUnix ,
117+ accessCounter : 0 ,
77118 } ,
78- expirationTtl : options . expirationSeconds ,
119+ expiration : expirationUnix ,
79120 }
80121
81122 await env . PB . put ( pasteName , content , putOptions )
0 commit comments