@rezo-zero/nuxt-cache-control 0.0.3

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/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # Nuxt Cache-Control
2
+
3
+ [![npm version][npm-version-src]][npm-version-href]
4
+ [![Nuxt][nuxt-src]][nuxt-href]
5
+
6
+ Declare fine-grained cache control headers for your Nuxt application in each page.
7
+
8
+ - [✨  Release Notes](/CHANGELOG.md)
9
+
10
+ ## Features
11
+
12
+ - **Fine-grained cache control**: Set cache control headers for each page with `useCacheControl` composable.
13
+ - **Prevents caching when response status is not 200**
14
+ - **Prevents public responses when some cookies attached**: configure some cookies names for which cache-control will be private.
15
+
16
+ ## Quick Setup
17
+
18
+ Install the module to your Nuxt application with one command:
19
+
20
+ ```bash
21
+ npx nuxi module add @rezo-zero/nuxt-cache-control
22
+ ```
23
+
24
+ ### Configure module
25
+
26
+ ```ts
27
+ // nuxt.config.ts
28
+ export default defineNuxtConfig({
29
+ modules: [
30
+ '@rezo-zero/nuxt-cache-control'
31
+ ],
32
+ cacheControl: {
33
+ noCacheCookies: ['cart', 'session', 'auth']
34
+ }
35
+ })
36
+ ```
37
+
38
+ That's it! You can now use Nuxt Cache Control in your Nuxt app with `useCacheControl` composable.
39
+
40
+ ```ts
41
+ export interface CacheControlOptions {
42
+ maxAge?: number // in seconds
43
+ sMaxAge?: number // in seconds
44
+ staleWhileRevalidate?: number | true // in seconds, or true, which means infinite staleWhileRevalidate
45
+ public: boolean
46
+ }
47
+ ```
48
+
49
+
50
+ ## Contribution
51
+
52
+ <details>
53
+ <summary>Local development</summary>
54
+
55
+ ```bash
56
+ # Install dependencies
57
+ pnpm install
58
+
59
+ # Generate type stubs
60
+ pnpm dev:prepare
61
+
62
+ # Develop with the playground
63
+ pnpm dev
64
+
65
+ # Build the playground
66
+ pnpm dev:build
67
+
68
+ # Run ESLint
69
+ pnpm lint
70
+
71
+ # Run Vitest
72
+ pnpm test
73
+ pnpm test:watch
74
+
75
+ # Release new version
76
+ pnpm release
77
+ ```
78
+
79
+ </details>
80
+
81
+
82
+ <!-- Badges -->
83
+ [npm-version-src]: https://img.shields.io/npm/v/@rezo-zero/nuxt-cache-control/latest.svg?style=flat&colorA=020420&colorB=00DC82
84
+ [npm-version-href]: https://npmjs.com/package/@rezo-zero/nuxt-cache-control
85
+
86
+ [npm-downloads-src]: https://img.shields.io/npm/dm/@rezo-zero/nuxt-cache-control.svg?style=flat&colorA=020420&colorB=00DC82
87
+ [npm-downloads-href]: https://npmjs.com/package/@rezo-zero/nuxt-cache-control
88
+
89
+ [license-src]: https://img.shields.io/npm/l/@rezo-zero/nuxt-cache-control.svg?style=flat&colorA=020420&colorB=00DC82
90
+ [license-href]: https://npmjs.com/package/@rezo-zero/nuxt-cache-control
91
+
92
+ [nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt.js
93
+ [nuxt-href]: https://nuxt.com
@@ -0,0 +1,5 @@
1
+ module.exports = function(...args) {
2
+ return import('./module.mjs').then(m => m.default.call(this, ...args))
3
+ }
4
+ const _meta = module.exports.meta = require('./module.json')
5
+ module.exports.getMeta = () => Promise.resolve(_meta)
@@ -0,0 +1,8 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ noCacheCookies?: string[];
5
+ }
6
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
7
+
8
+ export { type ModuleOptions, _default as default };
@@ -0,0 +1,8 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ noCacheCookies?: string[];
5
+ }
6
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
7
+
8
+ export { type ModuleOptions, _default as default };
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "nuxt-cache-control",
3
+ "configKey": "cacheControl",
4
+ "compatibility": {
5
+ "nuxt": "^3.10.0"
6
+ },
7
+ "version": "0.0.3"
8
+ }
@@ -0,0 +1,28 @@
1
+ import { defineNuxtModule, createResolver, addImports, addServerPlugin } from '@nuxt/kit';
2
+ import { defu } from 'defu';
3
+
4
+ const module = defineNuxtModule({
5
+ meta: {
6
+ name: "nuxt-cache-control",
7
+ configKey: "cacheControl",
8
+ // Compatibility constraints
9
+ compatibility: {
10
+ // Semver version of supported nuxt versions
11
+ nuxt: "^3.10.0"
12
+ }
13
+ },
14
+ setup(options, nuxt) {
15
+ const { resolve } = createResolver(import.meta.url);
16
+ nuxt.options.runtimeConfig.cacheControl = defu(nuxt.options.runtimeConfig.cacheControl || {}, options);
17
+ addImports({
18
+ name: "useCacheControl",
19
+ // name of the composable to be used
20
+ as: "useCacheControl",
21
+ from: resolve("runtime/composables/use-cache-control")
22
+ // path of composable
23
+ });
24
+ addServerPlugin(resolve("runtime/server/plugins/cache-control"));
25
+ }
26
+ });
27
+
28
+ export { module as default };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#directives
3
+ */
4
+ export interface CacheControlOptions {
5
+ maxAge?: number;
6
+ sMaxAge?: number;
7
+ staleWhileRevalidate?: number | true;
8
+ public: boolean;
9
+ }
10
+ export declare function useCacheControl(cacheControl: CacheControlOptions): void;
@@ -0,0 +1,13 @@
1
+ import { getCurrentInstance, useSSRContext } from "vue";
2
+ export function useCacheControl(cacheControl) {
3
+ if (process.client) {
4
+ return;
5
+ }
6
+ if (!getCurrentInstance()) {
7
+ return;
8
+ }
9
+ const ssrContext = useSSRContext();
10
+ if (ssrContext && ssrContext.event) {
11
+ ssrContext.event.context.cacheControl = cacheControl;
12
+ }
13
+ }
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,37 @@
1
+ export default defineNitroPlugin((nitroApp) => {
2
+ nitroApp.hooks.hook("render:response", (_response, { event }) => {
3
+ const qs = getQuery(event);
4
+ if (getResponseStatus(event) !== 200) {
5
+ setResponseHeader(event, "Cache-Control", `private, no-cache, no-store, must-revalidate`);
6
+ return;
7
+ }
8
+ if (qs.url && qs.statusCode) {
9
+ setResponseHeader(event, "Cache-Control", `private, no-cache, no-store, must-revalidate`);
10
+ return;
11
+ }
12
+ const cacheControl = event.context.cacheControl || {
13
+ maxAge: 0,
14
+ public: false
15
+ };
16
+ const cookies = parseCookies(event);
17
+ const noCacheCookies = useRuntimeConfig().cacheControl.noCacheCookies || [];
18
+ const noCache = noCacheCookies.some((cookie) => cookies[cookie]);
19
+ if (!noCache && cacheControl.public) {
20
+ const cacheControlHeader = [`public`];
21
+ if (cacheControl?.maxAge >= 0) {
22
+ cacheControlHeader.push(`max-age=${cacheControl.maxAge}`);
23
+ }
24
+ if (cacheControl?.sMaxAge >= 0) {
25
+ cacheControlHeader.push(`s-maxage=${cacheControl.sMaxAge}`);
26
+ }
27
+ if (cacheControl?.staleWhileRevalidate === true) {
28
+ cacheControlHeader.push(`stale-while-revalidate`);
29
+ } else if (cacheControl?.staleWhileRevalidate > 0) {
30
+ cacheControlHeader.push(`stale-while-revalidate=${cacheControl.staleWhileRevalidate}`);
31
+ }
32
+ setResponseHeader(event, "Cache-Control", cacheControlHeader.join(", "));
33
+ } else {
34
+ setResponseHeader(event, "Cache-Control", `private, no-cache, no-store, must-revalidate`);
35
+ }
36
+ });
37
+ });
@@ -0,0 +1,16 @@
1
+
2
+ import type { ModuleOptions } from './module.js'
3
+
4
+
5
+ declare module '@nuxt/schema' {
6
+ interface NuxtConfig { ['cacheControl']?: Partial<ModuleOptions> }
7
+ interface NuxtOptions { ['cacheControl']?: ModuleOptions }
8
+ }
9
+
10
+ declare module 'nuxt/schema' {
11
+ interface NuxtConfig { ['cacheControl']?: Partial<ModuleOptions> }
12
+ interface NuxtOptions { ['cacheControl']?: ModuleOptions }
13
+ }
14
+
15
+
16
+ export type { ModuleOptions, default } from './module.js'
@@ -0,0 +1,16 @@
1
+
2
+ import type { ModuleOptions } from './module'
3
+
4
+
5
+ declare module '@nuxt/schema' {
6
+ interface NuxtConfig { ['cacheControl']?: Partial<ModuleOptions> }
7
+ interface NuxtOptions { ['cacheControl']?: ModuleOptions }
8
+ }
9
+
10
+ declare module 'nuxt/schema' {
11
+ interface NuxtConfig { ['cacheControl']?: Partial<ModuleOptions> }
12
+ interface NuxtOptions { ['cacheControl']?: ModuleOptions }
13
+ }
14
+
15
+
16
+ export type { ModuleOptions, default } from './module'
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@rezo-zero/nuxt-cache-control",
3
+ "version": "0.0.3",
4
+ "description": "Declare fine-grained cache control headers for your Nuxt application in each page",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/rezozero/nuxt-cache-control.git"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/types.d.ts",
14
+ "import": "./dist/module.mjs",
15
+ "require": "./dist/module.cjs"
16
+ }
17
+ },
18
+ "main": "./dist/module.cjs",
19
+ "types": "./dist/types.d.ts",
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "scripts": {
24
+ "prepack": "nuxt-module-build build",
25
+ "dev": "nuxi dev playground",
26
+ "dev:build": "nuxi build playground",
27
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
28
+ "release": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish --access=public && git push --follow-tags",
29
+ "lint": "eslint .",
30
+ "test": "vitest run",
31
+ "test:watch": "vitest watch"
32
+ },
33
+ "dependencies": {
34
+ "@nuxt/kit": "^3.11.1",
35
+ "defu": "^6.1.4"
36
+ },
37
+ "devDependencies": {
38
+ "@nuxt/devtools": "latest",
39
+ "@nuxt/eslint-config": "^0.2.0",
40
+ "@nuxt/module-builder": "^0.5.5",
41
+ "@nuxt/schema": "^3.11.1",
42
+ "@nuxt/test-utils": "^3.12.0",
43
+ "@types/node": "^20.11.29",
44
+ "changelogen": "^0.5.5",
45
+ "eslint": "^8.57.0",
46
+ "eslint-config-prettier": "^9.1.0",
47
+ "eslint-plugin-prettier": "^5.1.3",
48
+ "nuxt": "^3.11.1",
49
+ "prettier": "^3.2.5",
50
+ "vitest": "^1.4.0"
51
+ },
52
+ "engines": {
53
+ "node": "^20"
54
+ }
55
+ }