@adonisjs/cache 1.0.0-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md ADDED
@@ -0,0 +1,9 @@
1
+ # The MIT License
2
+
3
+ Copyright (c) 2023
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # @adonisjs/cache
2
+
3
+ <br />
4
+
5
+ [![gh-workflow-image]][gh-workflow-url] [![npm-image]][npm-url] ![][typescript-image] [![license-image]][license-url]
6
+
7
+ ## Introduction
8
+ Cache module for AdonisJS built on top of BentoCache. Support multiples drivers, File, In-Memory, Redis, SQLs databases and more.
9
+
10
+ ## Official Documentation
11
+ The documentation is available on the [AdonisJS website](https://docs.adonisjs.com/guides/cache/introduction).
12
+
13
+ ## Contributing
14
+ One of the primary goals of AdonisJS is to have a vibrant community of users and contributors who believes in the principles of the framework.
15
+
16
+ We encourage you to read the [contribution guide](https://github.com/adonisjs/.github/blob/main/docs/CONTRIBUTING.md) before contributing to the framework.
17
+
18
+ ## Code of Conduct
19
+ In order to ensure that the AdonisJS community is welcoming to all, please review and abide by the [Code of Conduct](https://github.com/adonisjs/.github/blob/main/docs/CODE_OF_CONDUCT.md).
20
+
21
+ ## License
22
+ AdonisJS Lucid is open-sourced software licensed under the [MIT license](LICENSE.md).
23
+
24
+ [gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/adonisjs/cache/test.yml?style=for-the-badge
25
+ [gh-workflow-url]: https://github.com/adonisjs/cache/actions/workflows/test.yml "Github action"
26
+
27
+ [npm-image]: https://img.shields.io/npm/v/@adonisjs/cache/latest.svg?style=for-the-badge&logo=npm
28
+ [npm-url]: https://www.npmjs.com/package/@adonisjs/cache/v/latest "npm"
29
+
30
+ [typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
31
+
32
+ [license-url]: LICENSE.md
33
+ [license-image]: https://img.shields.io/github/license/adonisjs/cache?style=for-the-badge
@@ -0,0 +1,17 @@
1
+ import { BaseCommand } from '@adonisjs/core/ace';
2
+ import { CommandOptions } from '@adonisjs/core/types/ace';
3
+ export default class CacheClear extends BaseCommand {
4
+ #private;
5
+ static commandName: string;
6
+ static description: string;
7
+ static options: CommandOptions;
8
+ /**
9
+ * Choose a custom cache store to clear. Otherwise, we use the
10
+ * default one
11
+ */
12
+ store: string;
13
+ /**
14
+ * Handle command
15
+ */
16
+ run(): Promise<void>;
17
+ }
@@ -0,0 +1,77 @@
1
+ /*
2
+ * @adonisjs/cache
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
10
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
11
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
12
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
13
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
14
+ };
15
+ import { BaseCommand, flags } from '@adonisjs/core/ace';
16
+ export default class CacheClear extends BaseCommand {
17
+ static commandName = 'cache:clear';
18
+ static description = 'Clear the application cache';
19
+ static options = {
20
+ startApp: true,
21
+ };
22
+ /**
23
+ * Prompts to take consent when clearing the cache in production
24
+ */
25
+ async #takeProductionConsent() {
26
+ const question = 'You are in production environment. Want to continue clearing the cache?';
27
+ try {
28
+ return await this.prompt.confirm(question);
29
+ }
30
+ catch (error) {
31
+ return false;
32
+ }
33
+ }
34
+ /**
35
+ * Check if the given cache exist
36
+ */
37
+ #cacheExists(cache, cacheName) {
38
+ try {
39
+ cache.use(cacheName);
40
+ return true;
41
+ }
42
+ catch (error) {
43
+ return false;
44
+ }
45
+ }
46
+ /**
47
+ * Handle command
48
+ */
49
+ async run() {
50
+ const cache = await this.app.container.make('cache');
51
+ this.store = this.store || cache.defaultStoreName;
52
+ /**
53
+ * Exit if cache store doesn't exists
54
+ */
55
+ if (!this.#cacheExists(cache, this.store)) {
56
+ this.logger.error(`"${this.store}" is not a valid cache store. Double check config/cache.ts file`);
57
+ this.exitCode = 1;
58
+ return;
59
+ }
60
+ /**
61
+ * Take consent when clearing the cache in production
62
+ */
63
+ if (this.app.inProduction) {
64
+ const shouldClear = await this.#takeProductionConsent();
65
+ if (!shouldClear)
66
+ return;
67
+ }
68
+ /**
69
+ * Finally clear the cache
70
+ */
71
+ await cache.use(this.store).clear();
72
+ this.logger.success(`Cleared "${this.store}" cache successfully`);
73
+ }
74
+ }
75
+ __decorate([
76
+ flags.string({ description: 'Define a custom cache store to clear', alias: 's' })
77
+ ], CacheClear.prototype, "store", void 0);
@@ -0,0 +1 @@
1
+ {"commands":[{"commandName":"cache:clear","description":"Clear the application cache","help":"","namespace":"cache","aliases":[],"flags":[{"name":"store","flagName":"store","required":false,"type":"string","description":"Define a custom cache store to clear","alias":"s"}],"args":[],"options":{"startApp":true},"filePath":"cache_clear.js","absoluteFilePath":"/home/julienr/code/adonis/cache/build/commands/cache_clear.js"}],"version":1}
@@ -0,0 +1,4 @@
1
+ import { CommandMetaData, Command } from '@adonisjs/ace/types';
2
+
3
+ export function getMetaData(): Promise<CommandMetaData[]>
4
+ export function getCommand(metaData: CommandMetaData): Promise<Command | null>
@@ -0,0 +1,36 @@
1
+ import { readFile } from 'node:fs/promises'
2
+
3
+ /**
4
+ * In-memory cache of commands after they have been loaded
5
+ */
6
+ let commandsMetaData
7
+
8
+ /**
9
+ * Reads the commands from the "./commands.json" file. Since, the commands.json
10
+ * file is generated automatically, we do not have to validate its contents
11
+ */
12
+ export async function getMetaData() {
13
+ if (commandsMetaData) {
14
+ return commandsMetaData
15
+ }
16
+
17
+ const commandsIndex = await readFile(new URL('./commands.json', import.meta.url), 'utf-8')
18
+ commandsMetaData = JSON.parse(commandsIndex).commands
19
+
20
+ return commandsMetaData
21
+ }
22
+
23
+ /**
24
+ * Imports the command by lookingup its path from the commands
25
+ * metadata
26
+ */
27
+ export async function getCommand(metaData) {
28
+ const commands = await getMetaData()
29
+ const command = commands.find(({ commandName }) => metaData.commandName === commandName)
30
+ if (!command) {
31
+ return null
32
+ }
33
+
34
+ const { default: commandConstructor } = await import(new URL(command.filePath, import.meta.url).href)
35
+ return commandConstructor
36
+ }
@@ -0,0 +1,5 @@
1
+ import type Configure from '@adonisjs/core/commands/configure';
2
+ /**
3
+ * Configures the package
4
+ */
5
+ export declare function configure(command: Configure): Promise<void>;
@@ -0,0 +1,61 @@
1
+ /*
2
+ * @adonisjs/cache
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+ const DRIVERS = ['redis', 'file', 'memory', 'database', 'dynamodb'];
10
+ const DRIVERS_INFO = {
11
+ file: {},
12
+ memory: {},
13
+ redis: {},
14
+ database: {},
15
+ dynamodb: {
16
+ envValidations: {
17
+ AWS_ACCESS_KEY_ID: `Env.schema.string()`,
18
+ AWS_SECRET_ACCESS_KEY: `Env.schema.string()`,
19
+ AWS_REGION: `Env.schema.string()`,
20
+ DYNAMODB_ENDPOINT: `Env.schema.string()`,
21
+ },
22
+ envVars: {
23
+ AWS_ACCESS_KEY_ID: '',
24
+ AWS_SECRET_ACCESS_KEY: '',
25
+ AWS_REGION: '',
26
+ DYNAMODB_ENDPOINT: '',
27
+ },
28
+ },
29
+ };
30
+ /**
31
+ * Configures the package
32
+ */
33
+ export async function configure(command) {
34
+ const driver = await command.prompt.choice('Select the cache driver you plan to use', ['redis', 'file', 'memory', 'database', 'dynamodb'], {
35
+ hint: 'You can always change it later',
36
+ });
37
+ const { envVars, envValidations } = DRIVERS_INFO[driver];
38
+ const codemods = await command.createCodemods();
39
+ /**
40
+ * Publish provider
41
+ */
42
+ await codemods.updateRcFile((rcFile) => {
43
+ rcFile.addProvider('@adonisjs/cache/cache_provider').addCommand('@adonisjs/cache/commands');
44
+ });
45
+ /**
46
+ * Define environment variables
47
+ */
48
+ if (envVars) {
49
+ codemods.defineEnvVariables(envVars);
50
+ }
51
+ /**
52
+ * Define environment validations
53
+ */
54
+ if (envValidations) {
55
+ codemods.defineEnvValidations({ variables: envValidations });
56
+ }
57
+ /**
58
+ * Publish config
59
+ */
60
+ await command.publishStub('config.stub', { driver: driver });
61
+ }
@@ -0,0 +1,6 @@
1
+ export { errors } from 'bentocache';
2
+ export { configure } from './configure.js';
3
+ export { stubsRoot } from './stubs/main.js';
4
+ export { defineConfig } from './src/define_config.js';
5
+ export { drivers } from './src/drivers.js';
6
+ export { store } from './src/store.js';
package/build/index.js ADDED
@@ -0,0 +1,14 @@
1
+ /*
2
+ * @adonisjs/cache
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+ export { errors } from 'bentocache';
10
+ export { configure } from './configure.js';
11
+ export { stubsRoot } from './stubs/main.js';
12
+ export { defineConfig } from './src/define_config.js';
13
+ export { drivers } from './src/drivers.js';
14
+ export { store } from './src/store.js';
@@ -0,0 +1,42 @@
1
+ import type { ApplicationService } from '@adonisjs/core/types';
2
+ import type { CacheEvents } from 'bentocache/types';
3
+ import type { CacheService } from '../src/types.js';
4
+ /**
5
+ * Extend Adonis.js types to include cache
6
+ */
7
+ declare module '@adonisjs/core/types' {
8
+ /**
9
+ * Adding cache type to the application container
10
+ */
11
+ interface ContainerBindings {
12
+ cache: CacheService;
13
+ }
14
+ /**
15
+ * Add cache events to the application events list
16
+ */
17
+ interface EventsList {
18
+ 'cache:cleared': CacheEvents['cache:cleared'];
19
+ 'cache:deleted': CacheEvents['cache:deleted'];
20
+ 'cache:hit': CacheEvents['cache:hit'];
21
+ 'cache:miss': CacheEvents['cache:miss'];
22
+ 'cache:written': CacheEvents['cache:written'];
23
+ 'bus:message:published': CacheEvents['bus:message:published'];
24
+ 'bus:message:received': CacheEvents['bus:message:received'];
25
+ }
26
+ }
27
+ /**
28
+ * Cache provider to register cache specific bindings
29
+ */
30
+ export default class CacheProvider {
31
+ #private;
32
+ protected app: ApplicationService;
33
+ constructor(app: ApplicationService);
34
+ /**
35
+ * Register bindings
36
+ */
37
+ register(): Promise<void>;
38
+ /**
39
+ * Disconnect all cache stores when shutting down the app
40
+ */
41
+ shutdown(): Promise<void>;
42
+ }
@@ -0,0 +1,64 @@
1
+ /*
2
+ * @adonisjs/cache
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+ import { defineReplBindings } from '../src/bindings/repl.js';
10
+ /**
11
+ * Cache provider to register cache specific bindings
12
+ */
13
+ export default class CacheProvider {
14
+ app;
15
+ constructor(app) {
16
+ this.app = app;
17
+ }
18
+ /**
19
+ * Register the cache manager to the container
20
+ */
21
+ async #registerCacheManager() {
22
+ const cacheConfig = this.app.config.get('cache');
23
+ this.app.container.singleton('cache', async () => {
24
+ const { BentoCache } = await import('bentocache');
25
+ const emitter = await this.app.container.make('emitter');
26
+ /**
27
+ * Resolve all store config providers
28
+ */
29
+ const resolvedStores = Object.entries(cacheConfig.stores).map(async ([name, store]) => {
30
+ return [name, await store.entry().resolver(this.app)];
31
+ });
32
+ return new BentoCache({
33
+ ...cacheConfig,
34
+ emitter: emitter,
35
+ default: cacheConfig.default,
36
+ stores: Object.fromEntries(await Promise.all(resolvedStores)),
37
+ });
38
+ });
39
+ }
40
+ /**
41
+ * Register REPL bindings
42
+ */
43
+ async #registerReplBindings() {
44
+ if (this.app.getEnvironment() !== 'repl') {
45
+ return;
46
+ }
47
+ const repl = await this.app.container.make('repl');
48
+ defineReplBindings(this.app, repl);
49
+ }
50
+ /**
51
+ * Register bindings
52
+ */
53
+ async register() {
54
+ this.#registerCacheManager();
55
+ this.#registerReplBindings();
56
+ }
57
+ /**
58
+ * Disconnect all cache stores when shutting down the app
59
+ */
60
+ async shutdown() {
61
+ const cache = await this.app.container.make('cache');
62
+ await cache.disconnectAll().catch(() => { });
63
+ }
64
+ }
@@ -0,0 +1,3 @@
1
+ import type { CacheService } from '../src/types.js';
2
+ declare let cache: CacheService;
3
+ export { cache as default };
@@ -0,0 +1,17 @@
1
+ /*
2
+ * @adonisjs/cache
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+ import app from '@adonisjs/core/services/app';
10
+ let cache;
11
+ /**
12
+ * Returns a singleton instance of the Cache manager
13
+ */
14
+ await app.booted(async () => {
15
+ cache = await app.container.make('cache');
16
+ });
17
+ export { cache as default };
@@ -0,0 +1,6 @@
1
+ import type { Repl } from '@adonisjs/core/repl';
2
+ import type { ApplicationService } from '@adonisjs/core/types';
3
+ /**
4
+ * Define REPL bindings
5
+ */
6
+ export declare function defineReplBindings(app: ApplicationService, Repl: Repl): void;
@@ -0,0 +1,28 @@
1
+ /*
2
+ * @adonisjs/cache
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+ /**
10
+ * Helper to define REPL state
11
+ */
12
+ function setupReplState(repl, key, value) {
13
+ repl.server.context[key] = value;
14
+ repl.notify(`Loaded ${key} module. You can access it using the "${repl.colors.underline(key)}" variable`);
15
+ }
16
+ /**
17
+ * Define REPL bindings
18
+ */
19
+ export function defineReplBindings(app, Repl) {
20
+ /**
21
+ * Load cache provider to the cache property
22
+ */
23
+ Repl.addMethod('loadCache', async (repl) => {
24
+ setupReplState(repl, 'cache', await app.container.make('cache'));
25
+ }, {
26
+ description: 'Load cache provider to the "cache" property',
27
+ });
28
+ }
@@ -0,0 +1,12 @@
1
+ import { Store } from './store.js';
2
+ import { CacheOptions } from './types.js';
3
+ /**
4
+ * Define cache configuration
5
+ */
6
+ export declare function defineConfig<KnownCaches extends Record<string, Store>>(config: CacheOptions & {
7
+ default: keyof KnownCaches;
8
+ stores: KnownCaches;
9
+ }): CacheOptions & {
10
+ default: keyof KnownCaches;
11
+ stores: KnownCaches;
12
+ };
@@ -0,0 +1,14 @@
1
+ /*
2
+ * @adonisjs/cache
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+ /**
10
+ * Define cache configuration
11
+ */
12
+ export function defineConfig(config) {
13
+ return config;
14
+ }
@@ -0,0 +1,20 @@
1
+ import type { ConfigProvider } from '@adonisjs/core/types';
2
+ import type { RedisConnections } from '@adonisjs/redis/types';
3
+ import { MemoryConfig, CreateDriverResult, L1CacheDriver, L2CacheDriver, CreateBusDriverResult, DynamoDBConfig, FileConfig } from 'bentocache/types';
4
+ /**
5
+ * Different drivers supported by the cache module
6
+ */
7
+ export declare const drivers: {
8
+ memory: (config: MemoryConfig) => ConfigProvider<CreateDriverResult<L1CacheDriver>>;
9
+ redis: (config: {
10
+ connectionName?: keyof RedisConnections;
11
+ }) => ConfigProvider<CreateDriverResult<L2CacheDriver>>;
12
+ redisBus: (config: {
13
+ connectionName?: keyof RedisConnections;
14
+ }) => ConfigProvider<CreateBusDriverResult>;
15
+ database: (config?: {
16
+ connectionName?: string;
17
+ }) => ConfigProvider<CreateDriverResult<L2CacheDriver>>;
18
+ dynamodb: (config: DynamoDBConfig) => ConfigProvider<CreateDriverResult<L2CacheDriver>>;
19
+ file: (config: FileConfig) => ConfigProvider<CreateDriverResult<L2CacheDriver>>;
20
+ };
@@ -0,0 +1,101 @@
1
+ /*
2
+ * @adonisjs/cache
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+ /// <reference types="@adonisjs/redis/redis_provider" />
10
+ /// <reference types="@adonisjs/lucid/database_provider" />
11
+ import { configProvider } from '@adonisjs/core';
12
+ /**
13
+ * Different drivers supported by the cache module
14
+ */
15
+ export const drivers = {
16
+ /**
17
+ * Redis driver for L2 layer
18
+ * You must install @adonisjs/redis to use this driver
19
+ */
20
+ redis(config) {
21
+ return configProvider.create(async (app) => {
22
+ const redis = await app.container.make('redis');
23
+ const { redisDriver } = await import('bentocache/drivers/redis');
24
+ const redisConnection = redis.connection(config.connectionName);
25
+ return redisDriver({ connection: redisConnection.ioConnection });
26
+ });
27
+ },
28
+ /**
29
+ * Redis driver for the sync bus
30
+ * You must install @adonisjs/redis to use this driver
31
+ */
32
+ redisBus(config) {
33
+ return configProvider.create(async (app) => {
34
+ const redis = await app.container.make('redis');
35
+ const { redisBusDriver } = await import('bentocache/drivers/redis');
36
+ const redisConnection = redis.connection(config.connectionName);
37
+ return redisBusDriver({ connection: redisConnection.ioConnection.options });
38
+ });
39
+ },
40
+ /**
41
+ * Memory driver for L1 layer
42
+ */
43
+ memory(config) {
44
+ return configProvider.create(async () => {
45
+ const { memoryDriver } = await import('bentocache/drivers/memory');
46
+ return memoryDriver(config);
47
+ });
48
+ },
49
+ /**
50
+ * Database driver for L2 layer
51
+ * You must install @adonisjs/lucid to use this driver
52
+ */
53
+ database(config) {
54
+ return configProvider.create(async (app) => {
55
+ const db = await app.container.make('lucid.db');
56
+ const connectionName = config?.connectionName || db.primaryConnectionName;
57
+ const dialect = db.connection(connectionName).dialect.name;
58
+ /**
59
+ * We only support pg, mysql, better-sqlite3 and sqlite3 dialects for now
60
+ */
61
+ const supportedDialects = ['pg', 'mysql', 'better-sqlite3', 'sqlite3'];
62
+ if (!supportedDialects.includes(dialect)) {
63
+ throw new Error(`Unsupported dialect "${dialect}"`);
64
+ }
65
+ /**
66
+ * Get the knex connection for the given connection name
67
+ */
68
+ const rawConnection = db.getRawConnection(connectionName);
69
+ if (!rawConnection?.connection?.client) {
70
+ throw new Error(`Unable to get raw connection for "${connectionName}"`);
71
+ }
72
+ /**
73
+ * Create the driver
74
+ */
75
+ const { knexDriver } = await import('bentocache/drivers/sql');
76
+ return knexDriver({
77
+ connection: rawConnection.connection.client,
78
+ dialect: dialect === 'postgres' ? 'pg' : dialect,
79
+ });
80
+ });
81
+ },
82
+ /**
83
+ * DynamoDB driver for L2 layer
84
+ * You must install @aws-sdk/client-dynamodb to use this driver
85
+ */
86
+ dynamodb(config) {
87
+ return configProvider.create(async () => {
88
+ const { dynamoDbDriver } = await import('bentocache/drivers/dynamodb');
89
+ return dynamoDbDriver(config);
90
+ });
91
+ },
92
+ /**
93
+ * File driver for L2 layer
94
+ */
95
+ file(config) {
96
+ return configProvider.create(async () => {
97
+ const { fileDriver } = await import('bentocache/drivers/file');
98
+ return fileDriver(config);
99
+ });
100
+ },
101
+ };
@@ -0,0 +1,46 @@
1
+ import type { ConfigProvider } from '@adonisjs/core/types';
2
+ import { RawCommonOptions, CreateDriverResult, L1CacheDriver, CreateBusDriverResult, L2CacheDriver } from 'bentocache/types';
3
+ /**
4
+ * Create a new store
5
+ */
6
+ export declare function store(options?: RawCommonOptions & {
7
+ prefix?: string;
8
+ }): Store;
9
+ export declare class Store {
10
+ #private;
11
+ constructor(baseOptions?: RawCommonOptions & {
12
+ prefix?: string;
13
+ });
14
+ /**
15
+ * Add a L1 layer to your store. This is usually a memory driver
16
+ * for fast access purposes.
17
+ */
18
+ useL1Layer(driver: ConfigProvider<CreateDriverResult<L1CacheDriver>>): this;
19
+ /**
20
+ * Add a L2 layer to your store. This is usually something
21
+ * distributed like Redis, DynamoDB, Sql database, etc.
22
+ */
23
+ useL2Layer(driver: ConfigProvider<CreateDriverResult<L2CacheDriver>>): this;
24
+ /**
25
+ * Add a bus to your store. It will be used to synchronize L1 layers between
26
+ * different instances of your application.
27
+ */
28
+ useBus(bus: ConfigProvider<CreateBusDriverResult>): this;
29
+ /**
30
+ * Create a config provider for the store
31
+ */
32
+ entry(): ConfigProvider<{
33
+ "__#70@#private": any;
34
+ useL1Layer(driver: CreateDriverResult<L1CacheDriver>): any;
35
+ useL2Layer(driver: CreateDriverResult<L2CacheDriver>): any;
36
+ useBus(bus: CreateBusDriverResult): any;
37
+ readonly entry: {
38
+ options: RawCommonOptions & {
39
+ prefix?: string | undefined;
40
+ };
41
+ l1: CreateDriverResult<L1CacheDriver> | undefined;
42
+ l2: CreateDriverResult<L2CacheDriver> | undefined;
43
+ bus: CreateBusDriverResult | undefined;
44
+ };
45
+ }>;
46
+ }
@@ -0,0 +1,64 @@
1
+ /*
2
+ * @adonisjs/cache
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+ import { bentostore } from 'bentocache';
10
+ import { configProvider } from '@adonisjs/core';
11
+ /**
12
+ * Create a new store
13
+ */
14
+ export function store(options) {
15
+ return new Store(options);
16
+ }
17
+ export class Store {
18
+ #baseOptions = {};
19
+ #l1;
20
+ #l2;
21
+ #bus;
22
+ constructor(baseOptions = {}) {
23
+ this.#baseOptions = baseOptions;
24
+ }
25
+ /**
26
+ * Add a L1 layer to your store. This is usually a memory driver
27
+ * for fast access purposes.
28
+ */
29
+ useL1Layer(driver) {
30
+ this.#l1 = driver;
31
+ return this;
32
+ }
33
+ /**
34
+ * Add a L2 layer to your store. This is usually something
35
+ * distributed like Redis, DynamoDB, Sql database, etc.
36
+ */
37
+ useL2Layer(driver) {
38
+ this.#l2 = driver;
39
+ return this;
40
+ }
41
+ /**
42
+ * Add a bus to your store. It will be used to synchronize L1 layers between
43
+ * different instances of your application.
44
+ */
45
+ useBus(bus) {
46
+ this.#bus = bus;
47
+ return this;
48
+ }
49
+ /**
50
+ * Create a config provider for the store
51
+ */
52
+ entry() {
53
+ return configProvider.create(async (app) => {
54
+ const storeInstance = bentostore(this.#baseOptions);
55
+ if (this.#l1)
56
+ storeInstance.useL1Layer(await this.#l1?.resolver(app));
57
+ if (this.#l2)
58
+ storeInstance.useL2Layer(await this.#l2?.resolver(app));
59
+ if (this.#bus)
60
+ storeInstance.useBus(await this.#bus?.resolver(app));
61
+ return storeInstance;
62
+ });
63
+ }
64
+ }
@@ -0,0 +1,26 @@
1
+ import type { BentoCache, bentostore } from 'bentocache';
2
+ import type { RawBentoCacheOptions } from 'bentocache/types';
3
+ import type { store } from './store.js';
4
+ /**
5
+ * The options accepted by the cache module
6
+ */
7
+ export type CacheOptions = Omit<RawBentoCacheOptions, 'logger' | 'emitter'>;
8
+ /**
9
+ * Infer the stores from the user config
10
+ */
11
+ export type InferStores<T extends {
12
+ stores: Record<string, ReturnType<typeof store>>;
13
+ }> = {
14
+ [K in keyof T['stores']]: any;
15
+ };
16
+ /**
17
+ * A list of known caches stores inferred from the user config
18
+ * This interface must be extended in user-land
19
+ */
20
+ export interface CacheStores {
21
+ }
22
+ /**
23
+ * The cache service interface registered with the container
24
+ */
25
+ export interface CacheService extends BentoCache<CacheStores extends Record<string, ReturnType<typeof bentostore>> ? CacheStores : never> {
26
+ }
@@ -0,0 +1,9 @@
1
+ /*
2
+ * @adonisjs/cache
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+ export {};
@@ -0,0 +1,45 @@
1
+ {{{
2
+ exports({ to: app.configPath('cache.ts') })
3
+ }}}
4
+ import env from '#start/env'
5
+ {{#if driver === 'file'}}
6
+ import app from '@adonisjs/core/services/app'
7
+ {{/if}}
8
+ import { defineConfig, store, drivers } from '@adonisjs/cache'
9
+
10
+ const cacheConfig = defineConfig({
11
+ default: '{{ driver }}',
12
+ stores: {
13
+ {{#if driver === 'database'}}
14
+ database: store().useL2Layer(drivers.database({
15
+ connectionName: 'primary',
16
+ }))
17
+ {{#elif driver === 'redis'}}
18
+ redis: store().useL2Layer(drivers.redis({
19
+ connectionName: 'primary',
20
+ }))
21
+ {{#elif driver === 'memory'}}
22
+ memory: store().useL1Layer(drivers.memory())
23
+ {{#elif driver === 'file'}}
24
+ file: store().useL2Layer(drivers.file({
25
+ directory: app.tmpPath('cache')
26
+ }))
27
+ {{#elif driver === 'dynamodb'}}
28
+ dynamodb: store().useL2Layer(drivers.dynamodb({
29
+ table: { name: 'cache' },
30
+ credentials: {
31
+ accessKeyId: env.get('AWS_ACCESS_KEY_ID'),
32
+ secretAccessKey: env.get('AWS_SECRET_ACCESS_KEY')
33
+ },
34
+ region: env.get('AWS_REGION'),
35
+ endpoint: env.get('DYNAMODB_ENDPOINT')
36
+ }))
37
+ {{/if}}
38
+ }
39
+ })
40
+
41
+ export default cacheConfig
42
+
43
+ declare module '@adonisjs/cache/types' {
44
+ interface CacheStores extends InferStores<typeof cacheConfig> {}
45
+ }
@@ -0,0 +1 @@
1
+ export declare const stubsRoot: string;
@@ -0,0 +1,10 @@
1
+ /*
2
+ * @adonisjs/cache
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+ import { getDirname } from '@poppinss/utils';
10
+ export const stubsRoot = getDirname(import.meta.url);
package/package.json ADDED
@@ -0,0 +1,127 @@
1
+ {
2
+ "name": "@adonisjs/cache",
3
+ "description": "Official caching module for AdonisJS framework",
4
+ "version": "1.0.0-0",
5
+ "engines": {
6
+ "node": ">=18.16.0"
7
+ },
8
+ "main": "build/index.js",
9
+ "type": "module",
10
+ "files": [
11
+ "build/configure.js",
12
+ "build/configure.d.ts",
13
+ "build/index.js",
14
+ "build/index.d.ts",
15
+ "build/factories",
16
+ "build/providers",
17
+ "build/services",
18
+ "build/commands",
19
+ "build/src",
20
+ "build/stubs"
21
+ ],
22
+ "exports": {
23
+ ".": "./build/index.js",
24
+ "./types": "./build/src/types.js",
25
+ "./commands/*": "./build/commands/*.js",
26
+ "./commands": "./build/commands/main.js",
27
+ "./services/main": "./build/services/main.js",
28
+ "./cache_provider": "./build/providers/cache_provider.js"
29
+ },
30
+ "scripts": {
31
+ "clean": "del-cli build",
32
+ "copy:templates": "copyfiles \"stubs/**/*.stub\" build",
33
+ "typecheck": "tsc --noEmit",
34
+ "index:commands": "adonis-kit index build/commands",
35
+ "lint": "eslint . --ext=.ts",
36
+ "format": "prettier --write .",
37
+ "quick:test": "node --enable-source-maps --loader=ts-node/esm bin/test.ts",
38
+ "pretest": "npm run lint",
39
+ "test": "c8 npm run quick:test",
40
+ "prebuild": "npm run lint && npm run clean",
41
+ "build": "tsc",
42
+ "postbuild": "npm run copy:templates && npm run index:commands",
43
+ "release": "np",
44
+ "version": "npm run build",
45
+ "prepublishOnly": "npm run build"
46
+ },
47
+ "devDependencies": {
48
+ "@adonisjs/assembler": "^6.1.3-25",
49
+ "@adonisjs/core": "^6.1.5-29",
50
+ "@adonisjs/eslint-config": "^1.1.8",
51
+ "@adonisjs/lucid": "19.0.0-3",
52
+ "@adonisjs/prettier-config": "^1.1.8",
53
+ "@adonisjs/redis": "8.0.0-12",
54
+ "@adonisjs/tsconfig": "^1.1.8",
55
+ "@japa/assert": "2.0.1",
56
+ "@japa/expect-type": "^2.0.0",
57
+ "@japa/file-system": "^2.0.1",
58
+ "@japa/runner": "^3.0.5",
59
+ "@japa/snapshot": "^2.0.1",
60
+ "@swc/core": "^1.3.96",
61
+ "@types/node": "^20.8.10",
62
+ "better-sqlite3": "^9.0.0",
63
+ "c8": "^8.0.1",
64
+ "copyfiles": "^2.4.1",
65
+ "del-cli": "^5.1.0",
66
+ "eslint": "^8.53.0",
67
+ "ioredis": "^5.3.2",
68
+ "luxon": "^3.4.3",
69
+ "np": "^8.0.4",
70
+ "p-event": "^6.0.0",
71
+ "prettier": "^3.0.3",
72
+ "ts-node": "^10.9.1",
73
+ "typescript": "^5.2.2"
74
+ },
75
+ "dependencies": {
76
+ "@poppinss/utils": "^6.5.1",
77
+ "bentocache": "1.0.0-beta.4"
78
+ },
79
+ "peerDependencies": {
80
+ "@adonisjs/assembler": "^6.1.3-22",
81
+ "@adonisjs/core": "^6.1.5-26",
82
+ "@adonisjs/lucid": "19.0.0-3",
83
+ "@adonisjs/redis": "8.0.0-12"
84
+ },
85
+ "peerDependenciesMeta": {
86
+ "@adonisjs/assembler": {
87
+ "optional": true
88
+ },
89
+ "@adonisjs/redis": {
90
+ "optional": true
91
+ },
92
+ "@adonisjs/lucid": {
93
+ "optional": true
94
+ }
95
+ },
96
+ "author": "adonisjs, Julien Ripouteau",
97
+ "license": "MIT",
98
+ "keywords": [
99
+ "adonisjs",
100
+ "cache",
101
+ "caching",
102
+ "bentocache"
103
+ ],
104
+ "eslintConfig": {
105
+ "extends": "@adonisjs/eslint-config/package"
106
+ },
107
+ "prettier": "@adonisjs/prettier-config",
108
+ "publishConfig": {
109
+ "access": "public",
110
+ "tag": "latest"
111
+ },
112
+ "np": {
113
+ "message": "chore(release): %s",
114
+ "tag": "latest",
115
+ "branch": "main",
116
+ "anyBranch": false
117
+ },
118
+ "c8": {
119
+ "reporter": [
120
+ "text",
121
+ "html"
122
+ ],
123
+ "exclude": [
124
+ "tests/**"
125
+ ]
126
+ }
127
+ }