@vlian/csrf 0.1.1

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/dist/index.cjs ADDED
@@ -0,0 +1,159 @@
1
+ /**
2
+ * CSRF 防护工具
3
+ * 提供 CSRF Token 的生成、存储和验证功能
4
+ */ /**
5
+ * CSRF Token 存储接口
6
+ */ "use strict";
7
+ Object.defineProperty(exports, "__esModule", {
8
+ value: true
9
+ });
10
+ function _export(target, all) {
11
+ for(var name in all)Object.defineProperty(target, name, {
12
+ enumerable: true,
13
+ get: Object.getOwnPropertyDescriptor(all, name).get
14
+ });
15
+ }
16
+ _export(exports, {
17
+ get CSRFTokenManager () {
18
+ return CSRFTokenManager;
19
+ },
20
+ get getCSRFManager () {
21
+ return getCSRFManager;
22
+ },
23
+ get initCSRFManager () {
24
+ return initCSRFManager;
25
+ }
26
+ });
27
+ function _define_property(obj, key, value) {
28
+ if (key in obj) {
29
+ Object.defineProperty(obj, key, {
30
+ value: value,
31
+ enumerable: true,
32
+ configurable: true,
33
+ writable: true
34
+ });
35
+ } else {
36
+ obj[key] = value;
37
+ }
38
+ return obj;
39
+ }
40
+ /**
41
+ * 默认 Token 存储(使用 Cookie)
42
+ */ let CookieTokenStorage = class CookieTokenStorage {
43
+ getToken() {
44
+ if (typeof document === 'undefined') {
45
+ return null;
46
+ }
47
+ const cookies = document.cookie.split(';');
48
+ for (const cookie of cookies){
49
+ const [name, value] = cookie.trim().split('=');
50
+ if (name === this.cookieName) {
51
+ return decodeURIComponent(value);
52
+ }
53
+ }
54
+ return null;
55
+ }
56
+ setToken(token) {
57
+ if (typeof document === 'undefined') {
58
+ return;
59
+ }
60
+ // 设置 Cookie(HttpOnly 由服务端设置,这里只设置客户端可访问的)
61
+ document.cookie = `${this.cookieName}=${encodeURIComponent(token)}; path=/; SameSite=Strict`;
62
+ }
63
+ clearToken() {
64
+ if (typeof document === 'undefined') {
65
+ return;
66
+ }
67
+ document.cookie = `${this.cookieName}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
68
+ }
69
+ constructor(cookieName = 'csrf-token'){
70
+ _define_property(this, "cookieName", void 0);
71
+ this.cookieName = cookieName;
72
+ }
73
+ };
74
+ /**
75
+ * 内存 Token 存储(用于 SSR 或测试)
76
+ */ let MemoryTokenStorage = class MemoryTokenStorage {
77
+ getToken() {
78
+ return this.token;
79
+ }
80
+ setToken(token) {
81
+ this.token = token;
82
+ }
83
+ clearToken() {
84
+ this.token = null;
85
+ }
86
+ constructor(){
87
+ _define_property(this, "token", null);
88
+ }
89
+ };
90
+ let CSRFTokenManager = class CSRFTokenManager {
91
+ /**
92
+ * 获取 CSRF Token
93
+ */ async getToken() {
94
+ if (this.getTokenFn) {
95
+ try {
96
+ return await Promise.resolve(this.getTokenFn());
97
+ } catch (error) {
98
+ console.warn('CSRF Token 获取失败:', error);
99
+ return null;
100
+ }
101
+ }
102
+ // 从存储中获取
103
+ return this.storage.getToken();
104
+ }
105
+ /**
106
+ * 设置 CSRF Token
107
+ */ setToken(token) {
108
+ this.storage.setToken(token);
109
+ }
110
+ /**
111
+ * 验证 CSRF Token
112
+ */ async validateToken(token) {
113
+ if (this.validateTokenFn) {
114
+ try {
115
+ return await Promise.resolve(this.validateTokenFn(token));
116
+ } catch (error) {
117
+ console.warn('CSRF Token 验证失败:', error);
118
+ return false;
119
+ }
120
+ }
121
+ // 默认验证:检查存储中的 Token 是否匹配
122
+ const storedToken = this.storage.getToken();
123
+ return storedToken !== null && storedToken === token;
124
+ }
125
+ /**
126
+ * 清除 CSRF Token
127
+ */ clearToken() {
128
+ this.storage.clearToken();
129
+ }
130
+ /**
131
+ * 获取请求头名称
132
+ */ getHeaderName() {
133
+ return this.headerName;
134
+ }
135
+ constructor(config){
136
+ _define_property(this, "storage", void 0);
137
+ _define_property(this, "headerName", void 0);
138
+ _define_property(this, "cookieName", void 0);
139
+ _define_property(this, "getTokenFn", void 0);
140
+ _define_property(this, "validateTokenFn", void 0);
141
+ this.headerName = config?.headerName ?? 'X-CSRF-Token';
142
+ this.cookieName = config?.cookieName ?? 'csrf-token';
143
+ this.storage = config?.storage ?? (typeof document !== 'undefined' ? new CookieTokenStorage(this.cookieName) : new MemoryTokenStorage());
144
+ this.getTokenFn = config?.getToken;
145
+ this.validateTokenFn = config?.validateToken;
146
+ }
147
+ };
148
+ /**
149
+ * 全局 CSRF Token 管理器实例
150
+ */ let globalCSRFManager = null;
151
+ function initCSRFManager(config) {
152
+ globalCSRFManager = new CSRFTokenManager(config);
153
+ return globalCSRFManager;
154
+ }
155
+ function getCSRFManager() {
156
+ return globalCSRFManager;
157
+ }
158
+
159
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * CSRF 防护工具\n * 提供 CSRF Token 的生成、存储和验证功能\n */\n\n/**\n * CSRF Token 存储接口\n */\nexport interface CSRFTokenStorage {\n /**\n * 获取 Token\n */\n getToken(): string | null;\n /**\n * 设置 Token\n */\n setToken(token: string): void;\n /**\n * 清除 Token\n */\n clearToken(): void;\n}\n\n/**\n * 默认 Token 存储(使用 Cookie)\n */\nclass CookieTokenStorage implements CSRFTokenStorage {\n private cookieName: string;\n\n constructor(cookieName: string = 'csrf-token') {\n this.cookieName = cookieName;\n }\n\n getToken(): string | null {\n if (typeof document === 'undefined') {\n return null;\n }\n\n const cookies = document.cookie.split(';');\n for (const cookie of cookies) {\n const [name, value] = cookie.trim().split('=');\n if (name === this.cookieName) {\n return decodeURIComponent(value);\n }\n }\n return null;\n }\n\n setToken(token: string): void {\n if (typeof document === 'undefined') {\n return;\n }\n\n // 设置 Cookie(HttpOnly 由服务端设置,这里只设置客户端可访问的)\n document.cookie = `${this.cookieName}=${encodeURIComponent(token)}; path=/; SameSite=Strict`;\n }\n\n clearToken(): void {\n if (typeof document === 'undefined') {\n return;\n }\n\n document.cookie = `${this.cookieName}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT`;\n }\n}\n\n/**\n * 内存 Token 存储(用于 SSR 或测试)\n */\nclass MemoryTokenStorage implements CSRFTokenStorage {\n private token: string | null = null;\n\n getToken(): string | null {\n return this.token;\n }\n\n setToken(token: string): void {\n this.token = token;\n }\n\n clearToken(): void {\n this.token = null;\n }\n}\n\n/**\n * CSRF Token 管理器\n */\nexport class CSRFTokenManager {\n private storage: CSRFTokenStorage;\n private headerName: string;\n private cookieName: string;\n private getTokenFn?: () => string | Promise<string>;\n private validateTokenFn?: (token: string) => boolean | Promise<boolean>;\n\n constructor(config?: {\n storage?: CSRFTokenStorage;\n headerName?: string;\n cookieName?: string;\n getToken?: () => string | Promise<string>;\n validateToken?: (token: string) => boolean | Promise<boolean>;\n }) {\n this.headerName = config?.headerName ?? 'X-CSRF-Token';\n this.cookieName = config?.cookieName ?? 'csrf-token';\n this.storage = config?.storage ?? (typeof document !== 'undefined' \n ? new CookieTokenStorage(this.cookieName)\n : new MemoryTokenStorage());\n this.getTokenFn = config?.getToken;\n this.validateTokenFn = config?.validateToken;\n }\n\n /**\n * 获取 CSRF Token\n */\n async getToken(): Promise<string | null> {\n if (this.getTokenFn) {\n try {\n return await Promise.resolve(this.getTokenFn());\n } catch (error) {\n console.warn('CSRF Token 获取失败:', error);\n return null;\n }\n }\n\n // 从存储中获取\n return this.storage.getToken();\n }\n\n /**\n * 设置 CSRF Token\n */\n setToken(token: string): void {\n this.storage.setToken(token);\n }\n\n /**\n * 验证 CSRF Token\n */\n async validateToken(token: string): Promise<boolean> {\n if (this.validateTokenFn) {\n try {\n return await Promise.resolve(this.validateTokenFn(token));\n } catch (error) {\n console.warn('CSRF Token 验证失败:', error);\n return false;\n }\n }\n\n // 默认验证:检查存储中的 Token 是否匹配\n const storedToken = this.storage.getToken();\n return storedToken !== null && storedToken === token;\n }\n\n /**\n * 清除 CSRF Token\n */\n clearToken(): void {\n this.storage.clearToken();\n }\n\n /**\n * 获取请求头名称\n */\n getHeaderName(): string {\n return this.headerName;\n }\n}\n\n/**\n * 全局 CSRF Token 管理器实例\n */\nlet globalCSRFManager: CSRFTokenManager | null = null;\n\n/**\n * 初始化 CSRF Token 管理器\n */\nexport function initCSRFManager(config?: {\n storage?: CSRFTokenStorage;\n headerName?: string;\n cookieName?: string;\n getToken?: () => string | Promise<string>;\n validateToken?: (token: string) => boolean | Promise<boolean>;\n}): CSRFTokenManager {\n globalCSRFManager = new CSRFTokenManager(config);\n return globalCSRFManager;\n}\n\n/**\n * 获取全局 CSRF Token 管理器\n */\nexport function getCSRFManager(): CSRFTokenManager | null {\n return globalCSRFManager;\n}\n"],"names":["CSRFTokenManager","getCSRFManager","initCSRFManager","CookieTokenStorage","getToken","document","cookies","cookie","split","name","value","trim","cookieName","decodeURIComponent","setToken","token","encodeURIComponent","clearToken","MemoryTokenStorage","getTokenFn","Promise","resolve","error","console","warn","storage","validateToken","validateTokenFn","storedToken","getHeaderName","headerName","config","globalCSRFManager"],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * CSRF 防护工具
3
+ * 提供 CSRF Token 的生成、存储和验证功能
4
+ */
5
+ /**
6
+ * CSRF Token 存储接口
7
+ */
8
+ export interface CSRFTokenStorage {
9
+ /**
10
+ * 获取 Token
11
+ */
12
+ getToken(): string | null;
13
+ /**
14
+ * 设置 Token
15
+ */
16
+ setToken(token: string): void;
17
+ /**
18
+ * 清除 Token
19
+ */
20
+ clearToken(): void;
21
+ }
22
+ /**
23
+ * CSRF Token 管理器
24
+ */
25
+ export declare class CSRFTokenManager {
26
+ private storage;
27
+ private headerName;
28
+ private cookieName;
29
+ private getTokenFn?;
30
+ private validateTokenFn?;
31
+ constructor(config?: {
32
+ storage?: CSRFTokenStorage;
33
+ headerName?: string;
34
+ cookieName?: string;
35
+ getToken?: () => string | Promise<string>;
36
+ validateToken?: (token: string) => boolean | Promise<boolean>;
37
+ });
38
+ /**
39
+ * 获取 CSRF Token
40
+ */
41
+ getToken(): Promise<string | null>;
42
+ /**
43
+ * 设置 CSRF Token
44
+ */
45
+ setToken(token: string): void;
46
+ /**
47
+ * 验证 CSRF Token
48
+ */
49
+ validateToken(token: string): Promise<boolean>;
50
+ /**
51
+ * 清除 CSRF Token
52
+ */
53
+ clearToken(): void;
54
+ /**
55
+ * 获取请求头名称
56
+ */
57
+ getHeaderName(): string;
58
+ }
59
+ /**
60
+ * 初始化 CSRF Token 管理器
61
+ */
62
+ export declare function initCSRFManager(config?: {
63
+ storage?: CSRFTokenStorage;
64
+ headerName?: string;
65
+ cookieName?: string;
66
+ getToken?: () => string | Promise<string>;
67
+ validateToken?: (token: string) => boolean | Promise<boolean>;
68
+ }): CSRFTokenManager;
69
+ /**
70
+ * 获取全局 CSRF Token 管理器
71
+ */
72
+ export declare function getCSRFManager(): CSRFTokenManager | null;
package/dist/index.js ADDED
@@ -0,0 +1,144 @@
1
+ /**
2
+ * CSRF 防护工具
3
+ * 提供 CSRF Token 的生成、存储和验证功能
4
+ */ /**
5
+ * CSRF Token 存储接口
6
+ */ function _define_property(obj, key, value) {
7
+ if (key in obj) {
8
+ Object.defineProperty(obj, key, {
9
+ value: value,
10
+ enumerable: true,
11
+ configurable: true,
12
+ writable: true
13
+ });
14
+ } else {
15
+ obj[key] = value;
16
+ }
17
+ return obj;
18
+ }
19
+ /**
20
+ * 默认 Token 存储(使用 Cookie)
21
+ */ let CookieTokenStorage = class CookieTokenStorage {
22
+ getToken() {
23
+ if (typeof document === 'undefined') {
24
+ return null;
25
+ }
26
+ const cookies = document.cookie.split(';');
27
+ for (const cookie of cookies){
28
+ const [name, value] = cookie.trim().split('=');
29
+ if (name === this.cookieName) {
30
+ return decodeURIComponent(value);
31
+ }
32
+ }
33
+ return null;
34
+ }
35
+ setToken(token) {
36
+ if (typeof document === 'undefined') {
37
+ return;
38
+ }
39
+ // 设置 Cookie(HttpOnly 由服务端设置,这里只设置客户端可访问的)
40
+ document.cookie = `${this.cookieName}=${encodeURIComponent(token)}; path=/; SameSite=Strict`;
41
+ }
42
+ clearToken() {
43
+ if (typeof document === 'undefined') {
44
+ return;
45
+ }
46
+ document.cookie = `${this.cookieName}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
47
+ }
48
+ constructor(cookieName = 'csrf-token'){
49
+ _define_property(this, "cookieName", void 0);
50
+ this.cookieName = cookieName;
51
+ }
52
+ };
53
+ /**
54
+ * 内存 Token 存储(用于 SSR 或测试)
55
+ */ let MemoryTokenStorage = class MemoryTokenStorage {
56
+ getToken() {
57
+ return this.token;
58
+ }
59
+ setToken(token) {
60
+ this.token = token;
61
+ }
62
+ clearToken() {
63
+ this.token = null;
64
+ }
65
+ constructor(){
66
+ _define_property(this, "token", null);
67
+ }
68
+ };
69
+ /**
70
+ * CSRF Token 管理器
71
+ */ export class CSRFTokenManager {
72
+ /**
73
+ * 获取 CSRF Token
74
+ */ async getToken() {
75
+ if (this.getTokenFn) {
76
+ try {
77
+ return await Promise.resolve(this.getTokenFn());
78
+ } catch (error) {
79
+ console.warn('CSRF Token 获取失败:', error);
80
+ return null;
81
+ }
82
+ }
83
+ // 从存储中获取
84
+ return this.storage.getToken();
85
+ }
86
+ /**
87
+ * 设置 CSRF Token
88
+ */ setToken(token) {
89
+ this.storage.setToken(token);
90
+ }
91
+ /**
92
+ * 验证 CSRF Token
93
+ */ async validateToken(token) {
94
+ if (this.validateTokenFn) {
95
+ try {
96
+ return await Promise.resolve(this.validateTokenFn(token));
97
+ } catch (error) {
98
+ console.warn('CSRF Token 验证失败:', error);
99
+ return false;
100
+ }
101
+ }
102
+ // 默认验证:检查存储中的 Token 是否匹配
103
+ const storedToken = this.storage.getToken();
104
+ return storedToken !== null && storedToken === token;
105
+ }
106
+ /**
107
+ * 清除 CSRF Token
108
+ */ clearToken() {
109
+ this.storage.clearToken();
110
+ }
111
+ /**
112
+ * 获取请求头名称
113
+ */ getHeaderName() {
114
+ return this.headerName;
115
+ }
116
+ constructor(config){
117
+ _define_property(this, "storage", void 0);
118
+ _define_property(this, "headerName", void 0);
119
+ _define_property(this, "cookieName", void 0);
120
+ _define_property(this, "getTokenFn", void 0);
121
+ _define_property(this, "validateTokenFn", void 0);
122
+ this.headerName = config?.headerName ?? 'X-CSRF-Token';
123
+ this.cookieName = config?.cookieName ?? 'csrf-token';
124
+ this.storage = config?.storage ?? (typeof document !== 'undefined' ? new CookieTokenStorage(this.cookieName) : new MemoryTokenStorage());
125
+ this.getTokenFn = config?.getToken;
126
+ this.validateTokenFn = config?.validateToken;
127
+ }
128
+ }
129
+ /**
130
+ * 全局 CSRF Token 管理器实例
131
+ */ let globalCSRFManager = null;
132
+ /**
133
+ * 初始化 CSRF Token 管理器
134
+ */ export function initCSRFManager(config) {
135
+ globalCSRFManager = new CSRFTokenManager(config);
136
+ return globalCSRFManager;
137
+ }
138
+ /**
139
+ * 获取全局 CSRF Token 管理器
140
+ */ export function getCSRFManager() {
141
+ return globalCSRFManager;
142
+ }
143
+
144
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * CSRF 防护工具\n * 提供 CSRF Token 的生成、存储和验证功能\n */\n\n/**\n * CSRF Token 存储接口\n */\nexport interface CSRFTokenStorage {\n /**\n * 获取 Token\n */\n getToken(): string | null;\n /**\n * 设置 Token\n */\n setToken(token: string): void;\n /**\n * 清除 Token\n */\n clearToken(): void;\n}\n\n/**\n * 默认 Token 存储(使用 Cookie)\n */\nclass CookieTokenStorage implements CSRFTokenStorage {\n private cookieName: string;\n\n constructor(cookieName: string = 'csrf-token') {\n this.cookieName = cookieName;\n }\n\n getToken(): string | null {\n if (typeof document === 'undefined') {\n return null;\n }\n\n const cookies = document.cookie.split(';');\n for (const cookie of cookies) {\n const [name, value] = cookie.trim().split('=');\n if (name === this.cookieName) {\n return decodeURIComponent(value);\n }\n }\n return null;\n }\n\n setToken(token: string): void {\n if (typeof document === 'undefined') {\n return;\n }\n\n // 设置 Cookie(HttpOnly 由服务端设置,这里只设置客户端可访问的)\n document.cookie = `${this.cookieName}=${encodeURIComponent(token)}; path=/; SameSite=Strict`;\n }\n\n clearToken(): void {\n if (typeof document === 'undefined') {\n return;\n }\n\n document.cookie = `${this.cookieName}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT`;\n }\n}\n\n/**\n * 内存 Token 存储(用于 SSR 或测试)\n */\nclass MemoryTokenStorage implements CSRFTokenStorage {\n private token: string | null = null;\n\n getToken(): string | null {\n return this.token;\n }\n\n setToken(token: string): void {\n this.token = token;\n }\n\n clearToken(): void {\n this.token = null;\n }\n}\n\n/**\n * CSRF Token 管理器\n */\nexport class CSRFTokenManager {\n private storage: CSRFTokenStorage;\n private headerName: string;\n private cookieName: string;\n private getTokenFn?: () => string | Promise<string>;\n private validateTokenFn?: (token: string) => boolean | Promise<boolean>;\n\n constructor(config?: {\n storage?: CSRFTokenStorage;\n headerName?: string;\n cookieName?: string;\n getToken?: () => string | Promise<string>;\n validateToken?: (token: string) => boolean | Promise<boolean>;\n }) {\n this.headerName = config?.headerName ?? 'X-CSRF-Token';\n this.cookieName = config?.cookieName ?? 'csrf-token';\n this.storage = config?.storage ?? (typeof document !== 'undefined' \n ? new CookieTokenStorage(this.cookieName)\n : new MemoryTokenStorage());\n this.getTokenFn = config?.getToken;\n this.validateTokenFn = config?.validateToken;\n }\n\n /**\n * 获取 CSRF Token\n */\n async getToken(): Promise<string | null> {\n if (this.getTokenFn) {\n try {\n return await Promise.resolve(this.getTokenFn());\n } catch (error) {\n console.warn('CSRF Token 获取失败:', error);\n return null;\n }\n }\n\n // 从存储中获取\n return this.storage.getToken();\n }\n\n /**\n * 设置 CSRF Token\n */\n setToken(token: string): void {\n this.storage.setToken(token);\n }\n\n /**\n * 验证 CSRF Token\n */\n async validateToken(token: string): Promise<boolean> {\n if (this.validateTokenFn) {\n try {\n return await Promise.resolve(this.validateTokenFn(token));\n } catch (error) {\n console.warn('CSRF Token 验证失败:', error);\n return false;\n }\n }\n\n // 默认验证:检查存储中的 Token 是否匹配\n const storedToken = this.storage.getToken();\n return storedToken !== null && storedToken === token;\n }\n\n /**\n * 清除 CSRF Token\n */\n clearToken(): void {\n this.storage.clearToken();\n }\n\n /**\n * 获取请求头名称\n */\n getHeaderName(): string {\n return this.headerName;\n }\n}\n\n/**\n * 全局 CSRF Token 管理器实例\n */\nlet globalCSRFManager: CSRFTokenManager | null = null;\n\n/**\n * 初始化 CSRF Token 管理器\n */\nexport function initCSRFManager(config?: {\n storage?: CSRFTokenStorage;\n headerName?: string;\n cookieName?: string;\n getToken?: () => string | Promise<string>;\n validateToken?: (token: string) => boolean | Promise<boolean>;\n}): CSRFTokenManager {\n globalCSRFManager = new CSRFTokenManager(config);\n return globalCSRFManager;\n}\n\n/**\n * 获取全局 CSRF Token 管理器\n */\nexport function getCSRFManager(): CSRFTokenManager | null {\n return globalCSRFManager;\n}\n"],"names":["CookieTokenStorage","getToken","document","cookies","cookie","split","name","value","trim","cookieName","decodeURIComponent","setToken","token","encodeURIComponent","clearToken","MemoryTokenStorage","CSRFTokenManager","getTokenFn","Promise","resolve","error","console","warn","storage","validateToken","validateTokenFn","storedToken","getHeaderName","headerName","config","globalCSRFManager","initCSRFManager","getCSRFManager"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@vlian/csrf",
3
+ "version": "0.1.1",
4
+ "description": "CSRF token manager for vlian ecosystem",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "sideEffects": false,
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./package.json": "./package.json"
16
+ },
17
+ "typesVersions": {
18
+ "*": {
19
+ "*": [
20
+ "dist/*.d.ts"
21
+ ]
22
+ }
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "README.md"
27
+ ],
28
+ "scripts": {
29
+ "build": "npm run clean && npm run build:types && npm run build:esm && npm run build:cjs",
30
+ "build:types": "tsc --emitDeclarationOnly --declarationMap false --sourceMap false",
31
+ "build:esm": "swc src -d dist --strip-leading-paths --config-file .swcrc",
32
+ "build:cjs": "swc src -d dist-temp --strip-leading-paths --config-file .swcrc.cjs && node scripts/rename-cjs.js && rm -rf dist-temp",
33
+ "clean": "rm -rf dist dist-temp",
34
+ "prepublishOnly": "npm run build && npm version patch --no-git-tag-version"
35
+ },
36
+ "author": "Secra Framework Contributors",
37
+ "license": "Apache-2.0",
38
+ "engines": {
39
+ "node": ">=16.0.0"
40
+ },
41
+ "devDependencies": {
42
+ "@swc/cli": "^0.8.0",
43
+ "@swc/core": "^1.15.18",
44
+ "@types/node": "^20.0.0",
45
+ "typescript": "^5.9.3"
46
+ },
47
+ "publishConfig": {
48
+ "access": "public"
49
+ },
50
+ "packageManager": "pnpm@10.27.0"
51
+ }