@html-validate/plugin-utils 1.0.2 → 2.0.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.js → cjs/index.cjs} +18 -12
- package/dist/cjs/index.cjs.map +7 -0
- package/dist/cjs/index.d.cts +1 -0
- package/dist/{tsdoc-metadata.json → cjs/tsdoc-metadata.json} +1 -1
- package/dist/{index.esm.js → esm/index.mjs} +15 -4
- package/dist/esm/index.mjs.map +7 -0
- package/package.json +15 -11
- /package/dist/{index.d.ts → esm/index.d.mts} +0 -0
|
@@ -25,7 +25,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
26
|
mod
|
|
27
27
|
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
28
|
|
|
30
29
|
// src/index.ts
|
|
31
30
|
var src_exports = {};
|
|
@@ -34,7 +33,6 @@ __export(src_exports, {
|
|
|
34
33
|
positionFromOffset: () => positionFromOffset,
|
|
35
34
|
positionToOffset: () => positionToOffset
|
|
36
35
|
});
|
|
37
|
-
module.exports = __toCommonJS(src_exports);
|
|
38
36
|
|
|
39
37
|
// src/position-from-offset.ts
|
|
40
38
|
function positionFromOffset(text, offset) {
|
|
@@ -85,6 +83,7 @@ function joinTemplateLiteral(nodes) {
|
|
|
85
83
|
}
|
|
86
84
|
function extractLiteral(node, filename, data) {
|
|
87
85
|
switch (node.type) {
|
|
86
|
+
/* ignored nodes */
|
|
88
87
|
case "FunctionExpression":
|
|
89
88
|
case "Identifier":
|
|
90
89
|
return null;
|
|
@@ -123,9 +122,12 @@ function extractLiteral(node, filename, data) {
|
|
|
123
122
|
return null;
|
|
124
123
|
}
|
|
125
124
|
}
|
|
125
|
+
/* istanbul ignore next: this only provides a better error, all currently known nodes are tested */
|
|
126
126
|
default: {
|
|
127
127
|
const loc = node.loc.start;
|
|
128
|
-
const
|
|
128
|
+
const line = String(loc.line);
|
|
129
|
+
const column = String(loc.column);
|
|
130
|
+
const context = `${filename}:${line}:${column}`;
|
|
129
131
|
throw new Error(`Unhandled node type "${node.type}" at "${context}" in extractLiteral`);
|
|
130
132
|
}
|
|
131
133
|
}
|
|
@@ -136,14 +138,20 @@ function compareKey(node, key, filename) {
|
|
|
136
138
|
return node.name === key;
|
|
137
139
|
case "Literal":
|
|
138
140
|
return node.value === key;
|
|
141
|
+
/* istanbul ignore next: this only provides a better error, all currently known nodes are tested */
|
|
139
142
|
default: {
|
|
140
143
|
const loc = node.loc.start;
|
|
141
|
-
const
|
|
144
|
+
const line = String(loc.line);
|
|
145
|
+
const column = String(loc.column);
|
|
146
|
+
const context = `${filename}:${line}:${column}`;
|
|
142
147
|
throw new Error(`Unhandled node type "${node.type}" at "${context}" in compareKey`);
|
|
143
148
|
}
|
|
144
149
|
}
|
|
145
150
|
}
|
|
146
|
-
var TemplateExtractor = class {
|
|
151
|
+
var TemplateExtractor = class _TemplateExtractor {
|
|
152
|
+
ast;
|
|
153
|
+
filename;
|
|
154
|
+
data;
|
|
147
155
|
constructor(ast, filename, data) {
|
|
148
156
|
this.ast = ast;
|
|
149
157
|
this.filename = filename;
|
|
@@ -166,7 +174,7 @@ var TemplateExtractor = class {
|
|
|
166
174
|
sourceType: "module",
|
|
167
175
|
loc: true
|
|
168
176
|
});
|
|
169
|
-
return new
|
|
177
|
+
return new _TemplateExtractor(ast, filename ?? "inline", source);
|
|
170
178
|
}
|
|
171
179
|
/**
|
|
172
180
|
* Extract object properties.
|
|
@@ -202,9 +210,7 @@ var TemplateExtractor = class {
|
|
|
202
210
|
return result;
|
|
203
211
|
}
|
|
204
212
|
};
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
positionToOffset
|
|
210
|
-
});
|
|
213
|
+
|
|
214
|
+
// src/entry-cjs.ts
|
|
215
|
+
module.exports = { ...src_exports };
|
|
216
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/index.ts", "../../src/position-from-offset.ts", "../../src/position-to-offset.ts", "../../src/template-extractor.ts", "../../src/entry-cjs.ts"],
|
|
4
|
+
"sourcesContent": ["export { type Position } from \"./position\";\nexport { positionFromOffset } from \"./position-from-offset\";\nexport { positionToOffset } from \"./position-to-offset\";\nexport { TemplateExtractor } from \"./template-extractor\";\n", "/**\n * Given an offset into a source, calculate the corresponding line and column.\n *\n * @public\n * @since 1.0.0\n */\nexport function positionFromOffset(text: string, offset: number): [line: number, column: number] {\n\tlet line = 1;\n\tlet prev = 0;\n\tlet pos = text.indexOf(\"\\n\");\n\n\t/* step one line at a time until newline position is beyond wanted offset */\n\twhile (pos !== -1) {\n\t\tif (pos >= offset) {\n\t\t\treturn [line, offset - prev + 1];\n\t\t}\n\t\tline++;\n\t\tprev = pos + 1;\n\t\tpos = text.indexOf(\"\\n\", pos + 1);\n\t}\n\n\t/* missing final newline */\n\treturn [line, offset - prev + 1];\n}\n", "import { type Position } from \"./position\";\n\n/**\n * Compute source offset from line and column and the given markup.\n *\n * @public\n * @since 1.0.0\n * @param position - Line and column.\n * @param data - Source markup.\n * @returns The byte offset into the markup which line and column corresponds to.\n */\nexport function positionToOffset(position: Position, data: string): number {\n\tlet line = position.line;\n\tlet column = position.column + 1;\n\tfor (let i = 0; i < data.length; i++) {\n\t\tif (line > 1) {\n\t\t\t/* not yet on the correct line */\n\t\t\tif (data[i] === \"\\n\") {\n\t\t\t\tline--;\n\t\t\t}\n\t\t} else if (column > 1) {\n\t\t\t/* not yet on the correct column */\n\t\t\tcolumn--;\n\t\t} else {\n\t\t\t/* line/column found, return current position */\n\t\t\treturn i;\n\t\t}\n\t}\n\t/* istanbul ignore next: should never reach this line unless espree passes bad\n\t * positions, no sane way to test */\n\tthrow new Error(\"Failed to compute location offset from position\");\n}\n", "/* eslint-disable @typescript-eslint/no-non-null-assertion -- declarations say\n * location fields are optional but they are always present when `{loc: true}` */\n\nimport * as espree from \"espree\";\nimport * as walk from \"acorn-walk\";\n\n/* eslint-disable-next-line n/no-extraneous-import -- type is pulled via acorn-walk */\nimport { type Node } from \"acorn\";\n\nimport { type Source } from \"html-validate\";\nimport { positionToOffset } from \"./position-to-offset\";\n\n/* espree puts location information a bit different than estree */\ndeclare module \"estree\" {\n\tinterface TemplateElement {\n\t\tstart: number;\n\t\tend: number;\n\t}\n}\n\nfunction joinTemplateLiteral(nodes: espree.TemplateElement[]): string {\n\tlet offset = nodes[0].start + 1;\n\tlet output = \"\";\n\tfor (const node of nodes) {\n\t\toutput += \" \".repeat(node.start + 1 - offset);\n\t\toutput += node.value.raw;\n\t\toffset = node.end - 2;\n\t}\n\treturn output;\n}\n\nfunction extractLiteral(\n\tnode: espree.Expression | espree.Pattern | espree.Literal | espree.BlockStatement,\n\tfilename: string,\n\tdata: string,\n): Source | null {\n\tswitch (node.type) {\n\t\t/* ignored nodes */\n\t\tcase \"FunctionExpression\":\n\t\tcase \"Identifier\":\n\t\t\treturn null;\n\n\t\tcase \"Literal\":\n\t\t\tif (typeof node.value !== \"string\") {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tdata: node.value.toString(),\n\t\t\t\tfilename,\n\t\t\t\tline: node.loc!.start.line,\n\t\t\t\tcolumn: node.loc!.start.column + 1,\n\t\t\t\toffset: positionToOffset(node.loc!.start, data) + 1,\n\t\t\t};\n\n\t\tcase \"TemplateLiteral\":\n\t\t\treturn {\n\t\t\t\tdata: joinTemplateLiteral(node.quasis),\n\t\t\t\tfilename,\n\t\t\t\tline: node.loc!.start.line,\n\t\t\t\tcolumn: node.loc!.start.column + 1,\n\t\t\t\toffset: positionToOffset(node.loc!.start, data) + 1,\n\t\t\t};\n\n\t\tcase \"TaggedTemplateExpression\":\n\t\t\treturn {\n\t\t\t\tdata: joinTemplateLiteral(node.quasi.quasis),\n\t\t\t\tfilename,\n\t\t\t\tline: node.quasi.loc!.start.line,\n\t\t\t\tcolumn: node.quasi.loc!.start.column + 1,\n\t\t\t\toffset: positionToOffset(node.quasi.loc!.start, data) + 1,\n\t\t\t};\n\n\t\tcase \"ArrowFunctionExpression\": {\n\t\t\tconst whitelist = [\"Literal\", \"TemplateLiteral\"];\n\t\t\tif (whitelist.includes(node.body.type)) {\n\t\t\t\treturn extractLiteral(node.body, filename, data);\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\t/* istanbul ignore next: this only provides a better error, all currently known nodes are tested */\n\t\tdefault: {\n\t\t\tconst loc = node.loc!.start;\n\t\t\tconst line = String(loc.line);\n\t\t\tconst column = String(loc.column);\n\t\t\tconst context = `${filename}:${line}:${column}`;\n\t\t\tthrow new Error(`Unhandled node type \"${node.type}\" at \"${context}\" in extractLiteral`);\n\t\t}\n\t}\n}\n\nfunction compareKey(\n\tnode: espree.Expression | espree.PrivateIdentifier,\n\tkey: string,\n\tfilename: string,\n): boolean {\n\tswitch (node.type) {\n\t\tcase \"Identifier\":\n\t\t\treturn node.name === key;\n\n\t\tcase \"Literal\":\n\t\t\treturn node.value === key;\n\n\t\t/* istanbul ignore next: this only provides a better error, all currently known nodes are tested */\n\t\tdefault: {\n\t\t\tconst loc = node.loc!.start;\n\t\t\tconst line = String(loc.line);\n\t\t\tconst column = String(loc.column);\n\t\t\tconst context = `${filename}:${line}:${column}`;\n\t\t\tthrow new Error(`Unhandled node type \"${node.type}\" at \"${context}\" in compareKey`);\n\t\t}\n\t}\n}\n\n/**\n * @public\n * @since 1.0.0\n */\nexport class TemplateExtractor {\n\tprivate ast: espree.Program;\n\n\tprivate filename: string;\n\tprivate data: string;\n\n\tprivate constructor(ast: espree.Program, filename: string, data: string) {\n\t\tthis.ast = ast;\n\t\tthis.filename = filename;\n\t\tthis.data = data;\n\t}\n\n\t/**\n\t * Create a new [[TemplateExtractor]] from javascript source code.\n\t *\n\t * `Source` offsets will be relative to the string, i.e. offset 0 is the first\n\t * character of the string. If the string is only a subset of a larger string\n\t * the offsets must be adjusted manually.\n\t *\n\t * @param source - Source code.\n\t * @param filename - Optional filename to set in the resulting\n\t * `Source`. Defauls to `\"inline\"`.\n\t */\n\tpublic static fromString(source: string, filename?: string): TemplateExtractor {\n\t\tconst ast = espree.parse(source, {\n\t\t\tecmaVersion: \"latest\",\n\t\t\tsourceType: \"module\",\n\t\t\tloc: true,\n\t\t});\n\t\treturn new TemplateExtractor(ast, filename ?? \"inline\", source);\n\t}\n\n\t/**\n\t * Extract object properties.\n\t *\n\t * Given a key `\"template\"` this method finds all objects literals with a\n\t * `\"template\"` property and creates a [[Source]] instance with proper offsets\n\t * with the value of the property. For instance:\n\t *\n\t * ```\n\t * const myObj = {\n\t * foo: 'bar',\n\t * };\n\t * ```\n\t *\n\t * The above snippet would yield a `Source` with the content `bar`.\n\t *\n\t */\n\tpublic extractObjectProperty(key: string): Source[] {\n\t\tconst result: Source[] = [];\n\t\tconst { filename, data } = this;\n\t\tconst node: Node = this.ast as unknown as Node;\n\t\twalk.simple(node, {\n\t\t\tProperty(node: espree.Property) {\n\t\t\t\tif (compareKey(node.key, key, filename)) {\n\t\t\t\t\tconst source = extractLiteral(node.value, filename, data);\n\t\t\t\t\tif (source) {\n\t\t\t\t\t\tsource.filename = filename;\n\t\t\t\t\t\tresult.push(source);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t} as unknown as walk.SimpleVisitors<unknown>);\n\t\treturn result;\n\t}\n}\n", "/* istanbul ignore file */\n\nimport * as utils from \"./index\";\n\nexport = { ...utils };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["node"]
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { }
|
|
@@ -47,6 +47,7 @@ function joinTemplateLiteral(nodes) {
|
|
|
47
47
|
}
|
|
48
48
|
function extractLiteral(node, filename, data) {
|
|
49
49
|
switch (node.type) {
|
|
50
|
+
/* ignored nodes */
|
|
50
51
|
case "FunctionExpression":
|
|
51
52
|
case "Identifier":
|
|
52
53
|
return null;
|
|
@@ -85,9 +86,12 @@ function extractLiteral(node, filename, data) {
|
|
|
85
86
|
return null;
|
|
86
87
|
}
|
|
87
88
|
}
|
|
89
|
+
/* istanbul ignore next: this only provides a better error, all currently known nodes are tested */
|
|
88
90
|
default: {
|
|
89
91
|
const loc = node.loc.start;
|
|
90
|
-
const
|
|
92
|
+
const line = String(loc.line);
|
|
93
|
+
const column = String(loc.column);
|
|
94
|
+
const context = `${filename}:${line}:${column}`;
|
|
91
95
|
throw new Error(`Unhandled node type "${node.type}" at "${context}" in extractLiteral`);
|
|
92
96
|
}
|
|
93
97
|
}
|
|
@@ -98,14 +102,20 @@ function compareKey(node, key, filename) {
|
|
|
98
102
|
return node.name === key;
|
|
99
103
|
case "Literal":
|
|
100
104
|
return node.value === key;
|
|
105
|
+
/* istanbul ignore next: this only provides a better error, all currently known nodes are tested */
|
|
101
106
|
default: {
|
|
102
107
|
const loc = node.loc.start;
|
|
103
|
-
const
|
|
108
|
+
const line = String(loc.line);
|
|
109
|
+
const column = String(loc.column);
|
|
110
|
+
const context = `${filename}:${line}:${column}`;
|
|
104
111
|
throw new Error(`Unhandled node type "${node.type}" at "${context}" in compareKey`);
|
|
105
112
|
}
|
|
106
113
|
}
|
|
107
114
|
}
|
|
108
|
-
var TemplateExtractor = class {
|
|
115
|
+
var TemplateExtractor = class _TemplateExtractor {
|
|
116
|
+
ast;
|
|
117
|
+
filename;
|
|
118
|
+
data;
|
|
109
119
|
constructor(ast, filename, data) {
|
|
110
120
|
this.ast = ast;
|
|
111
121
|
this.filename = filename;
|
|
@@ -128,7 +138,7 @@ var TemplateExtractor = class {
|
|
|
128
138
|
sourceType: "module",
|
|
129
139
|
loc: true
|
|
130
140
|
});
|
|
131
|
-
return new
|
|
141
|
+
return new _TemplateExtractor(ast, filename ?? "inline", source);
|
|
132
142
|
}
|
|
133
143
|
/**
|
|
134
144
|
* Extract object properties.
|
|
@@ -169,3 +179,4 @@ export {
|
|
|
169
179
|
positionFromOffset,
|
|
170
180
|
positionToOffset
|
|
171
181
|
};
|
|
182
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/position-from-offset.ts", "../../src/position-to-offset.ts", "../../src/template-extractor.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Given an offset into a source, calculate the corresponding line and column.\n *\n * @public\n * @since 1.0.0\n */\nexport function positionFromOffset(text: string, offset: number): [line: number, column: number] {\n\tlet line = 1;\n\tlet prev = 0;\n\tlet pos = text.indexOf(\"\\n\");\n\n\t/* step one line at a time until newline position is beyond wanted offset */\n\twhile (pos !== -1) {\n\t\tif (pos >= offset) {\n\t\t\treturn [line, offset - prev + 1];\n\t\t}\n\t\tline++;\n\t\tprev = pos + 1;\n\t\tpos = text.indexOf(\"\\n\", pos + 1);\n\t}\n\n\t/* missing final newline */\n\treturn [line, offset - prev + 1];\n}\n", "import { type Position } from \"./position\";\n\n/**\n * Compute source offset from line and column and the given markup.\n *\n * @public\n * @since 1.0.0\n * @param position - Line and column.\n * @param data - Source markup.\n * @returns The byte offset into the markup which line and column corresponds to.\n */\nexport function positionToOffset(position: Position, data: string): number {\n\tlet line = position.line;\n\tlet column = position.column + 1;\n\tfor (let i = 0; i < data.length; i++) {\n\t\tif (line > 1) {\n\t\t\t/* not yet on the correct line */\n\t\t\tif (data[i] === \"\\n\") {\n\t\t\t\tline--;\n\t\t\t}\n\t\t} else if (column > 1) {\n\t\t\t/* not yet on the correct column */\n\t\t\tcolumn--;\n\t\t} else {\n\t\t\t/* line/column found, return current position */\n\t\t\treturn i;\n\t\t}\n\t}\n\t/* istanbul ignore next: should never reach this line unless espree passes bad\n\t * positions, no sane way to test */\n\tthrow new Error(\"Failed to compute location offset from position\");\n}\n", "/* eslint-disable @typescript-eslint/no-non-null-assertion -- declarations say\n * location fields are optional but they are always present when `{loc: true}` */\n\nimport * as espree from \"espree\";\nimport * as walk from \"acorn-walk\";\n\n/* eslint-disable-next-line n/no-extraneous-import -- type is pulled via acorn-walk */\nimport { type Node } from \"acorn\";\n\nimport { type Source } from \"html-validate\";\nimport { positionToOffset } from \"./position-to-offset\";\n\n/* espree puts location information a bit different than estree */\ndeclare module \"estree\" {\n\tinterface TemplateElement {\n\t\tstart: number;\n\t\tend: number;\n\t}\n}\n\nfunction joinTemplateLiteral(nodes: espree.TemplateElement[]): string {\n\tlet offset = nodes[0].start + 1;\n\tlet output = \"\";\n\tfor (const node of nodes) {\n\t\toutput += \" \".repeat(node.start + 1 - offset);\n\t\toutput += node.value.raw;\n\t\toffset = node.end - 2;\n\t}\n\treturn output;\n}\n\nfunction extractLiteral(\n\tnode: espree.Expression | espree.Pattern | espree.Literal | espree.BlockStatement,\n\tfilename: string,\n\tdata: string,\n): Source | null {\n\tswitch (node.type) {\n\t\t/* ignored nodes */\n\t\tcase \"FunctionExpression\":\n\t\tcase \"Identifier\":\n\t\t\treturn null;\n\n\t\tcase \"Literal\":\n\t\t\tif (typeof node.value !== \"string\") {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tdata: node.value.toString(),\n\t\t\t\tfilename,\n\t\t\t\tline: node.loc!.start.line,\n\t\t\t\tcolumn: node.loc!.start.column + 1,\n\t\t\t\toffset: positionToOffset(node.loc!.start, data) + 1,\n\t\t\t};\n\n\t\tcase \"TemplateLiteral\":\n\t\t\treturn {\n\t\t\t\tdata: joinTemplateLiteral(node.quasis),\n\t\t\t\tfilename,\n\t\t\t\tline: node.loc!.start.line,\n\t\t\t\tcolumn: node.loc!.start.column + 1,\n\t\t\t\toffset: positionToOffset(node.loc!.start, data) + 1,\n\t\t\t};\n\n\t\tcase \"TaggedTemplateExpression\":\n\t\t\treturn {\n\t\t\t\tdata: joinTemplateLiteral(node.quasi.quasis),\n\t\t\t\tfilename,\n\t\t\t\tline: node.quasi.loc!.start.line,\n\t\t\t\tcolumn: node.quasi.loc!.start.column + 1,\n\t\t\t\toffset: positionToOffset(node.quasi.loc!.start, data) + 1,\n\t\t\t};\n\n\t\tcase \"ArrowFunctionExpression\": {\n\t\t\tconst whitelist = [\"Literal\", \"TemplateLiteral\"];\n\t\t\tif (whitelist.includes(node.body.type)) {\n\t\t\t\treturn extractLiteral(node.body, filename, data);\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\t/* istanbul ignore next: this only provides a better error, all currently known nodes are tested */\n\t\tdefault: {\n\t\t\tconst loc = node.loc!.start;\n\t\t\tconst line = String(loc.line);\n\t\t\tconst column = String(loc.column);\n\t\t\tconst context = `${filename}:${line}:${column}`;\n\t\t\tthrow new Error(`Unhandled node type \"${node.type}\" at \"${context}\" in extractLiteral`);\n\t\t}\n\t}\n}\n\nfunction compareKey(\n\tnode: espree.Expression | espree.PrivateIdentifier,\n\tkey: string,\n\tfilename: string,\n): boolean {\n\tswitch (node.type) {\n\t\tcase \"Identifier\":\n\t\t\treturn node.name === key;\n\n\t\tcase \"Literal\":\n\t\t\treturn node.value === key;\n\n\t\t/* istanbul ignore next: this only provides a better error, all currently known nodes are tested */\n\t\tdefault: {\n\t\t\tconst loc = node.loc!.start;\n\t\t\tconst line = String(loc.line);\n\t\t\tconst column = String(loc.column);\n\t\t\tconst context = `${filename}:${line}:${column}`;\n\t\t\tthrow new Error(`Unhandled node type \"${node.type}\" at \"${context}\" in compareKey`);\n\t\t}\n\t}\n}\n\n/**\n * @public\n * @since 1.0.0\n */\nexport class TemplateExtractor {\n\tprivate ast: espree.Program;\n\n\tprivate filename: string;\n\tprivate data: string;\n\n\tprivate constructor(ast: espree.Program, filename: string, data: string) {\n\t\tthis.ast = ast;\n\t\tthis.filename = filename;\n\t\tthis.data = data;\n\t}\n\n\t/**\n\t * Create a new [[TemplateExtractor]] from javascript source code.\n\t *\n\t * `Source` offsets will be relative to the string, i.e. offset 0 is the first\n\t * character of the string. If the string is only a subset of a larger string\n\t * the offsets must be adjusted manually.\n\t *\n\t * @param source - Source code.\n\t * @param filename - Optional filename to set in the resulting\n\t * `Source`. Defauls to `\"inline\"`.\n\t */\n\tpublic static fromString(source: string, filename?: string): TemplateExtractor {\n\t\tconst ast = espree.parse(source, {\n\t\t\tecmaVersion: \"latest\",\n\t\t\tsourceType: \"module\",\n\t\t\tloc: true,\n\t\t});\n\t\treturn new TemplateExtractor(ast, filename ?? \"inline\", source);\n\t}\n\n\t/**\n\t * Extract object properties.\n\t *\n\t * Given a key `\"template\"` this method finds all objects literals with a\n\t * `\"template\"` property and creates a [[Source]] instance with proper offsets\n\t * with the value of the property. For instance:\n\t *\n\t * ```\n\t * const myObj = {\n\t * foo: 'bar',\n\t * };\n\t * ```\n\t *\n\t * The above snippet would yield a `Source` with the content `bar`.\n\t *\n\t */\n\tpublic extractObjectProperty(key: string): Source[] {\n\t\tconst result: Source[] = [];\n\t\tconst { filename, data } = this;\n\t\tconst node: Node = this.ast as unknown as Node;\n\t\twalk.simple(node, {\n\t\t\tProperty(node: espree.Property) {\n\t\t\t\tif (compareKey(node.key, key, filename)) {\n\t\t\t\t\tconst source = extractLiteral(node.value, filename, data);\n\t\t\t\t\tif (source) {\n\t\t\t\t\t\tsource.filename = filename;\n\t\t\t\t\t\tresult.push(source);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t} as unknown as walk.SimpleVisitors<unknown>);\n\t\treturn result;\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["node"]
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@html-validate/plugin-utils",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Plugin utilities and helpers for writing plugins to HTML-Validate",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"html-validate"
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
},
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
14
|
-
"url": "https://gitlab.com/html-validate/plugin-utils.git"
|
|
14
|
+
"url": "git+https://gitlab.com/html-validate/plugin-utils.git"
|
|
15
15
|
},
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"author": "David Sveningsson <ext@sidvind.com>",
|
|
@@ -19,24 +19,28 @@
|
|
|
19
19
|
"type": "commonjs",
|
|
20
20
|
"exports": {
|
|
21
21
|
".": {
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
"import": {
|
|
23
|
+
"types": "./dist/esm/index.d.mts",
|
|
24
|
+
"default": "./dist/esm/index.mjs"
|
|
25
|
+
},
|
|
26
|
+
"require": {
|
|
27
|
+
"types": "./dist/cjs/index.d.cts",
|
|
28
|
+
"default": "./dist/cjs/index.cjs"
|
|
29
|
+
}
|
|
25
30
|
}
|
|
26
31
|
},
|
|
27
|
-
"main": "dist/index.cjs
|
|
28
|
-
"module": "dist/index.
|
|
29
|
-
"types": "dist/index.d.ts",
|
|
32
|
+
"main": "dist/cjs/index.cjs",
|
|
33
|
+
"module": "dist/esm/index.mjs",
|
|
30
34
|
"files": [
|
|
31
35
|
"dist"
|
|
32
36
|
],
|
|
33
37
|
"peerDependencies": {
|
|
34
38
|
"acorn-walk": "^8",
|
|
35
|
-
"espree": "^9",
|
|
36
|
-
"html-validate": "^
|
|
39
|
+
"espree": "^9 || ^10",
|
|
40
|
+
"html-validate": "^8.0.0 || ^9.0.0 || >= 9.0.0-rc.6 < 10.0.0"
|
|
37
41
|
},
|
|
38
42
|
"engines": {
|
|
39
|
-
"node": ">=
|
|
43
|
+
"node": ">= 18.0"
|
|
40
44
|
},
|
|
41
45
|
"publishConfig": {
|
|
42
46
|
"access": "public"
|
|
File without changes
|