storageCache.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import { cacheCipher } from '/@/settings/encryptionSetting';
  2. import type { EncryptionParams } from '/@/utils/cipher';
  3. import { AesEncryption } from '/@/utils/cipher';
  4. import { isNullOrUnDef } from '/@/utils/is';
  5. export interface CreateStorageParams extends EncryptionParams {
  6. prefixKey: string;
  7. storage: Storage;
  8. hasEncrypt: boolean;
  9. timeout?: Nullable<number>;
  10. }
  11. export const createStorage = ({
  12. prefixKey = '',
  13. storage = sessionStorage,
  14. key = cacheCipher.key,
  15. iv = cacheCipher.iv,
  16. timeout = null,
  17. hasEncrypt = true,
  18. }: Partial<CreateStorageParams> = {}) => {
  19. if (hasEncrypt && [key.length, iv.length].some((item) => item !== 16)) {
  20. throw new Error('When hasEncrypt is true, the key or iv must be 16 bits!');
  21. }
  22. const encryption = new AesEncryption({ key, iv });
  23. /**
  24. * Cache class
  25. * Construction parameters can be passed into sessionStorage, localStorage,
  26. * @class Cache
  27. * @example
  28. */
  29. const WebStorage = class WebStorage {
  30. private storage: Storage;
  31. private prefixKey?: string;
  32. private encryption: AesEncryption;
  33. private hasEncrypt: boolean;
  34. /**
  35. *
  36. * @param {*} storage
  37. */
  38. constructor() {
  39. this.storage = storage;
  40. this.prefixKey = prefixKey;
  41. this.encryption = encryption;
  42. this.hasEncrypt = hasEncrypt;
  43. }
  44. private getKey(key: string) {
  45. return `${this.prefixKey}${key}`.toUpperCase();
  46. }
  47. /**
  48. * Set cache
  49. * @param {string} key
  50. * @param {*} value
  51. * @param {*} expire Expiration time in seconds
  52. * @memberof Cache
  53. */
  54. set(key: string, value: any, expire: number | null = timeout) {
  55. const stringData = JSON.stringify({
  56. value,
  57. time: Date.now(),
  58. expire: !isNullOrUnDef(expire) ? new Date().getTime() + expire * 1000 : null,
  59. });
  60. const stringifyValue = this.hasEncrypt
  61. ? this.encryption.encryptByAES(stringData)
  62. : stringData;
  63. this.storage.setItem(this.getKey(key), stringifyValue);
  64. }
  65. /**
  66. * Read cache
  67. * @param {string} key
  68. * @param {*} def
  69. * @memberof Cache
  70. */
  71. get(key: string, def: any = null): any {
  72. const val = this.storage.getItem(this.getKey(key));
  73. if (!val) return def;
  74. try {
  75. const decVal = this.hasEncrypt ? this.encryption.decryptByAES(val) : val;
  76. const data = JSON.parse(decVal);
  77. const { value, expire } = data;
  78. if (isNullOrUnDef(expire) || expire >= new Date().getTime()) {
  79. return value;
  80. }
  81. this.remove(key);
  82. } catch (e) {
  83. return def;
  84. }
  85. }
  86. /**
  87. * Delete cache based on key
  88. * @param {string} key
  89. * @memberof Cache
  90. */
  91. remove(key: string) {
  92. this.storage.removeItem(this.getKey(key));
  93. }
  94. /**
  95. * Delete all caches of this instance
  96. */
  97. clear(): void {
  98. this.storage.clear();
  99. }
  100. };
  101. return new WebStorage();
  102. };