@safeki/nuxt 0.1.1 → 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 safeki
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,74 +1,153 @@
1
- <!--
2
- Get your module up and running quickly.
3
-
4
- Find and replace all on all files (CMD+SHIFT+F):
5
- - Name: My Module
6
- - Package name: @safeki/nuxt
7
- - Description: My new Nuxt module
8
- -->
9
-
10
- # My Module
1
+ # @safeki/nuxt
11
2
 
12
3
  [![npm version][npm-version-src]][npm-version-href]
13
4
  [![npm downloads][npm-downloads-src]][npm-downloads-href]
14
5
  [![License][license-src]][license-href]
15
6
  [![Nuxt][nuxt-src]][nuxt-href]
16
7
 
17
- My new Nuxt module for doing amazing things.
18
-
19
- - [✨ &nbsp;Release Notes](/CHANGELOG.md)
20
- <!-- - [🏀 Online playground](https://stackblitz.com/github/your-org/@safeki/nuxt?file=playground%2Fapp.vue) -->
21
- <!-- - [📖 &nbsp;Documentation](https://example.com) -->
8
+ Safekit utilities for Nuxt applications. The module currently provides Sentry setup helpers and server-side crypto helpers for encrypting values during deployment and decrypting them inside Nitro runtime code.
22
9
 
23
10
  ## Features
24
11
 
25
- <!-- Highlight some of the features your module provide here -->
26
- - &nbsp;Foo
27
- - 🚠 &nbsp;Bar
28
- - 🌲 &nbsp;Baz
12
+ - Nuxt module wrapper for `@sentry/nuxt`
13
+ - Private runtime config storage for a Safekit crypto secret key
14
+ - AES-256-GCM encryption and decryption helpers
15
+ - Server auto-imports for decrypting encrypted Safekit values in Nitro code
16
+ - Playground form for testing encrypt and decrypt with a secret key entered directly in the UI
29
17
 
30
18
  ## Quick Setup
31
19
 
32
- Install the module to your Nuxt application with one command:
20
+ Install the module in your Nuxt application:
33
21
 
34
22
  ```bash
35
23
  npx nuxt module add @safeki/nuxt
36
24
  ```
37
25
 
38
- That's it! You can now use My Module in your Nuxt app ✨
39
-
40
-
41
- ## Contribution
42
-
43
- <details>
44
- <summary>Local development</summary>
45
-
46
- ```bash
47
- # Install dependencies
48
- npm install
49
-
50
- # Generate type stubs
51
- npm run dev:prepare
52
-
53
- # Develop with the playground
54
- npm run dev
55
-
56
- # Build the playground
57
- npm run dev:build
58
-
59
- # Run ESLint
60
- npm run lint
61
-
62
- # Run Vitest
63
- npm run test
64
- npm run test:watch
65
-
66
- # Release new version
67
- npm run release
68
- ```
69
-
70
- </details>
26
+ Add module options in `nuxt.config.ts`:
27
+
28
+ ```ts
29
+ export default defineNuxtConfig({
30
+ modules: [
31
+ ['@safeki/nuxt', {
32
+ crypto: {
33
+ secretKey: process.env.SAFEKIT_CRYPTO_SECRET_KEY,
34
+ },
35
+ sentry: {
36
+ telemetry: false,
37
+ sourcemaps: {
38
+ disable: true,
39
+ },
40
+ client: {
41
+ dsn: process.env.NUXT_PUBLIC_SENTRY_DSN,
42
+ tracesSampleRate: 1,
43
+ replaysSessionSampleRate: 0,
44
+ replaysOnErrorSampleRate: 1,
45
+ },
46
+ },
47
+ }],
48
+ ],
49
+ })
50
+ ```
51
+
52
+ ## Crypto
53
+
54
+ Use `@safeki/nuxt/crypto` from a Docker entrypoint or any Node.js script to encrypt values before the Nuxt server starts:
55
+
56
+ ```bash
57
+ node -e "import('@safeki/nuxt/crypto').then(({ encrypt }) => console.log(encrypt(process.env.PLAIN_TEXT, process.env.SAFEKIT_CRYPTO_SECRET_KEY)))"
58
+ ```
59
+
60
+ The encrypted payload uses this format:
61
+
62
+ ```txt
63
+ safekit:v1.<iv>.<authTag>.<encryptedText>
64
+ ```
65
+
66
+ Decrypt inside server routes, server middleware, and Nitro code with the server-only auto-import:
67
+
68
+ ```ts
69
+ export default defineEventHandler(() => {
70
+ return decryptSafekit('safekit:v1...')
71
+ })
72
+ ```
73
+
74
+ The package exports these crypto helpers:
75
+
76
+ ```ts
77
+ import { decrypt, decryped, encrypt, encryped } from '@safeki/nuxt/crypto'
78
+ ```
79
+
80
+ `encrypt` and `decrypt` are the preferred names. `encryped` and `decryped` are kept as aliases for compatibility with the original API wording.
81
+
82
+ ## Sentry
83
+
84
+ Client Sentry options are stored under public runtime config and consumed by the module runtime config file. Server Sentry initialization reads from environment variables:
85
+
86
+ ```bash
87
+ SENTRY_DSN=
88
+ SENTRY_ENVIRONMENT=
89
+ SENTRY_RELEASE=
90
+ SENTRY_DEBUG=false
91
+ SENTRY_SEND_DEFAULT_PII=false
92
+ SENTRY_TRACES_SAMPLE_RATE=1
93
+ ```
94
+
95
+ ## Module Options
96
+
97
+ ```ts
98
+ interface ModuleOptions {
99
+ crypto?: {
100
+ secretKey?: string
101
+ }
102
+ sentry?: SentryNuxtModuleOptions & {
103
+ client?: {
104
+ dsn?: string
105
+ environment?: string
106
+ release?: string
107
+ debug?: boolean
108
+ sendDefaultPii?: boolean
109
+ tracesSampleRate?: number
110
+ replaysSessionSampleRate?: number
111
+ replaysOnErrorSampleRate?: number
112
+ tracePropagationTargets?: string[]
113
+ }
114
+ }
115
+ }
116
+ ```
117
+
118
+ If `crypto.secretKey` is not provided, the module falls back to `process.env.SAFEKIT_CRYPTO_SECRET_KEY`.
119
+
120
+ ## Playground
121
+
122
+ Run the playground locally:
123
+
124
+ ```bash
125
+ npm run dev
126
+ ```
127
+
128
+ The playground includes a crypto form for entering a secret key directly, encrypting plain text, and decrypting the encrypted output.
129
+
130
+ ## Development
131
+
132
+ ```bash
133
+ # Install dependencies
134
+ npm install
135
+
136
+ # Generate stubs and prepare playground
137
+ npm run dev:prepare
138
+
139
+ # Start playground
140
+ npm run dev
141
+
142
+ # Build package
143
+ npm run prepack
144
+ ```
145
+
146
+ The package build emits the Nuxt module entry plus the public `@safeki/nuxt/crypto` subpath used by deployment scripts.
147
+
148
+ ## License
71
149
 
150
+ [MIT](./LICENSE)
72
151
 
73
152
  <!-- Badges -->
74
153
  [npm-version-src]: https://img.shields.io/npm/v/@safeki/nuxt/latest.svg?style=flat&colorA=020420&colorB=00DC82
@@ -0,0 +1,6 @@
1
+ declare function encrypt(plainText: string, secretKey: string): string;
2
+ declare function decrypt(encryptedText: string, secretKey: string): string;
3
+ declare const encryped: typeof encrypt;
4
+ declare const decryped: typeof decrypt;
5
+
6
+ export { decryped, decrypt, encryped, encrypt };
@@ -0,0 +1,55 @@
1
+ import { randomBytes, createCipheriv, createDecipheriv, createHash } from 'node:crypto';
2
+
3
+ const VERSION = "safekit:v1";
4
+ const ALGORITHM = "aes-256-gcm";
5
+ const IV_LENGTH = 12;
6
+ function assertSecretKey(secretKey) {
7
+ if (!secretKey) {
8
+ throw new Error("Safekit crypto secret key is required");
9
+ }
10
+ }
11
+ function createKey(secretKey) {
12
+ assertSecretKey(secretKey);
13
+ return createHash("sha256").update(secretKey).digest();
14
+ }
15
+ function toBase64Url(value) {
16
+ return value.toString("base64url");
17
+ }
18
+ function fromBase64Url(value) {
19
+ return Buffer.from(value, "base64url");
20
+ }
21
+ function encrypt(plainText, secretKey) {
22
+ const iv = randomBytes(IV_LENGTH);
23
+ const cipher = createCipheriv(ALGORITHM, createKey(secretKey), iv);
24
+ const encrypted = Buffer.concat([
25
+ cipher.update(plainText, "utf8"),
26
+ cipher.final()
27
+ ]);
28
+ const authTag = cipher.getAuthTag();
29
+ return [
30
+ VERSION,
31
+ toBase64Url(iv),
32
+ toBase64Url(authTag),
33
+ toBase64Url(encrypted)
34
+ ].join(".");
35
+ }
36
+ function decrypt(encryptedText, secretKey) {
37
+ const [version, encodedIv, encodedAuthTag, encodedEncrypted] = encryptedText.split(".");
38
+ if (version !== VERSION || !encodedIv || !encodedAuthTag || !encodedEncrypted) {
39
+ throw new Error("Invalid Safekit encrypted value");
40
+ }
41
+ const decipher = createDecipheriv(
42
+ ALGORITHM,
43
+ createKey(secretKey),
44
+ fromBase64Url(encodedIv)
45
+ );
46
+ decipher.setAuthTag(fromBase64Url(encodedAuthTag));
47
+ return Buffer.concat([
48
+ decipher.update(fromBase64Url(encodedEncrypted)),
49
+ decipher.final()
50
+ ]).toString("utf8");
51
+ }
52
+ const encryped = encrypt;
53
+ const decryped = decrypt;
54
+
55
+ export { decryped, decrypt, encryped, encrypt };
package/dist/module.d.mts CHANGED
@@ -16,6 +16,9 @@ interface ModuleOptions {
16
16
  sentry?: ModuleOptions$1 & {
17
17
  client?: SafekitSentryClientOptions;
18
18
  };
19
+ crypto?: {
20
+ secretKey?: string;
21
+ };
19
22
  }
20
23
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
21
24
 
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@safeki/nuxt",
3
3
  "configKey": "nuxtSafekit",
4
- "version": "0.1.1",
4
+ "version": "0.1.3",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { defineNuxtModule, createResolver, installModule } from '@nuxt/kit';
1
+ import { defineNuxtModule, createResolver, addServerImports, installModule } from '@nuxt/kit';
2
2
 
3
3
  const module$1 = defineNuxtModule({
4
4
  meta: {
@@ -10,12 +10,31 @@ const module$1 = defineNuxtModule({
10
10
  async setup(options, nuxt) {
11
11
  const resolver = createResolver(import.meta.url);
12
12
  const { client = {}, ...sentryModuleOptions } = options.sentry || {};
13
+ const secretKey = options.crypto?.secretKey || process.env.SAFEKIT_CRYPTO_SECRET_KEY || "";
14
+ nuxt.options.runtimeConfig.nuxtSafekit = {
15
+ ...nuxt.options.runtimeConfig.nuxtSafekit || {},
16
+ crypto: {
17
+ secretKey
18
+ }
19
+ };
13
20
  nuxt.options.runtimeConfig.public.nuxtSafekit = {
14
21
  ...nuxt.options.runtimeConfig.public.nuxtSafekit || {},
15
22
  sentry: {
16
23
  client
17
24
  }
18
25
  };
26
+ addServerImports([
27
+ {
28
+ name: "decryptSafekit",
29
+ as: "decryptSafekit",
30
+ from: resolver.resolve("./runtime/server/crypto")
31
+ },
32
+ {
33
+ name: "decrypedSafekit",
34
+ as: "decrypedSafekit",
35
+ from: resolver.resolve("./runtime/server/crypto")
36
+ }
37
+ ]);
19
38
  await installModule("@sentry/nuxt/module", {
20
39
  autoInjectServerSentry: "top-level-import",
21
40
  configDir: resolver.resolve("./runtime"),
@@ -0,0 +1,2 @@
1
+ export declare function decryptSafekit(encryptedText: string): string;
2
+ export declare const decrypedSafekit: typeof decryptSafekit;
@@ -0,0 +1,7 @@
1
+ import { useRuntimeConfig } from "#imports";
2
+ import { decrypt } from "../../crypto";
3
+ export function decryptSafekit(encryptedText) {
4
+ const secretKey = useRuntimeConfig().nuxtSafekit?.crypto?.secretKey;
5
+ return decrypt(encryptedText, secretKey);
6
+ }
7
+ export const decrypedSafekit = decryptSafekit;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@safeki/nuxt",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "My new Nuxt module",
5
5
  "repository": "your-org/@safeki/nuxt",
6
6
  "license": "MIT",
@@ -9,6 +9,10 @@
9
9
  ".": {
10
10
  "types": "./dist/types.d.mts",
11
11
  "import": "./dist/module.mjs"
12
+ },
13
+ "./crypto": {
14
+ "types": "./dist/crypto.d.mts",
15
+ "import": "./dist/crypto.mjs"
12
16
  }
13
17
  },
14
18
  "main": "./dist/module.mjs",
@@ -16,6 +20,9 @@
16
20
  "*": {
17
21
  ".": [
18
22
  "./dist/types.d.mts"
23
+ ],
24
+ "crypto": [
25
+ "./dist/crypto.d.mts"
19
26
  ]
20
27
  }
21
28
  },
@@ -31,6 +38,7 @@
31
38
  "dev:build": "nuxt build playground",
32
39
  "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxt prepare playground",
33
40
  "release": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
41
+ "publish": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish --access public",
34
42
  "lint": "eslint .",
35
43
  "lint:fix": "eslint . --fix",
36
44
  "test": "vitest run",