@ohos-rs/oxk 0.4.0 → 0.5.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 +113 -11
- package/bin/format.js +1 -1
- package/bin/oxk.js +18 -1
- package/index.d.ts +28 -19
- package/index.js +56 -53
- package/lint.d.ts +1 -0
- package/lint.js +274 -0
- package/oxlint-runtime/js_config.cjs +8 -0
- package/oxlint-runtime/plugins.cjs +31 -0
- package/package.json +39 -22
package/lint.js
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
const { mkdtempSync, readFileSync, rmSync, writeFileSync } = require('node:fs')
|
|
2
|
+
const { tmpdir } = require('node:os')
|
|
3
|
+
const { basename, join, resolve } = require('node:path')
|
|
4
|
+
const { lint: lintNative, lintSync, lintWithPlugins } = require('./index.js')
|
|
5
|
+
|
|
6
|
+
let pluginRuntime = null
|
|
7
|
+
let jsConfigRuntime = null
|
|
8
|
+
|
|
9
|
+
function getPluginRuntime() {
|
|
10
|
+
if (!pluginRuntime) pluginRuntime = require('./oxlint-runtime/plugins.cjs')
|
|
11
|
+
return pluginRuntime
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function getJsConfigRuntime() {
|
|
15
|
+
if (!jsConfigRuntime) jsConfigRuntime = require('./oxlint-runtime/js_config.cjs')
|
|
16
|
+
return jsConfigRuntime
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getErrorMessage(error) {
|
|
20
|
+
return error instanceof Error ? error.message : String(error)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function stripJsonComments(source) {
|
|
24
|
+
let output = ''
|
|
25
|
+
let inString = false
|
|
26
|
+
let quote = ''
|
|
27
|
+
let escaped = false
|
|
28
|
+
|
|
29
|
+
for (let index = 0; index < source.length; index += 1) {
|
|
30
|
+
const char = source[index]
|
|
31
|
+
const next = source[index + 1]
|
|
32
|
+
|
|
33
|
+
if (inString) {
|
|
34
|
+
output += char
|
|
35
|
+
if (escaped) {
|
|
36
|
+
escaped = false
|
|
37
|
+
} else if (char === '\\') {
|
|
38
|
+
escaped = true
|
|
39
|
+
} else if (char === quote) {
|
|
40
|
+
inString = false
|
|
41
|
+
}
|
|
42
|
+
continue
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (char === '"' || char === "'") {
|
|
46
|
+
inString = true
|
|
47
|
+
quote = char
|
|
48
|
+
output += char
|
|
49
|
+
continue
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (char === '/' && next === '/') {
|
|
53
|
+
while (index < source.length && source[index] !== '\n') {
|
|
54
|
+
output += ' '
|
|
55
|
+
index += 1
|
|
56
|
+
}
|
|
57
|
+
if (index < source.length) output += '\n'
|
|
58
|
+
continue
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (char === '/' && next === '*') {
|
|
62
|
+
output += ' '
|
|
63
|
+
index += 2
|
|
64
|
+
while (index < source.length) {
|
|
65
|
+
if (source[index] === '*' && source[index + 1] === '/') {
|
|
66
|
+
output += ' '
|
|
67
|
+
index += 1
|
|
68
|
+
break
|
|
69
|
+
}
|
|
70
|
+
output += source[index] === '\n' ? '\n' : ' '
|
|
71
|
+
index += 1
|
|
72
|
+
}
|
|
73
|
+
continue
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
output += char
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return output
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function findConfigPath(args, cwd) {
|
|
83
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
84
|
+
const token = args[index]
|
|
85
|
+
if (token === '--config' || token === '-c') {
|
|
86
|
+
const value = args[index + 1]
|
|
87
|
+
return value ? resolve(cwd, value) : null
|
|
88
|
+
}
|
|
89
|
+
if (token.startsWith('--config=')) {
|
|
90
|
+
return resolve(cwd, token.slice('--config='.length))
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
for (const name of ['.oxlintrc.json', '.oxlintrc.jsonc', 'oxlint.config.ts']) {
|
|
95
|
+
const candidate = join(cwd, name)
|
|
96
|
+
try {
|
|
97
|
+
readFileSync(candidate)
|
|
98
|
+
return candidate
|
|
99
|
+
} catch {}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return null
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function isJsonConfig(configPath) {
|
|
106
|
+
return configPath.endsWith('.json') || configPath.endsWith('.jsonc')
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function loadJsConfig(configPath) {
|
|
110
|
+
const response = JSON.parse(await getJsConfigRuntime().loadJsConfigs([configPath]))
|
|
111
|
+
|
|
112
|
+
if (Array.isArray(response.Success)) {
|
|
113
|
+
const [result] = response.Success
|
|
114
|
+
if (!result || result.config == null) {
|
|
115
|
+
throw new Error('Configuration file must have a default export that is an object.')
|
|
116
|
+
}
|
|
117
|
+
return result.config
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (Array.isArray(response.Failures)) {
|
|
121
|
+
const first = response.Failures[0]
|
|
122
|
+
throw new Error(first ? `${first.path}: ${first.error}` : 'Failed to load JavaScript configuration.')
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
throw new Error(response.Error ?? 'Failed to load JavaScript configuration.')
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function loadConfig(configPath) {
|
|
129
|
+
if (isJsonConfig(configPath)) {
|
|
130
|
+
return JSON.parse(stripJsonComments(readFileSync(configPath, 'utf8')))
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return loadJsConfig(configPath)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function hasJsPlugins(config) {
|
|
137
|
+
if (!config || typeof config !== 'object' || Array.isArray(config)) return false
|
|
138
|
+
if (Array.isArray(config.jsPlugins) && config.jsPlugins.length > 0) return true
|
|
139
|
+
return Array.isArray(config.overrides) && config.overrides.some(hasJsPlugins)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async function prepareLintConfig(args) {
|
|
143
|
+
const cwd = process.cwd()
|
|
144
|
+
const configPath = findConfigPath(args, cwd)
|
|
145
|
+
if (!configPath) return { args, cleanup: () => {}, needsJsPlugins: false }
|
|
146
|
+
|
|
147
|
+
let config
|
|
148
|
+
try {
|
|
149
|
+
config = await loadConfig(configPath)
|
|
150
|
+
} catch (error) {
|
|
151
|
+
throw new Error(`Failed to load oxlint configuration ${configPath}: ${getErrorMessage(error)}`)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
let shouldRewrite = !isJsonConfig(configPath)
|
|
155
|
+
let tempDir = null
|
|
156
|
+
const ensureTempDir = () => {
|
|
157
|
+
if (!tempDir) tempDir = mkdtempSync(join(tmpdir(), 'oxk-lint-config-'))
|
|
158
|
+
return tempDir
|
|
159
|
+
}
|
|
160
|
+
const needsJsPlugins = hasJsPlugins(config)
|
|
161
|
+
|
|
162
|
+
if (!shouldRewrite) {
|
|
163
|
+
return { args, cleanup: () => {}, needsJsPlugins }
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
tempDir = ensureTempDir()
|
|
167
|
+
const tempConfigPath = join(
|
|
168
|
+
tempDir,
|
|
169
|
+
isJsonConfig(configPath) && basename(configPath).endsWith('.jsonc') ? 'oxlintrc.jsonc' : 'oxlintrc.json',
|
|
170
|
+
)
|
|
171
|
+
writeFileSync(tempConfigPath, JSON.stringify(config, null, 2), 'utf8')
|
|
172
|
+
|
|
173
|
+
const nextArgs = []
|
|
174
|
+
let replaced = false
|
|
175
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
176
|
+
const token = args[index]
|
|
177
|
+
if (token === '--config' || token === '-c') {
|
|
178
|
+
nextArgs.push(token, tempConfigPath)
|
|
179
|
+
index += 1
|
|
180
|
+
replaced = true
|
|
181
|
+
} else if (token.startsWith('--config=')) {
|
|
182
|
+
nextArgs.push(`--config=${tempConfigPath}`)
|
|
183
|
+
replaced = true
|
|
184
|
+
} else {
|
|
185
|
+
nextArgs.push(token)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (!replaced) nextArgs.push('--config', tempConfigPath)
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
args: nextArgs,
|
|
192
|
+
cleanup: () => rmSync(tempDir, { recursive: true, force: true }),
|
|
193
|
+
needsJsPlugins,
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
async function loadPluginWrapper(pluginUrl, pluginName, pluginNameIsAlias, workspaceUri) {
|
|
198
|
+
return getPluginRuntime().loadPlugin(pluginUrl, pluginName ?? null, pluginNameIsAlias, workspaceUri ?? null)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function setupRuleConfigsWrapper(optionsJson) {
|
|
202
|
+
return getPluginRuntime().setupRuleConfigs(optionsJson)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
async function lintFileWrapper(
|
|
206
|
+
filePath,
|
|
207
|
+
bufferId,
|
|
208
|
+
buffer,
|
|
209
|
+
ruleIds,
|
|
210
|
+
optionIds,
|
|
211
|
+
settingsJson,
|
|
212
|
+
globalsJson,
|
|
213
|
+
workspaceUri,
|
|
214
|
+
) {
|
|
215
|
+
return getPluginRuntime().lintFile(
|
|
216
|
+
filePath,
|
|
217
|
+
bufferId,
|
|
218
|
+
buffer ?? null,
|
|
219
|
+
ruleIds,
|
|
220
|
+
optionIds,
|
|
221
|
+
settingsJson,
|
|
222
|
+
globalsJson,
|
|
223
|
+
workspaceUri ?? null,
|
|
224
|
+
)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function createWorkspaceWrapper() {
|
|
228
|
+
return Promise.resolve()
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function destroyWorkspaceWrapper() {}
|
|
232
|
+
|
|
233
|
+
function loadJsConfigsWrapper(paths) {
|
|
234
|
+
return getJsConfigRuntime().loadJsConfigs(paths)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async function withStandardOxlintEnv(run) {
|
|
238
|
+
const vpVersion = process.env.VP_VERSION
|
|
239
|
+
delete process.env.VP_VERSION
|
|
240
|
+
try {
|
|
241
|
+
return await run()
|
|
242
|
+
} finally {
|
|
243
|
+
if (vpVersion === undefined) {
|
|
244
|
+
delete process.env.VP_VERSION
|
|
245
|
+
} else {
|
|
246
|
+
process.env.VP_VERSION = vpVersion
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async function lint(args) {
|
|
252
|
+
return withStandardOxlintEnv(async () => {
|
|
253
|
+
const prepared = await prepareLintConfig(args)
|
|
254
|
+
try {
|
|
255
|
+
if (!prepared.needsJsPlugins) {
|
|
256
|
+
return typeof lintSync === 'function' ? lintSync(prepared.args) : lintNative(prepared.args)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return await lintWithPlugins(
|
|
260
|
+
prepared.args,
|
|
261
|
+
loadPluginWrapper,
|
|
262
|
+
setupRuleConfigsWrapper,
|
|
263
|
+
lintFileWrapper,
|
|
264
|
+
createWorkspaceWrapper,
|
|
265
|
+
destroyWorkspaceWrapper,
|
|
266
|
+
loadJsConfigsWrapper,
|
|
267
|
+
)
|
|
268
|
+
} finally {
|
|
269
|
+
prepared.cleanup()
|
|
270
|
+
}
|
|
271
|
+
})
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
module.exports = { lint }
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
var y=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var L=Object.prototype.hasOwnProperty;var M=(t,e)=>{for(var n in e)y(t,n,{get:e[n],enumerable:!0})},T=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of J(e))!L.call(t,r)&&r!==n&&y(t,r,{get:()=>e[r],enumerable:!(o=R(e,r))||o.enumerable});return t};var $=t=>T(y({},"__esModule",{value:!0}),t);var K={};M(K,{loadJsConfigs:()=>S,loadVitePlusConfigs:()=>k});module.exports=$(K);function g(t){try{if(t instanceof Error){let{stack:n}=t;if(typeof n=="string"&&n!=="")return n}let{message:e}=t;if(typeof e=="string"&&e!=="")return e}catch{}return"Unknown error"}var{prototype:W,hasOwn:z,keys:G,values:X,freeze:q,preventExtensions:Y,defineProperty:B,defineProperties:Q,create:Z,assign:tt,getPrototypeOf:et,setPrototypeOf:nt,entries:rt}=Object,{prototype:ot,isArray:st,from:it}=Array,{min:at,max:ct,floor:ft}=Math,{parse:ut,stringify:p}=JSON,{ownKeys:lt}=Reflect,{iterator:gt}=Symbol,{fromCodePoint:pt}=String,{now:b}=Date;var h=require("node:path"),x=require("node:url");var A="^20.19.0 || >=22.18.0",F=new Set([".ts",".mts",".cts"]);function v(t){if(!t.startsWith("file:"))return t;try{return(0,x.fileURLToPath)(t)}catch{return t}}function U(t){let e=(0,h.extname)(v(t)).toLowerCase();return F.has(e)}function _(t){if(t?.code==="ERR_UNKNOWN_FILE_EXTENSION")return!0;let e=t?.message;return typeof e=="string"&&/unknown(?: or unsupported)? file extension/i.test(e)}function O(t,e,n=process.version){return!U(e)||!_(t)?null:`${g(t)}
|
|
2
|
+
|
|
3
|
+
TypeScript config files require Node.js ${A}.
|
|
4
|
+
Detected Node.js ${n}.
|
|
5
|
+
Please upgrade Node.js or use a JSON config file instead.`}var d=t=>typeof t=="object"&&t!==null&&!Array.isArray(t);function C(t){let e=new WeakSet,n=new WeakSet,o=[],r=[],u=(s,i,f)=>{let a=f===-1?`${i} -> ${i}`:[...r.slice(f),i].join(" -> ");return`\`extends\` contains a circular reference.
|
|
6
|
+
|
|
7
|
+
${s} points back to ${i}
|
|
8
|
+
Cycle: ${a}`},c=(s,i)=>{if(e.has(s))return;if(n.has(s)){let a=o.indexOf(s),l=a===-1?"<unknown>":r[a];throw new Error(u(i,l,a))}n.add(s),o.push(s),r.push(i);let f=s.extends;if(f!==void 0){if(!Array.isArray(f))throw new Error("`extends` must be an array of config objects (strings/paths are not supported).");for(let a=0;a<f.length;a++){let l=f[a];if(!d(l))throw new Error(`\`extends[${a}]\` must be a config object (strings/paths are not supported).`);let w=`${i}.extends[${a}]`;if(n.has(l)){let m=o.indexOf(l),N=m===-1?"<unknown>":r[m];throw new Error(u(w,N,m))}c(l,w)}}n.delete(s),o.pop(),r.pop(),e.add(s)};c(t,"<root>")}async function P(t,e){let r=(await import(new URL(`file://${t}?cache=${e}`).href)).default;if(r===void 0)throw new Error("Configuration file has no default export.");return r}async function I(t,e){let n=await P(t,e);if(!d(n))throw new Error("Configuration file must have a default export that is an object.");return C(n),{path:t,config:n}}var E="lint";async function D(t,e){let n=await P(t,e);if(!d(n))return{path:t,config:null};let o=n[E];if(o===void 0)return{path:t,config:null};if(!d(o))throw new Error(`The \`${E}\` field in the default export must be an object.`);return C(o),{path:t,config:o}}async function j(t,e){try{let n=b(),o=await Promise.allSettled(t.map(c=>e(c,n))),r=[],u=[];for(let c=0;c<o.length;c++){let s=o[c];if(s.status==="fulfilled")r.push(s.value);else{let i=t[c],f=O(s.reason,i);u.push({path:i,error:f??g(s.reason)})}}return u.length>0?p({Failures:u}):p({Success:r})}catch(n){return p({Error:g(n)})}}var S=t=>j(t,I),k=t=>j(t,D);0&&(module.exports={loadJsConfigs,loadVitePlusConfigs});
|