@technomoron/mail-magic 1.0.9 → 1.0.11
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/CHANGES +19 -0
- package/README.md +5 -0
- package/dist/api/assets.js +153 -0
- package/dist/api/forms.js +2 -0
- package/dist/api/mailer.js +1 -0
- package/dist/bin/mail-magic.js +63 -0
- package/dist/index.js +61 -2
- package/dist/store/envloader.js +3 -3
- package/dist/store/store.js +66 -1
- package/package.json +17 -3
- package/.do-realease.sh +0 -54
- package/.editorconfig +0 -9
- package/.env-dist +0 -71
- package/.prettierrc +0 -14
- package/.vscode/extensions.json +0 -3
- package/.vscode/settings.json +0 -22
- package/config-example/form-template/default.njk +0 -102
- package/config-example/forms.config.json +0 -8
- package/config-example/init-data.json +0 -33
- package/config-example/tx-template/default.njk +0 -107
- package/ecosystem.config.cjs +0 -42
- package/eslint.config.mjs +0 -196
- package/lintconfig.cjs +0 -81
- package/src/api/assets.ts +0 -92
- package/src/api/forms.ts +0 -239
- package/src/api/mailer.ts +0 -270
- package/src/index.ts +0 -71
- package/src/models/db.ts +0 -112
- package/src/models/domain.ts +0 -72
- package/src/models/form.ts +0 -209
- package/src/models/init.ts +0 -240
- package/src/models/txmail.ts +0 -206
- package/src/models/user.ts +0 -79
- package/src/server.ts +0 -27
- package/src/store/envloader.ts +0 -109
- package/src/store/store.ts +0 -195
- package/src/types.ts +0 -39
- package/src/util.ts +0 -137
- package/tests/fixtures/certs/test.crt +0 -19
- package/tests/fixtures/certs/test.key +0 -28
- package/tests/helpers/test-setup.ts +0 -317
- package/tests/mail-magic.test.ts +0 -171
- package/tsconfig.json +0 -14
- package/vitest.config.ts +0 -11
package/.prettierrc
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"tabWidth": 4,
|
|
3
|
-
"useTabs": true,
|
|
4
|
-
"singleQuote": true,
|
|
5
|
-
"semi": true,
|
|
6
|
-
"trailingComma": "none",
|
|
7
|
-
"bracketSpacing": true,
|
|
8
|
-
"bracketSameLine": true,
|
|
9
|
-
"arrowParens": "always",
|
|
10
|
-
"printWidth": 120,
|
|
11
|
-
"vueIndentScriptAndStyle": false,
|
|
12
|
-
"htmlWhitespaceSensitivity": "ignore",
|
|
13
|
-
"singleAttributePerLine": false
|
|
14
|
-
}
|
package/.vscode/extensions.json
DELETED
package/.vscode/settings.json
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"editor.formatOnSave": true,
|
|
3
|
-
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
4
|
-
"[javascript]": {
|
|
5
|
-
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
6
|
-
},
|
|
7
|
-
"[typescript]": {
|
|
8
|
-
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
9
|
-
},
|
|
10
|
-
"[vue]": {
|
|
11
|
-
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
12
|
-
},
|
|
13
|
-
"[json]": {
|
|
14
|
-
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
15
|
-
},
|
|
16
|
-
"editor.codeActionsOnSave": {
|
|
17
|
-
"source.fixAll.eslint": "explicit"
|
|
18
|
-
},
|
|
19
|
-
"eslint.enable": true,
|
|
20
|
-
"eslint.workingDirectories": ["./"],
|
|
21
|
-
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact", "vue"]
|
|
22
|
-
}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
2
|
-
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
3
|
-
<html>
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="utf-8" />
|
|
6
|
-
<title>Form Submission Details</title>
|
|
7
|
-
<style>
|
|
8
|
-
body {
|
|
9
|
-
font-family: Arial, sans-serif;
|
|
10
|
-
line-height: 1.6;
|
|
11
|
-
color: #333;
|
|
12
|
-
}
|
|
13
|
-
h3 {
|
|
14
|
-
color: #444;
|
|
15
|
-
}
|
|
16
|
-
table {
|
|
17
|
-
width: 100%;
|
|
18
|
-
border-collapse: collapse;
|
|
19
|
-
margin-bottom: 20px;
|
|
20
|
-
}
|
|
21
|
-
th,
|
|
22
|
-
td {
|
|
23
|
-
border: 1px solid #ddd;
|
|
24
|
-
padding: 8px;
|
|
25
|
-
text-align: left;
|
|
26
|
-
}
|
|
27
|
-
th {
|
|
28
|
-
background-color: #f5f5f5;
|
|
29
|
-
}
|
|
30
|
-
</style>
|
|
31
|
-
</head>
|
|
32
|
-
<body>
|
|
33
|
-
<h3>Form Fields</h3>
|
|
34
|
-
{% if formFields %}
|
|
35
|
-
<table>
|
|
36
|
-
<thead>
|
|
37
|
-
<tr>
|
|
38
|
-
<th>Field</th>
|
|
39
|
-
<th>Value</th>
|
|
40
|
-
</tr>
|
|
41
|
-
</thead>
|
|
42
|
-
<tbody>
|
|
43
|
-
{% for field, value in formFields %}
|
|
44
|
-
<tr>
|
|
45
|
-
<td>{{ field }}</td>
|
|
46
|
-
<td>{{ value }}</td>
|
|
47
|
-
</tr>
|
|
48
|
-
{% endfor %}
|
|
49
|
-
</tbody>
|
|
50
|
-
</table>
|
|
51
|
-
{% else %}
|
|
52
|
-
<p>No form fields submitted.</p>
|
|
53
|
-
{% endif %}
|
|
54
|
-
|
|
55
|
-
<h3>File Metadata</h3>
|
|
56
|
-
{% if files and files.length %}
|
|
57
|
-
<table>
|
|
58
|
-
<thead>
|
|
59
|
-
<tr>
|
|
60
|
-
<th>Filename</th>
|
|
61
|
-
<th>Path</th>
|
|
62
|
-
</tr>
|
|
63
|
-
</thead>
|
|
64
|
-
<tbody>
|
|
65
|
-
{% for file in files %}
|
|
66
|
-
<tr>
|
|
67
|
-
<td>{{ file.originalname }}</td>
|
|
68
|
-
<td>{{ file.path }}</td>
|
|
69
|
-
</tr>
|
|
70
|
-
{% endfor %}
|
|
71
|
-
</tbody>
|
|
72
|
-
</table>
|
|
73
|
-
{% else %}
|
|
74
|
-
<p>No files attached.</p>
|
|
75
|
-
{% endif %}
|
|
76
|
-
|
|
77
|
-
<h3>Request Metadata</h3>
|
|
78
|
-
{% if _meta_ %}
|
|
79
|
-
<table>
|
|
80
|
-
<tbody>
|
|
81
|
-
<tr>
|
|
82
|
-
<th>Client IP</th>
|
|
83
|
-
<td>{{ _meta_.client_ip | default('Unknown') }}</td>
|
|
84
|
-
</tr>
|
|
85
|
-
<tr>
|
|
86
|
-
<th>Received At</th>
|
|
87
|
-
<td>{{ _meta_.received_at | default('Unknown') }}</td>
|
|
88
|
-
</tr>
|
|
89
|
-
{% if _meta_.ip_chain and _meta_.ip_chain.length %}
|
|
90
|
-
<tr>
|
|
91
|
-
<th>IP Chain</th>
|
|
92
|
-
<td>{{ _meta_.ip_chain | join(', ') }}</td>
|
|
93
|
-
</tr>
|
|
94
|
-
{% endif %}
|
|
95
|
-
</tbody>
|
|
96
|
-
</table>
|
|
97
|
-
{% else %}
|
|
98
|
-
<p>No metadata provided.</p>
|
|
99
|
-
{% endif %}
|
|
100
|
-
</body>
|
|
101
|
-
</html>
|
|
102
|
-
</html>
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"user": [
|
|
3
|
-
{
|
|
4
|
-
"user_id": 1,
|
|
5
|
-
"idname": "testuser",
|
|
6
|
-
"token": "SomethingWeirdWhoKnows",
|
|
7
|
-
"name": "Test Inc.",
|
|
8
|
-
"email": "noreply@example.com"
|
|
9
|
-
}
|
|
10
|
-
],
|
|
11
|
-
"domain": [
|
|
12
|
-
{
|
|
13
|
-
"domain_id": 1,
|
|
14
|
-
"user_id": 1,
|
|
15
|
-
"domain": "mail.example.com",
|
|
16
|
-
"sender": "Some User <noreply@example.com>"
|
|
17
|
-
}
|
|
18
|
-
],
|
|
19
|
-
"template": [
|
|
20
|
-
{
|
|
21
|
-
"template_id": 1,
|
|
22
|
-
"user_id": 1,
|
|
23
|
-
"domain_id": 1,
|
|
24
|
-
"name": "test",
|
|
25
|
-
"locale": "",
|
|
26
|
-
"template": "",
|
|
27
|
-
"template_file": "",
|
|
28
|
-
"sender": "someone@mail.example.com",
|
|
29
|
-
"subject": "Example Mail",
|
|
30
|
-
"slug": "test"
|
|
31
|
-
}
|
|
32
|
-
]
|
|
33
|
-
}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<title>Email Details</title>
|
|
6
|
-
<style>
|
|
7
|
-
body {
|
|
8
|
-
font-family: Arial, sans-serif;
|
|
9
|
-
color: #333;
|
|
10
|
-
line-height: 1.6;
|
|
11
|
-
}
|
|
12
|
-
h2 {
|
|
13
|
-
margin-top: 30px;
|
|
14
|
-
border-bottom: 1px solid #ccc;
|
|
15
|
-
}
|
|
16
|
-
table {
|
|
17
|
-
width: 100%;
|
|
18
|
-
border-collapse: collapse;
|
|
19
|
-
margin-top: 10px;
|
|
20
|
-
}
|
|
21
|
-
th,
|
|
22
|
-
td {
|
|
23
|
-
padding: 8px;
|
|
24
|
-
border: 1px solid #ddd;
|
|
25
|
-
}
|
|
26
|
-
th {
|
|
27
|
-
background: #f0f0f0;
|
|
28
|
-
}
|
|
29
|
-
</style>
|
|
30
|
-
</head>
|
|
31
|
-
<body>
|
|
32
|
-
<h2>Email Recipient</h2>
|
|
33
|
-
<p>
|
|
34
|
-
<strong>To:</strong>
|
|
35
|
-
{{ _rcpt_email_ }}
|
|
36
|
-
</p>
|
|
37
|
-
|
|
38
|
-
<h2>Template Variables</h2>
|
|
39
|
-
|
|
40
|
-
{% if _vars_ %}
|
|
41
|
-
<table>
|
|
42
|
-
<thead>
|
|
43
|
-
<tr>
|
|
44
|
-
<th>Key</th>
|
|
45
|
-
<th>Value</th>
|
|
46
|
-
</tr>
|
|
47
|
-
</thead>
|
|
48
|
-
<tbody>
|
|
49
|
-
{% for key, value in _vars_ %}
|
|
50
|
-
<tr>
|
|
51
|
-
<td>{{ key }}</td>
|
|
52
|
-
<td>{{ value }}</td>
|
|
53
|
-
</tr>
|
|
54
|
-
{% endfor %}
|
|
55
|
-
</tbody>
|
|
56
|
-
</table>
|
|
57
|
-
{% else %}
|
|
58
|
-
<p>No variables found.</p>
|
|
59
|
-
{% endif %}
|
|
60
|
-
|
|
61
|
-
<h2>Attachments</h2>
|
|
62
|
-
{% if _attachments_ and _attachments_ | length > 0 %}
|
|
63
|
-
<table>
|
|
64
|
-
<thead>
|
|
65
|
-
<tr>
|
|
66
|
-
<th>Label</th>
|
|
67
|
-
<th>Filename</th>
|
|
68
|
-
</tr>
|
|
69
|
-
</thead>
|
|
70
|
-
<tbody>
|
|
71
|
-
{% for label, filename in _attachments_ %}
|
|
72
|
-
<tr>
|
|
73
|
-
<td>{{ label }}</td>
|
|
74
|
-
<td>{{ filename }}</td>
|
|
75
|
-
</tr>
|
|
76
|
-
{% endfor %}
|
|
77
|
-
</tbody>
|
|
78
|
-
</table>
|
|
79
|
-
{% else %}
|
|
80
|
-
<p>No attachments included.</p>
|
|
81
|
-
{% endif %}
|
|
82
|
-
|
|
83
|
-
<h2>Request Metadata</h2>
|
|
84
|
-
{% if _meta_ %}
|
|
85
|
-
<table>
|
|
86
|
-
<tbody>
|
|
87
|
-
<tr>
|
|
88
|
-
<th>Client IP</th>
|
|
89
|
-
<td>{{ _meta_.client_ip | default('Unknown') }}</td>
|
|
90
|
-
</tr>
|
|
91
|
-
<tr>
|
|
92
|
-
<th>Received At</th>
|
|
93
|
-
<td>{{ _meta_.received_at | default('Unknown') }}</td>
|
|
94
|
-
</tr>
|
|
95
|
-
{% if _meta_.ip_chain and _meta_.ip_chain.length %}
|
|
96
|
-
<tr>
|
|
97
|
-
<th>IP Chain</th>
|
|
98
|
-
<td>{{ _meta_.ip_chain | join(', ') }}</td>
|
|
99
|
-
</tr>
|
|
100
|
-
{% endif %}
|
|
101
|
-
</tbody>
|
|
102
|
-
</table>
|
|
103
|
-
{% else %}
|
|
104
|
-
<p>No request metadata provided.</p>
|
|
105
|
-
{% endif %}
|
|
106
|
-
</body>
|
|
107
|
-
</html>
|
package/ecosystem.config.cjs
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
const tplsrv = 'mail-magic';
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
apps: [
|
|
5
|
-
{
|
|
6
|
-
name: tplsrv,
|
|
7
|
-
script: 'npm',
|
|
8
|
-
args: 'run start',
|
|
9
|
-
cwd: `/root/deploy/${tplsrv}/source`,
|
|
10
|
-
env: {
|
|
11
|
-
NODE_ENV: 'production'
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
name: 'listmonk',
|
|
16
|
-
script: './listmonk',
|
|
17
|
-
cwd: '/var/www/ml.yesmedia.no',
|
|
18
|
-
exec_mode: 'fork',
|
|
19
|
-
instances: 1,
|
|
20
|
-
autorestart: true,
|
|
21
|
-
watch: false,
|
|
22
|
-
max_memory_restart: '1G',
|
|
23
|
-
user: 'listmonk',
|
|
24
|
-
group: 'listmonk',
|
|
25
|
-
env: {
|
|
26
|
-
NODE_ENV: 'production'
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
],
|
|
30
|
-
deploy: {
|
|
31
|
-
'mail-magic': {
|
|
32
|
-
user: 'root',
|
|
33
|
-
host: 'localhost',
|
|
34
|
-
ref: 'origin/main',
|
|
35
|
-
path: `/root/deploy/${tplsrv}`,
|
|
36
|
-
repo: `git@github.com:technomoron/${tplsrv}`,
|
|
37
|
-
'pre-deploy-local': '',
|
|
38
|
-
'pre-setup': '',
|
|
39
|
-
'post-deploy': `cd /root/deploy/${tplsrv}/source && pnpm install && pnpm upgrade && pnpm run build && pm2 start /root/deploy/ecosystem.config.cjs`
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
};
|
package/eslint.config.mjs
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import tsPlugin from '@typescript-eslint/eslint-plugin';
|
|
2
|
-
import tsParser from '@typescript-eslint/parser';
|
|
3
|
-
import eslintConfigPrettier from 'eslint-config-prettier/flat';
|
|
4
|
-
import pluginImport from 'eslint-plugin-import';
|
|
5
|
-
import jsoncParser from 'jsonc-eslint-parser';
|
|
6
|
-
const TS_FILE_GLOBS = ['**/*.{ts,tsx,mts,cts,vue}'];
|
|
7
|
-
const TS_PLUGIN_FILE_GLOBS = ['**/*.{ts,tsx,mts,cts,js,mjs,cjs,vue}'];
|
|
8
|
-
const VUE_FILE_GLOBS = ['**/*.vue'];
|
|
9
|
-
|
|
10
|
-
const { hasVueSupport, pluginVue, vueTypeScriptConfigs } = await loadVueSupport();
|
|
11
|
-
const scopedVueTypeScriptConfigs = hasVueSupport
|
|
12
|
-
? scopeVueConfigs(vueTypeScriptConfigs).map(stripTypeScriptPlugin)
|
|
13
|
-
: [];
|
|
14
|
-
const vueSpecificBlocks = hasVueSupport
|
|
15
|
-
? [
|
|
16
|
-
...scopedVueTypeScriptConfigs,
|
|
17
|
-
{
|
|
18
|
-
files: VUE_FILE_GLOBS,
|
|
19
|
-
plugins: {
|
|
20
|
-
vue: pluginVue
|
|
21
|
-
},
|
|
22
|
-
rules: {
|
|
23
|
-
'vue/html-indent': 'off', // Let Prettier handle indentation
|
|
24
|
-
'vue/max-attributes-per-line': 'off', // Let Prettier handle line breaks
|
|
25
|
-
'vue/first-attribute-linebreak': 'off', // Let Prettier handle attribute positioning
|
|
26
|
-
'vue/singleline-html-element-content-newline': 'off',
|
|
27
|
-
'vue/html-self-closing': [
|
|
28
|
-
'error',
|
|
29
|
-
{
|
|
30
|
-
html: {
|
|
31
|
-
void: 'always',
|
|
32
|
-
normal: 'always',
|
|
33
|
-
component: 'always'
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
],
|
|
37
|
-
'vue/multi-word-component-names': 'off', // Disable multi-word name restriction
|
|
38
|
-
'vue/attribute-hyphenation': ['error', 'always']
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
]
|
|
42
|
-
: [];
|
|
43
|
-
|
|
44
|
-
export default [
|
|
45
|
-
{
|
|
46
|
-
ignores: [
|
|
47
|
-
'node_modules',
|
|
48
|
-
'dist',
|
|
49
|
-
'.output',
|
|
50
|
-
'.nuxt',
|
|
51
|
-
'.netlify',
|
|
52
|
-
'node_modules/.netlify',
|
|
53
|
-
'4000/.nuxt',
|
|
54
|
-
'coverage',
|
|
55
|
-
'**/*.d.ts',
|
|
56
|
-
'configure-eslint.cjs',
|
|
57
|
-
'configure-eslint.js',
|
|
58
|
-
'*.config.js',
|
|
59
|
-
'public'
|
|
60
|
-
]
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
files: TS_PLUGIN_FILE_GLOBS,
|
|
64
|
-
plugins: {
|
|
65
|
-
'@typescript-eslint': tsPlugin
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
...vueSpecificBlocks,
|
|
69
|
-
{
|
|
70
|
-
files: ['**/*.json'],
|
|
71
|
-
languageOptions: {
|
|
72
|
-
parser: jsoncParser
|
|
73
|
-
},
|
|
74
|
-
rules: {
|
|
75
|
-
quotes: ['error', 'double'] // Enforce double quotes in JSON
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
files: ['**/*.{ts,mts,tsx,js,mjs,cjs}'],
|
|
80
|
-
languageOptions: {
|
|
81
|
-
parser: tsParser,
|
|
82
|
-
parserOptions: {
|
|
83
|
-
ecmaVersion: 2023,
|
|
84
|
-
sourceType: 'module',
|
|
85
|
-
extraFileExtensions: ['.vue']
|
|
86
|
-
},
|
|
87
|
-
globals: {
|
|
88
|
-
RequestInit: 'readonly',
|
|
89
|
-
process: 'readonly',
|
|
90
|
-
Capacitor: 'readonly',
|
|
91
|
-
chrome: 'readonly'
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
plugins: {
|
|
95
|
-
import: pluginImport
|
|
96
|
-
},
|
|
97
|
-
rules: {
|
|
98
|
-
'import/order': [
|
|
99
|
-
'error',
|
|
100
|
-
{
|
|
101
|
-
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'],
|
|
102
|
-
'newlines-between': 'always',
|
|
103
|
-
alphabetize: { order: 'asc', caseInsensitive: true }
|
|
104
|
-
}
|
|
105
|
-
],
|
|
106
|
-
'@typescript-eslint/no-explicit-any': ['warn'],
|
|
107
|
-
'@typescript-eslint/no-unused-vars': ['warn'],
|
|
108
|
-
'@typescript-eslint/no-require-imports': 'off'
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
...eslintConfigPrettier
|
|
113
|
-
}
|
|
114
|
-
];
|
|
115
|
-
|
|
116
|
-
async function loadVueSupport() {
|
|
117
|
-
try {
|
|
118
|
-
const [vuePluginModule, vueConfigModule] = await Promise.all([
|
|
119
|
-
import('eslint-plugin-vue'),
|
|
120
|
-
import('@vue/eslint-config-typescript')
|
|
121
|
-
]);
|
|
122
|
-
|
|
123
|
-
const pluginVue = unwrapDefault(vuePluginModule);
|
|
124
|
-
const { defineConfigWithVueTs, vueTsConfigs } = vueConfigModule;
|
|
125
|
-
const configs = defineConfigWithVueTs(vueTsConfigs.recommended);
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
hasVueSupport: Boolean(pluginVue && configs.length),
|
|
129
|
-
pluginVue,
|
|
130
|
-
vueTypeScriptConfigs: configs
|
|
131
|
-
};
|
|
132
|
-
} catch (error) {
|
|
133
|
-
if (isModuleNotFoundError(error)) {
|
|
134
|
-
return {
|
|
135
|
-
hasVueSupport: false,
|
|
136
|
-
pluginVue: null,
|
|
137
|
-
vueTypeScriptConfigs: []
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
throw error;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function scopeVueConfigs(configs) {
|
|
146
|
-
return configs.map((config) => {
|
|
147
|
-
const files = config.files ?? [];
|
|
148
|
-
const referencesOnlyVueFiles = files.length > 0 && files.every((pattern) => pattern.includes('.vue'));
|
|
149
|
-
const hasVuePlugin = Boolean(config.plugins?.vue);
|
|
150
|
-
|
|
151
|
-
if (hasVuePlugin || referencesOnlyVueFiles) {
|
|
152
|
-
return {
|
|
153
|
-
...config,
|
|
154
|
-
files: VUE_FILE_GLOBS
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return {
|
|
159
|
-
...config,
|
|
160
|
-
files: TS_FILE_GLOBS
|
|
161
|
-
};
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function stripTypeScriptPlugin(config) {
|
|
166
|
-
const { plugins = {}, ...rest } = config;
|
|
167
|
-
|
|
168
|
-
if (!plugins['@typescript-eslint']) {
|
|
169
|
-
return config;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const otherPlugins = { ...plugins };
|
|
173
|
-
delete otherPlugins['@typescript-eslint'];
|
|
174
|
-
const hasOtherPlugins = Object.keys(otherPlugins).length > 0;
|
|
175
|
-
|
|
176
|
-
return {
|
|
177
|
-
...rest,
|
|
178
|
-
...(hasOtherPlugins ? { plugins: otherPlugins } : {})
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
function unwrapDefault(module) {
|
|
183
|
-
return module?.default ?? module;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function isModuleNotFoundError(error) {
|
|
187
|
-
if (!error) {
|
|
188
|
-
return false;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (error.code === 'ERR_MODULE_NOT_FOUND' || error.code === 'MODULE_NOT_FOUND') {
|
|
192
|
-
return true;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return typeof error.message === 'string' && error.message.includes('Cannot find module');
|
|
196
|
-
}
|
package/lintconfig.cjs
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { execSync, spawnSync } = require('child_process');
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const os = require('os');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
|
|
7
|
-
const RELEASE_API_URL = 'https://api.github.com/repos/technomoron/vscode-eslint-defaults/releases/latest';
|
|
8
|
-
const INSTALLER_ASSET_NAME = 'installer.tgz';
|
|
9
|
-
|
|
10
|
-
async function fetch_json(url) {
|
|
11
|
-
const response = await fetch(url, {
|
|
12
|
-
headers: {
|
|
13
|
-
'User-Agent': 'vscode-eslint-defaults-lintconfig',
|
|
14
|
-
Accept: 'application/vnd.github+json'
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
if (!response.ok) {
|
|
19
|
-
throw new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return response.json();
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async function download_asset(url, destination) {
|
|
26
|
-
const response = await fetch(url, {
|
|
27
|
-
headers: {
|
|
28
|
-
'User-Agent': 'vscode-eslint-defaults-lintconfig'
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
if (!response.ok) {
|
|
33
|
-
throw new Error(`Failed to download ${url}: ${response.status} ${response.statusText}`);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const buffer = Buffer.from(await response.arrayBuffer());
|
|
37
|
-
fs.writeFileSync(destination, buffer);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async function run() {
|
|
41
|
-
const release = await fetch_json(RELEASE_API_URL);
|
|
42
|
-
const assets = Array.isArray(release.assets) ? release.assets : [];
|
|
43
|
-
const asset = assets.find((item) => item.name === INSTALLER_ASSET_NAME);
|
|
44
|
-
|
|
45
|
-
if (!asset?.browser_download_url) {
|
|
46
|
-
throw new Error('Latest release does not include installer.tgz.');
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const temp_dir = fs.mkdtempSync(path.join(os.tmpdir(), 'lintconfig-'));
|
|
50
|
-
const tgz_path = path.join(temp_dir, INSTALLER_ASSET_NAME);
|
|
51
|
-
const args = process.argv.slice(2);
|
|
52
|
-
let exit_code = 0;
|
|
53
|
-
|
|
54
|
-
try {
|
|
55
|
-
await download_asset(asset.browser_download_url, tgz_path);
|
|
56
|
-
execSync(`tar -xzf "${tgz_path}" -C "${process.cwd()}"`, { stdio: 'inherit' });
|
|
57
|
-
|
|
58
|
-
const configure_path = path.join(process.cwd(), 'configure-eslint.cjs');
|
|
59
|
-
if (!fs.existsSync(configure_path)) {
|
|
60
|
-
throw new Error('configure-eslint.cjs not found after extraction.');
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const result = spawnSync(process.execPath, [configure_path, ...args], { stdio: 'inherit' });
|
|
64
|
-
if (result.status !== 0) {
|
|
65
|
-
exit_code = result.status ?? 1;
|
|
66
|
-
} else {
|
|
67
|
-
fs.unlinkSync(configure_path);
|
|
68
|
-
}
|
|
69
|
-
} finally {
|
|
70
|
-
fs.rmSync(temp_dir, { recursive: true, force: true });
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (exit_code !== 0) {
|
|
74
|
-
process.exit(exit_code);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
run().catch((error) => {
|
|
79
|
-
console.error(error.message || error);
|
|
80
|
-
process.exit(1);
|
|
81
|
-
});
|