comment-variables 0.6.2 → 0.8.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/README.md +2 -22
- package/comments.config.js +1 -21
- package/library/_commons/constants/bases.js +0 -58
- package/library/_commons/rules/compress.js +5 -3
- package/library/_commons/rules/resolve.js +4 -2
- package/library/_commons/utilities/flows.js +4 -1
- package/library/_commons/utilities/helpers.js +2 -10
- package/library/index.js +16 -22
- package/package.json +2 -4
- package/library/_commons/constants/regexes.js +0 -13
- package/library/_commons/schemas/config.js +0 -67
- package/library/_commons/utilities/flatten-config-data.js +0 -145
- package/library/_commons/utilities/resolve-config.js +0 -110
package/README.md
CHANGED
|
@@ -68,8 +68,6 @@ const data = {
|
|
|
68
68
|
definitions: Object.freeze({
|
|
69
69
|
exitDueToFailure:
|
|
70
70
|
"Terminates the whole process with a 'failure' code (1).", // $COMMENT#JSDOC#DEFINITIONS#EXITDUETOFAILURE
|
|
71
|
-
escapeRegex:
|
|
72
|
-
'Escapes all regex characters with a `"\\"` in a string to prepare it for use in a regex.', // $COMMENT#JSDOC#DEFINITIONS#ESCAPEREGEX
|
|
73
71
|
makeRuleResolve:
|
|
74
72
|
"The utility that creates the resolve rule based on the flattened config data, used to transform $COMMENT#* placeholders into actual comments.", // $COMMENT#JSDOC#DEFINITIONS#MAKERULERESOLVE
|
|
75
73
|
makeRuleCompress:
|
|
@@ -80,15 +78,10 @@ const data = {
|
|
|
80
78
|
"The flow that resolves $COMMENT#* placeholders intro actual comments.", // $COMMENT#JSDOC#DEFINITIONS#RESOLVECOMMENTSFLOW
|
|
81
79
|
compressCommentsFlow:
|
|
82
80
|
"The flow that compresses actual comments into $COMMENT#* placeholders.", // $COMMENT#JSDOC#DEFINITIONS#COMPRESSCOMMENTSFLOW
|
|
83
|
-
flattenConfigData:
|
|
84
|
-
"Flattens the config's data property into a one-dimensional object of $COMMENT-*-like keys and string values.", // $COMMENT#JSDOC#DEFINITIONS#FLATTENCONFIGDATA
|
|
85
|
-
resolveConfig:
|
|
86
|
-
"Verifies, validates and resolves the config path to retrieve the config's data and ignores.", // $COMMENT#JSDOC#DEFINITIONS#RESOLVECONFIG
|
|
87
81
|
logError:
|
|
88
82
|
'Logs an error to the console depending on its type. (`"error"` or `"warning"`.)', // $COMMENT#JSDOC#DEFINITIONS#LOGERROR
|
|
89
83
|
}),
|
|
90
84
|
params: Object.freeze({
|
|
91
|
-
string: "The string.", // $COMMENT#JSDOC#PARAMS#STRING
|
|
92
85
|
flattenedConfigData:
|
|
93
86
|
"The flattened config data, with $COMMENT#* placeholders as keys and actual comments as values.", // $COMMENT#JSDOC#PARAMS#FLATTENEDCONFIGDATA
|
|
94
87
|
reversedFlattenedConfigData:
|
|
@@ -99,29 +92,16 @@ const data = {
|
|
|
99
92
|
"The array of paths and globs for the flow's ESLint instance to ignore.", // $COMMENT#JSDOC#PARAMS#IGNORES
|
|
100
93
|
eitherFlattenedConfigData:
|
|
101
94
|
"Either the flattened config data or the reversed flattened config data, since they share the same structure.", // $COMMENT#JSDOC#PARAMS#EITHERFLATTENEDCONFIGDATA
|
|
102
|
-
|
|
103
|
-
"The config's data property. (Values are typed `unknown` given the limitations in typing recursive values in JSDoc.)", // $COMMENT#JSDOC#PARAMS#CONFIGDATA
|
|
104
|
-
configDataMapOption:
|
|
105
|
-
"The map housing the flattened keys with their values and sources through recursion, instantiated as a `new Map()`.", // $COMMENT#JSDOC#PARAMS#CONFIGDATAMAPOPTION
|
|
106
|
-
parentKeysOption:
|
|
107
|
-
"The list of keys that are parent to the key at hand given the recursive nature of the config's data's data structure, instantiated as an empty array of strings (`[]`).", // $COMMENT#JSDOC#PARAMS#PARENTKEYSOPTION
|
|
108
|
-
configPath:
|
|
109
|
-
'The path of the config from `comments.config.js`, or from a config passed via the `--config` flag in the CLI, or from one passed via `"commentVariables.config": true` in `.vscode/settings.json` for the VS Code Extension.', // $COMMENT#JSDOC#PARAMS#CONFIGPATH
|
|
95
|
+
error: "The error object being handle for the logging.", // $COMMENT#JSDOC#PARAMS#ERROR
|
|
110
96
|
options: "The additional options as follows:", // $COMMENT#JSDOC#PARAMS#OPTIONS
|
|
111
97
|
settings: "The required settings as follows:", // $COMMENT#JSDOC#PARAMS#SETTINGS
|
|
112
|
-
error: "The error object being handle for the logging.", // $COMMENT#JSDOC#PARAMS#ERROR
|
|
113
98
|
}),
|
|
114
99
|
returns: Object.freeze({
|
|
115
100
|
exitDueToFailure:
|
|
116
101
|
"Never. (Somehow typing needs to be explicit for unreachable code inference.)", // $COMMENT#JSDOC#RETURNS#EXITDUETOFAILURE
|
|
117
|
-
escapeRegex: `The string with regex characters escaped.`, // $COMMENT#JSDOC#RETURNS#ESCAPEREGEX
|
|
118
102
|
makeRuleResolve: "The resolve rule based on the flattened config data.", // $COMMENT#JSDOC#RETURNS#MAKERULERESOLVE
|
|
119
103
|
makeRuleCompress:
|
|
120
104
|
"The compress rule based on the reversed flattened config data.", // $COMMENT#JSDOC#RETURNS#MAKERULECOMPRESS
|
|
121
|
-
flattenConfigData:
|
|
122
|
-
"Both the flattened config data and its reversed version to ensure the strict reversibility of the `resolve` and `compress` commands in a success object (`success: true`). Errors are bubbled up during failures so they can be reused differently on the CLI and the VS Code Extension in a failure object (`success: false`).", // $COMMENT#JSDOC#RETURNS#FLATTENCONFIGDATA
|
|
123
|
-
resolveConfig:
|
|
124
|
-
"The flattened config data, the reverse flattened config data, the verified config path, the raw passed ignores, and the original config. Errors are returned during failures so they can be reused differently on the CLI and the VS Code Extension.", // $COMMENT#JSDOC#RETURNS#RESOLVECONFIG
|
|
125
105
|
}),
|
|
126
106
|
}),
|
|
127
107
|
};
|
|
@@ -138,4 +118,4 @@ export default config;
|
|
|
138
118
|
|
|
139
119
|
And yes, even comments within JavaScript and TypeScript blocks in Markdown files are addressed.
|
|
140
120
|
|
|
141
|
-
_Leverage the
|
|
121
|
+
_Leverage the power of JavaScript to programmatically design your JavaScript comments._
|
package/comments.config.js
CHANGED
|
@@ -17,8 +17,6 @@ const data = {
|
|
|
17
17
|
definitions: Object.freeze({
|
|
18
18
|
exitDueToFailure:
|
|
19
19
|
"Terminates the whole process with a 'failure' code (1).", // $COMMENT#JSDOC#DEFINITIONS#EXITDUETOFAILURE
|
|
20
|
-
escapeRegex:
|
|
21
|
-
'Escapes all regex characters with a `"\\"` in a string to prepare it for use in a regex.', // $COMMENT#JSDOC#DEFINITIONS#ESCAPEREGEX
|
|
22
20
|
makeRuleResolve:
|
|
23
21
|
"The utility that creates the resolve rule based on the flattened config data, used to transform $COMMENT#* placeholders into actual comments.", // $COMMENT#JSDOC#DEFINITIONS#MAKERULERESOLVE
|
|
24
22
|
makeRuleCompress:
|
|
@@ -29,15 +27,10 @@ const data = {
|
|
|
29
27
|
"The flow that resolves $COMMENT#* placeholders intro actual comments.", // $COMMENT#JSDOC#DEFINITIONS#RESOLVECOMMENTSFLOW
|
|
30
28
|
compressCommentsFlow:
|
|
31
29
|
"The flow that compresses actual comments into $COMMENT#* placeholders.", // $COMMENT#JSDOC#DEFINITIONS#COMPRESSCOMMENTSFLOW
|
|
32
|
-
flattenConfigData:
|
|
33
|
-
"Flattens the config's data property into a one-dimensional object of $COMMENT-*-like keys and string values.", // $COMMENT#JSDOC#DEFINITIONS#FLATTENCONFIGDATA
|
|
34
|
-
resolveConfig:
|
|
35
|
-
"Verifies, validates and resolves the config path to retrieve the config's data and ignores.", // $COMMENT#JSDOC#DEFINITIONS#RESOLVECONFIG
|
|
36
30
|
logError:
|
|
37
31
|
'Logs an error to the console depending on its type. (`"error"` or `"warning"`.)', // $COMMENT#JSDOC#DEFINITIONS#LOGERROR
|
|
38
32
|
}),
|
|
39
33
|
params: Object.freeze({
|
|
40
|
-
string: "The string.", // $COMMENT#JSDOC#PARAMS#STRING
|
|
41
34
|
flattenedConfigData:
|
|
42
35
|
"The flattened config data, with $COMMENT#* placeholders as keys and actual comments as values.", // $COMMENT#JSDOC#PARAMS#FLATTENEDCONFIGDATA
|
|
43
36
|
reversedFlattenedConfigData:
|
|
@@ -48,29 +41,16 @@ const data = {
|
|
|
48
41
|
"The array of paths and globs for the flow's ESLint instance to ignore.", // $COMMENT#JSDOC#PARAMS#IGNORES
|
|
49
42
|
eitherFlattenedConfigData:
|
|
50
43
|
"Either the flattened config data or the reversed flattened config data, since they share the same structure.", // $COMMENT#JSDOC#PARAMS#EITHERFLATTENEDCONFIGDATA
|
|
51
|
-
|
|
52
|
-
"The config's data property. (Values are typed `unknown` given the limitations in typing recursive values in JSDoc.)", // $COMMENT#JSDOC#PARAMS#CONFIGDATA
|
|
53
|
-
configDataMapOption:
|
|
54
|
-
"The map housing the flattened keys with their values and sources through recursion, instantiated as a `new Map()`.", // $COMMENT#JSDOC#PARAMS#CONFIGDATAMAPOPTION
|
|
55
|
-
parentKeysOption:
|
|
56
|
-
"The list of keys that are parent to the key at hand given the recursive nature of the config's data's data structure, instantiated as an empty array of strings (`[]`).", // $COMMENT#JSDOC#PARAMS#PARENTKEYSOPTION
|
|
57
|
-
configPath:
|
|
58
|
-
'The path of the config from `comments.config.js`, or from a config passed via the `--config` flag in the CLI, or from one passed via `"commentVariables.config": true` in `.vscode/settings.json` for the VS Code Extension.', // $COMMENT#JSDOC#PARAMS#CONFIGPATH
|
|
44
|
+
error: "The error object being handle for the logging.", // $COMMENT#JSDOC#PARAMS#ERROR
|
|
59
45
|
options: "The additional options as follows:", // $COMMENT#JSDOC#PARAMS#OPTIONS
|
|
60
46
|
settings: "The required settings as follows:", // $COMMENT#JSDOC#PARAMS#SETTINGS
|
|
61
|
-
error: "The error object being handle for the logging.", // $COMMENT#JSDOC#PARAMS#ERROR
|
|
62
47
|
}),
|
|
63
48
|
returns: Object.freeze({
|
|
64
49
|
exitDueToFailure:
|
|
65
50
|
"Never. (Somehow typing needs to be explicit for unreachable code inference.)", // $COMMENT#JSDOC#RETURNS#EXITDUETOFAILURE
|
|
66
|
-
escapeRegex: `The string with regex characters escaped.`, // $COMMENT#JSDOC#RETURNS#ESCAPEREGEX
|
|
67
51
|
makeRuleResolve: "The resolve rule based on the flattened config data.", // $COMMENT#JSDOC#RETURNS#MAKERULERESOLVE
|
|
68
52
|
makeRuleCompress:
|
|
69
53
|
"The compress rule based on the reversed flattened config data.", // $COMMENT#JSDOC#RETURNS#MAKERULECOMPRESS
|
|
70
|
-
flattenConfigData:
|
|
71
|
-
"Both the flattened config data and its reversed version to ensure the strict reversibility of the `resolve` and `compress` commands in a success object (`success: true`). Errors are bubbled up during failures so they can be reused differently on the CLI and the VS Code Extension in a failure object (`success: false`).", // $COMMENT#JSDOC#RETURNS#FLATTENCONFIGDATA
|
|
72
|
-
resolveConfig:
|
|
73
|
-
"The flattened config data, the reverse flattened config data, the verified config path, the raw passed ignores, and the original config. Errors are returned during failures so they can be reused differently on the CLI and the VS Code Extension.", // $COMMENT#JSDOC#RETURNS#RESOLVECONFIG
|
|
74
54
|
}),
|
|
75
55
|
}),
|
|
76
56
|
};
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
|
|
4
|
-
import tseslint from "typescript-eslint";
|
|
5
|
-
|
|
6
|
-
// plugin name
|
|
7
|
-
export const commentVariablesPluginName = "comment-variables";
|
|
8
|
-
|
|
9
4
|
// rule names
|
|
10
5
|
export const resolveRuleName = "resolve";
|
|
11
6
|
export const compressRuleName = "compress";
|
|
@@ -18,25 +13,6 @@ export const hasPackageJson = fs.existsSync(path.join(cwd, "package.json"));
|
|
|
18
13
|
// to prevent irreversible changes
|
|
19
14
|
export const hasGitFolder = fs.existsSync(path.join(cwd, ".git"));
|
|
20
15
|
|
|
21
|
-
// comments.config.js // comment-variables-resolve-config
|
|
22
|
-
export const defaultConfigFileName = "comments.config.js";
|
|
23
|
-
|
|
24
|
-
// flags // comment-variables-resolve-config
|
|
25
|
-
export const configFlag = "--config";
|
|
26
|
-
export const lintConfigImportsFlag = "--lint-config-imports";
|
|
27
|
-
export const myIgnoresOnlyFlag = "--my-ignores-only";
|
|
28
|
-
|
|
29
|
-
// ESLint ignores
|
|
30
|
-
export const knownIgnores = [
|
|
31
|
-
"node_modules",
|
|
32
|
-
"dist",
|
|
33
|
-
"out",
|
|
34
|
-
".next",
|
|
35
|
-
".react-router",
|
|
36
|
-
".parcel-cache",
|
|
37
|
-
".react-router-parcel",
|
|
38
|
-
];
|
|
39
|
-
|
|
40
16
|
// ESLint file globs
|
|
41
17
|
export const allJSTSFileGlobs = [
|
|
42
18
|
"**/*.js",
|
|
@@ -55,37 +31,3 @@ export const allMDVirtualJSTSFileGlobs = [
|
|
|
55
31
|
"**/*.md/*.cjs",
|
|
56
32
|
"**/*.md/*.mjs",
|
|
57
33
|
];
|
|
58
|
-
|
|
59
|
-
// default ESLint config language options
|
|
60
|
-
export const typeScriptAndJSXCompatible = {
|
|
61
|
-
// for compatibility with TypeScript (.ts and .tsx)
|
|
62
|
-
parser: tseslint.parser,
|
|
63
|
-
// for compatibility with JSX (React, etc.)
|
|
64
|
-
parserOptions: {
|
|
65
|
-
ecmaFeatures: {
|
|
66
|
-
jsx: true,
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
// messageId
|
|
72
|
-
export const placeholderMessageId = "placeholderMessageId";
|
|
73
|
-
|
|
74
|
-
// placeholder prefix // comment-variables-resolve-config
|
|
75
|
-
export const $COMMENT = "$COMMENT";
|
|
76
|
-
|
|
77
|
-
// success objects // comment-variables-resolve-config
|
|
78
|
-
export const successFalse = Object.freeze({
|
|
79
|
-
success: false,
|
|
80
|
-
});
|
|
81
|
-
export const successTrue = Object.freeze({
|
|
82
|
-
success: true,
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
// error objects // comment-variables-resolve-config
|
|
86
|
-
export const typeError = Object.freeze({
|
|
87
|
-
type: "error",
|
|
88
|
-
});
|
|
89
|
-
export const typeWarning = Object.freeze({
|
|
90
|
-
type: "warning",
|
|
91
|
-
});
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
$COMMENT,
|
|
3
|
+
escapeRegex,
|
|
4
|
+
placeholderMessageId,
|
|
5
|
+
} from "comment-variables-resolve-config";
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* The utility that creates the compress rule based on the reversed flattened config data, used to transform actual comments into $COMMENT#* placeholders.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
flattenedConfigPlaceholderRegex,
|
|
3
|
+
placeholderMessageId,
|
|
4
|
+
} from "comment-variables-resolve-config";
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* The utility that creates the resolve rule based on the flattened config data, used to transform $COMMENT#* placeholders into actual comments.
|
|
@@ -3,12 +3,15 @@ import markdown from "@eslint/markdown";
|
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
commentVariablesPluginName,
|
|
6
|
+
typeScriptAndJSXCompatible,
|
|
7
|
+
} from "comment-variables-resolve-config";
|
|
8
|
+
|
|
9
|
+
import {
|
|
6
10
|
resolveRuleName,
|
|
7
11
|
compressRuleName,
|
|
8
12
|
allJSTSFileGlobs,
|
|
9
13
|
allMDFileGlobs,
|
|
10
14
|
allMDVirtualJSTSFileGlobs,
|
|
11
|
-
typeScriptAndJSXCompatible,
|
|
12
15
|
} from "../constants/bases.js";
|
|
13
16
|
import { ruleNames_makeRules } from "../constants/rules.js";
|
|
14
17
|
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export const exitDueToFailure = () => process.exit(1);
|
|
8
8
|
|
|
9
|
+
/* logError */
|
|
10
|
+
|
|
9
11
|
/**
|
|
10
12
|
* Logs an error to the console depending on its type. (`"error"` or `"warning"`.)
|
|
11
13
|
* @param {{type: "error" | "warning"; message: string}} error The error object being handle for the logging.
|
|
@@ -23,13 +25,3 @@ export const logError = (error) => {
|
|
|
23
25
|
break;
|
|
24
26
|
}
|
|
25
27
|
};
|
|
26
|
-
|
|
27
|
-
/* escapeRegex */ // comment-variables-resolve-config
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Escapes all regex characters with a `"\"` in a string to prepare it for use in a regex.
|
|
31
|
-
* @param {string} string The string.
|
|
32
|
-
* @returns The string with regex characters escaped.
|
|
33
|
-
*/
|
|
34
|
-
export const escapeRegex = (string) =>
|
|
35
|
-
string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
package/library/index.js
CHANGED
|
@@ -3,22 +3,23 @@
|
|
|
3
3
|
|
|
4
4
|
import path from "path";
|
|
5
5
|
|
|
6
|
+
import resolveConfig, {
|
|
7
|
+
defaultConfigFileName,
|
|
8
|
+
configFlag,
|
|
9
|
+
lintConfigImportsFlag,
|
|
10
|
+
myIgnoresOnlyFlag,
|
|
11
|
+
knownIgnores,
|
|
12
|
+
} from "comment-variables-resolve-config";
|
|
13
|
+
|
|
6
14
|
import {
|
|
7
15
|
cwd,
|
|
8
16
|
hasPackageJson,
|
|
9
17
|
hasGitFolder,
|
|
10
|
-
defaultConfigFileName, // shared
|
|
11
|
-
configFlag, // shared
|
|
12
|
-
lintConfigImportsFlag, // shared
|
|
13
|
-
myIgnoresOnlyFlag, // shared
|
|
14
|
-
knownIgnores, // shared
|
|
15
18
|
resolveRuleName,
|
|
16
19
|
compressRuleName,
|
|
17
20
|
} from "./_commons/constants/bases.js";
|
|
18
21
|
|
|
19
22
|
import { exitDueToFailure, logError } from "./_commons/utilities/helpers.js";
|
|
20
|
-
import { resolveConfig } from "./_commons/utilities/resolve-config.js"; // shared
|
|
21
|
-
import { findAllImports } from "find-all-js-imports"; // own package
|
|
22
23
|
import {
|
|
23
24
|
resolveCommentsFlow,
|
|
24
25
|
compressCommentsFlow,
|
|
@@ -61,18 +62,23 @@ const passedConfigPath =
|
|
|
61
62
|
// defaults to comments.config.js if no --config flag is set
|
|
62
63
|
const rawConfigPath = passedConfigPath ?? path.join(cwd, defaultConfigFileName);
|
|
63
64
|
|
|
65
|
+
console.log(`Resolving config at ${rawConfigPath}...`);
|
|
66
|
+
|
|
64
67
|
const resolveConfigResults = await resolveConfig(rawConfigPath);
|
|
65
68
|
if (!resolveConfigResults.success) {
|
|
66
69
|
resolveConfigResults.errors.forEach((e) => logError(e));
|
|
67
70
|
exitDueToFailure();
|
|
68
71
|
}
|
|
69
72
|
|
|
73
|
+
console.log("Config resolved.");
|
|
74
|
+
|
|
70
75
|
const {
|
|
71
76
|
config,
|
|
72
77
|
flattenedConfigData,
|
|
73
78
|
reversedFlattenedConfigData,
|
|
74
79
|
configPath,
|
|
75
80
|
passedIgnores,
|
|
81
|
+
rawConfigAndImportPaths,
|
|
76
82
|
} = resolveConfigResults;
|
|
77
83
|
|
|
78
84
|
skipDetails || console.log("Running with config:", config);
|
|
@@ -88,21 +94,9 @@ skipDetails || console.log("Passed ignores are:", passedIgnores);
|
|
|
88
94
|
// ADDRESSES THE --lint-config-imports FLAG, GIVEN THAT THE FILES IMPORTED BY THE CONFIG ARE IGNORED BY DEFAULT.
|
|
89
95
|
|
|
90
96
|
const lintConfigImports = commands.indexOf(lintConfigImportsFlag) >= 2;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const findAllImportsResults = findAllImports(configPath);
|
|
95
|
-
if (!findAllImportsResults.success) {
|
|
96
|
-
findAllImportsResults.errors.forEach((e) => logError(e));
|
|
97
|
-
console.warn(
|
|
98
|
-
"Defaulting to --lint-config-imports flag behavior, not ignoring config path imports, only the config path itself."
|
|
99
|
-
);
|
|
100
|
-
} else {
|
|
101
|
-
rawConfigPathIgnores = [...findAllImportsResults.visitedSet] ?? [
|
|
102
|
-
configPath,
|
|
103
|
-
];
|
|
104
|
-
}
|
|
105
|
-
}
|
|
97
|
+
const rawConfigPathIgnores = lintConfigImports
|
|
98
|
+
? [configPath]
|
|
99
|
+
: rawConfigAndImportPaths;
|
|
106
100
|
|
|
107
101
|
// the ignore paths must be relative
|
|
108
102
|
const configPathIgnores = rawConfigPathIgnores.map((e) =>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "comment-variables",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "A CLI tool for configuring, managing and maintaining JavaScript comments as JavaScript variables.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"jscomments": "./library/index.js",
|
|
@@ -26,10 +26,8 @@
|
|
|
26
26
|
"type": "module",
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@eslint/markdown": "^6.5.0",
|
|
29
|
+
"comment-variables-resolve-config": "^1.3.0",
|
|
29
30
|
"eslint": "^9.29.0",
|
|
30
|
-
"find-all-js-imports": "^1.0.0",
|
|
31
|
-
"tsconfig-paths": "^4.2.0",
|
|
32
|
-
"typescript-eslint": "^8.34.1",
|
|
33
31
|
"zod": "^3.25.67"
|
|
34
32
|
},
|
|
35
33
|
"devDependencies": {
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { $COMMENT } from "./bases.js";
|
|
2
|
-
|
|
3
|
-
import { escapeRegex } from "../utilities/helpers.js";
|
|
4
|
-
|
|
5
|
-
// comment-variables-resolve-config
|
|
6
|
-
export const configKeyRegex = /^[\p{Ll}\p{Lu}\p{Lo}\p{Pd}\p{Pc}\p{N}\s]+$/u;
|
|
7
|
-
// comment-variables-resolve-config
|
|
8
|
-
export const flattenedConfigKeyRegex = /^[\p{Lu}\p{Lo}\p{Pd}\p{Pc}\p{N}#]+$/u; // same as configKeyRegex but without lowercase letters (\p{Ll}), without whitespaces (\s which are replaced by underscores) and with the '#' character (that links each subkey together)
|
|
9
|
-
// comment-variables-resolve-config
|
|
10
|
-
export const flattenedConfigPlaceholderRegex = new RegExp(
|
|
11
|
-
`${escapeRegex($COMMENT)}#([\\p{Lu}\\p{Lo}\\p{Pd}\\p{Pc}\\p{N}#_]+)`,
|
|
12
|
-
"gu"
|
|
13
|
-
); // same as flattenedConfigKeyRegex but taking the prefix $COMMENT and its # into consideration, removing ^ and $ in the capture group, and using _ as replacement for whitesplaces, globally
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
|
|
3
|
-
import { configKeyRegex } from "../constants/regexes.js";
|
|
4
|
-
|
|
5
|
-
export const ConfigDataSchema = z
|
|
6
|
-
.lazy(() =>
|
|
7
|
-
z.record(
|
|
8
|
-
z.unknown().superRefine((val, ctx) => {
|
|
9
|
-
if (typeof val === "string") {
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
if (typeof val === "object" && val && !Array.isArray(val)) {
|
|
14
|
-
const parsed = ConfigDataSchema.safeParse(val);
|
|
15
|
-
if (!parsed.success) {
|
|
16
|
-
for (const issue of parsed.error.issues) {
|
|
17
|
-
ctx.addIssue({
|
|
18
|
-
...issue,
|
|
19
|
-
path: [...ctx.path, ...issue.path],
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
ctx.addIssue({
|
|
27
|
-
code: z.ZodIssueCode.custom,
|
|
28
|
-
message: `Value \`${val}\` of type "${typeof val}" should be a string or a nested object.`,
|
|
29
|
-
path: ctx.path,
|
|
30
|
-
});
|
|
31
|
-
})
|
|
32
|
-
)
|
|
33
|
-
)
|
|
34
|
-
.superRefine((obj, ctx) => {
|
|
35
|
-
for (const key of Object.keys(obj)) {
|
|
36
|
-
if (key.includes("$")) {
|
|
37
|
-
ctx.addIssue({
|
|
38
|
-
code: z.ZodIssueCode.custom,
|
|
39
|
-
message: `Key "${key}" should not include the "$" character.`,
|
|
40
|
-
path: [key],
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
if (key.includes("#")) {
|
|
44
|
-
ctx.addIssue({
|
|
45
|
-
code: z.ZodIssueCode.custom,
|
|
46
|
-
message: `Key "${key}" should not include the "#" character.`,
|
|
47
|
-
path: [key],
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
if (!configKeyRegex.test(key)) {
|
|
51
|
-
ctx.addIssue({
|
|
52
|
-
code: z.ZodIssueCode.custom,
|
|
53
|
-
message: `Key "${key}" should only include whitespaces (s), lowercase letters (Ll), uppercase letters (Lu), other letters (Lo), numbers (N), dash punctuation (Pd), and connector punctuation (Pc).`,
|
|
54
|
-
path: [key],
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
export const ConfigIgnoresSchema = z.array(
|
|
61
|
-
z.string({
|
|
62
|
-
message: `The config's "ignores" key array should be made of string or be empty.`,
|
|
63
|
-
}),
|
|
64
|
-
{
|
|
65
|
-
message: `The config's "ignores" key value should be an array of strings (or at the very least an empty array).`,
|
|
66
|
-
}
|
|
67
|
-
);
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import { successFalse, successTrue, typeError } from "../constants/bases.js";
|
|
2
|
-
import { flattenedConfigKeyRegex } from "../constants/regexes.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @typedef {Record<string, unknown>} ConfigData
|
|
6
|
-
*
|
|
7
|
-
* @typedef {{
|
|
8
|
-
* success: false;
|
|
9
|
-
* errors: Array<{ type: "error" | "warning"; message: string }>;
|
|
10
|
-
* } | {
|
|
11
|
-
* success: true;
|
|
12
|
-
* flattenedConfigData: Record<string, string>;
|
|
13
|
-
* reversedFlattenedConfigData: Record<string, string>;
|
|
14
|
-
* }} FlattenConfigDataResults
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Flattens the config's data property into a one-dimensional object of $COMMENT-*-like keys and string values.
|
|
19
|
-
* @param {ConfigData} configData The config's data property. (Values are typed `unknown` given the limitations in typing recursive values in JSDoc.)
|
|
20
|
-
* @param {Object} [options] The additional options as follows:
|
|
21
|
-
* @param {Map<string, {value: string; source: string}>} [options.configDataMap] The map housing the flattened keys with their values and sources through recursion, instantiated as a `new Map()`.
|
|
22
|
-
* @param {string[]} [options.parentKeys] The list of keys that are parent to the key at hand given the recursive nature of the config's data's data structure, instantiated as an empty array of strings (`[]`).
|
|
23
|
-
* @returns Both the flattened config data and its reversed version to ensure the strict reversibility of the `resolve` and `compress` commands in a success object (`success: true`). Errors are bubbled up during failures so they can be reused differently on the CLI and the VS Code Extension in a failure object (`success: false`).
|
|
24
|
-
*/
|
|
25
|
-
export const flattenConfigData = (
|
|
26
|
-
configData,
|
|
27
|
-
{ configDataMap = new Map(), parentKeys = [] } = {}
|
|
28
|
-
) => {
|
|
29
|
-
for (const [key, value] of Object.entries(configData)) {
|
|
30
|
-
const newKeys = [...parentKeys, key];
|
|
31
|
-
const normalizedKey = newKeys
|
|
32
|
-
.map((k) => k.toUpperCase())
|
|
33
|
-
.join("#")
|
|
34
|
-
.replace(/\s/g, "_");
|
|
35
|
-
const source = newKeys.join(" > ");
|
|
36
|
-
|
|
37
|
-
if (typeof value === "string") {
|
|
38
|
-
if (configDataMap.has(normalizedKey)) {
|
|
39
|
-
// checks the uniqueness of each normalized key
|
|
40
|
-
return {
|
|
41
|
-
...successFalse,
|
|
42
|
-
errors: [
|
|
43
|
-
{
|
|
44
|
-
...typeError,
|
|
45
|
-
message: `ERROR. The normalized key "${normalizedKey}" has already been assigned. Check between the two following key paths: \n"${
|
|
46
|
-
configDataMap.get(normalizedKey).source
|
|
47
|
-
}" \n"${source}"`,
|
|
48
|
-
},
|
|
49
|
-
],
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
configDataMap.set(normalizedKey, {
|
|
54
|
-
value,
|
|
55
|
-
source,
|
|
56
|
-
});
|
|
57
|
-
} else if (typeof value === "object" && value && !Array.isArray(value)) {
|
|
58
|
-
const subConfigData = /** @type {ConfigData} */ (value);
|
|
59
|
-
const flattenConfigDataOptions = { configDataMap, parentKeys: newKeys };
|
|
60
|
-
|
|
61
|
-
const flattenConfigDataResults = /** @type {FlattenConfigDataResults} */ (
|
|
62
|
-
flattenConfigData(subConfigData, flattenConfigDataOptions)
|
|
63
|
-
);
|
|
64
|
-
if (!flattenConfigDataResults.success) return flattenConfigDataResults;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// At this point we're out of the recursion, and we can start working with the complete data.
|
|
69
|
-
|
|
70
|
-
// strips metadata
|
|
71
|
-
/**@type {Map<string, string>} */
|
|
72
|
-
const map = new Map();
|
|
73
|
-
configDataMap.forEach((value, key) => {
|
|
74
|
-
map.set(key, value.value);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
// makes the flattened config data object
|
|
78
|
-
const flattenedConfigData = Object.fromEntries(map);
|
|
79
|
-
|
|
80
|
-
// The integrity of the flattened config data needs to be established before working with it safely.
|
|
81
|
-
|
|
82
|
-
const flattenedConfigDataKeysSet = new Set(Object.keys(flattenedConfigData));
|
|
83
|
-
|
|
84
|
-
const flattenedConfigDataValuesArray = Object.values(flattenedConfigData);
|
|
85
|
-
const flattenedConfigDataValuesSet = new Set(flattenedConfigDataValuesArray);
|
|
86
|
-
|
|
87
|
-
for (const key of flattenedConfigDataKeysSet) {
|
|
88
|
-
if (flattenedConfigDataValuesSet.has(key)) {
|
|
89
|
-
// checks the reversability of flattenedConfigData
|
|
90
|
-
return {
|
|
91
|
-
...successFalse,
|
|
92
|
-
errors: [
|
|
93
|
-
{
|
|
94
|
-
...typeError,
|
|
95
|
-
message: `ERROR. The key "${key}" is and shouldn't be among the values of flattenedConfigData.`,
|
|
96
|
-
},
|
|
97
|
-
],
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
if (!flattenedConfigKeyRegex.test(key)) {
|
|
101
|
-
// checks if each key for flattenedConfigData passes the flattenedConfigKeyRegex test
|
|
102
|
-
return {
|
|
103
|
-
...successFalse,
|
|
104
|
-
errors: [
|
|
105
|
-
{
|
|
106
|
-
...typeError,
|
|
107
|
-
message: `ERROR. Somehow the key "${key}" is not properly formatted. (This is mostly an internal mistake.)`,
|
|
108
|
-
},
|
|
109
|
-
],
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/** @type {Set<string>} */
|
|
115
|
-
const set = new Set();
|
|
116
|
-
|
|
117
|
-
for (const value of flattenedConfigDataValuesArray) {
|
|
118
|
-
if (set.has(value)) {
|
|
119
|
-
console.log("errors, duplicate value");
|
|
120
|
-
// checks that no two values are duplicate
|
|
121
|
-
return {
|
|
122
|
-
...successFalse,
|
|
123
|
-
errors: [
|
|
124
|
-
{
|
|
125
|
-
...typeError,
|
|
126
|
-
message: `ERROR. The value "${value}" is already assigned to an existing key.`,
|
|
127
|
-
},
|
|
128
|
-
],
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
set.add(value);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Also including the reversed flattened config data.
|
|
135
|
-
|
|
136
|
-
const reversedFlattenedConfigData = Object.fromEntries(
|
|
137
|
-
Object.entries(flattenedConfigData).map(([key, value]) => [value, key])
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
return {
|
|
141
|
-
...successTrue,
|
|
142
|
-
flattenedConfigData,
|
|
143
|
-
reversedFlattenedConfigData,
|
|
144
|
-
};
|
|
145
|
-
};
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import url from "url";
|
|
3
|
-
|
|
4
|
-
import { successFalse, typeError } from "../constants/bases.js";
|
|
5
|
-
|
|
6
|
-
import { flattenConfigData } from "./flatten-config-data.js";
|
|
7
|
-
|
|
8
|
-
import { ConfigDataSchema, ConfigIgnoresSchema } from "../schemas/config.js";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Verifies, validates and resolves the config path to retrieve the config's data and ignores.
|
|
12
|
-
* @param {string} configPath The path of the config from `comments.config.js`, or from a config passed via the `--config` flag in the CLI, or from one passed via `"commentVariables.config": true` in `.vscode/settings.json` for the VS Code Extension.
|
|
13
|
-
* @returns The flattened config data, the reverse flattened config data, the verified config path, the raw passed ignores, and the original config. Errors are returned during failures so they can be reused differently on the CLI and the VS Code Extension.
|
|
14
|
-
*/
|
|
15
|
-
export async function resolveConfig(configPath) {
|
|
16
|
-
// Step 1: Checks if config file exists
|
|
17
|
-
|
|
18
|
-
if (!fs.existsSync(configPath)) {
|
|
19
|
-
return {
|
|
20
|
-
...successFalse,
|
|
21
|
-
errors: [
|
|
22
|
-
{
|
|
23
|
-
...typeError,
|
|
24
|
-
message: "ERROR. No config file found.",
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Step 2: Imports the config dynamically
|
|
31
|
-
|
|
32
|
-
const configModule = /** @type {unknown} */ (
|
|
33
|
-
await import(url.pathToFileURL(configPath))
|
|
34
|
-
);
|
|
35
|
-
const config = /** @type {unknown} */ (configModule.default);
|
|
36
|
-
|
|
37
|
-
// Step 3: Validates config object
|
|
38
|
-
|
|
39
|
-
// validates config
|
|
40
|
-
if (!config || typeof config !== "object" || Array.isArray(config)) {
|
|
41
|
-
return {
|
|
42
|
-
...successFalse,
|
|
43
|
-
errors: [
|
|
44
|
-
{
|
|
45
|
-
...typeError,
|
|
46
|
-
message:
|
|
47
|
-
"ERROR. Invalid config format. The config should be an object.",
|
|
48
|
-
},
|
|
49
|
-
],
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// validates config.data
|
|
54
|
-
const configDataResult = ConfigDataSchema.safeParse(config.data);
|
|
55
|
-
|
|
56
|
-
if (!configDataResult.success) {
|
|
57
|
-
return {
|
|
58
|
-
...successFalse,
|
|
59
|
-
errors: [
|
|
60
|
-
{
|
|
61
|
-
...typeError,
|
|
62
|
-
message: "ERROR. Config data could not pass validation from zod.",
|
|
63
|
-
},
|
|
64
|
-
...configDataResult.error.errors.map((e) => ({
|
|
65
|
-
...typeError,
|
|
66
|
-
message: e.message,
|
|
67
|
-
})),
|
|
68
|
-
],
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// validates config.ignores
|
|
73
|
-
const configIgnoresSchemaResult = ConfigIgnoresSchema.safeParse(
|
|
74
|
-
config.ignores
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
if (!configIgnoresSchemaResult.success) {
|
|
78
|
-
return {
|
|
79
|
-
...successFalse,
|
|
80
|
-
errors: [
|
|
81
|
-
{
|
|
82
|
-
...typeError,
|
|
83
|
-
message: "ERROR. Config ignores could not pass validation from zod.",
|
|
84
|
-
},
|
|
85
|
-
...configIgnoresSchemaResult.error.errors.map((e) => ({
|
|
86
|
-
...typeError,
|
|
87
|
-
message: e.message,
|
|
88
|
-
})),
|
|
89
|
-
],
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const flattenedConfigDataResults = flattenConfigData(configDataResult.data);
|
|
94
|
-
|
|
95
|
-
if (!flattenedConfigDataResults.success) {
|
|
96
|
-
return flattenedConfigDataResults;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// sends back:
|
|
100
|
-
// - the flattened config data,
|
|
101
|
-
// - the reverse flattened config data,
|
|
102
|
-
// - the verified config path
|
|
103
|
-
// - and the raw passed ignores
|
|
104
|
-
return {
|
|
105
|
-
...flattenedConfigDataResults, // finalized
|
|
106
|
-
configPath, // finalized
|
|
107
|
-
passedIgnores: configIgnoresSchemaResult.data, // addressed with --lint-config-imports and --my-ignores-only to be finalized
|
|
108
|
-
config, // and the config itself too
|
|
109
|
-
};
|
|
110
|
-
}
|