@markuplint/file-resolver 4.7.2 → 4.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/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [4.8.0](https://github.com/markuplint/markuplint/compare/@markuplint/file-resolver@4.7.2...@markuplint/file-resolver@4.8.0) (2024-05-28)
7
+
8
+ ### Features
9
+
10
+ - **file-resolver:** `configProvider` resolves paths of `pretenders` field ([08ccc73](https://github.com/markuplint/markuplint/commit/08ccc7306ac748ce66e33ab571dab1a2eeace12e))
11
+ - **file-resolver:** `generalImport` supports to access protected path in module ([6d0c60e](https://github.com/markuplint/markuplint/commit/6d0c60e25d63d31a150a5f2cf7c41bef481302d4))
12
+ - **file-resolver:** add `resolve-pretenders` function ([68ba7f5](https://github.com/markuplint/markuplint/commit/68ba7f5acaba13484172bca3ea5f60e0bf3044ef))
13
+
6
14
  ## [4.7.2](https://github.com/markuplint/markuplint/compare/@markuplint/file-resolver@4.7.1...@markuplint/file-resolver@4.7.2) (2024-05-12)
7
15
 
8
16
  **Note:** Version bump only for package @markuplint/file-resolver
@@ -1,6 +1,6 @@
1
1
  import type { MLFile } from './ml-file/index.js';
2
2
  import type { ConfigSet } from './types.js';
3
- import type { Config } from '@markuplint/ml-config';
3
+ import type { OptimizedConfig } from '@markuplint/ml-config';
4
4
  import type { Nullable } from '@markuplint/shared';
5
5
  export declare class ConfigProvider {
6
6
  #private;
@@ -10,7 +10,7 @@ export declare class ConfigProvider {
10
10
  }>;
11
11
  resolve(targetFile: Readonly<MLFile>, names: readonly Nullable<string>[], cache?: boolean): Promise<ConfigSet>;
12
12
  search(targetFile: Readonly<MLFile>): Promise<string | null>;
13
- set(config: Config, key?: string): string;
13
+ set(config: OptimizedConfig, key?: string): string;
14
14
  private _load;
15
15
  private _mergeConfigs;
16
16
  private _pathResolve;
@@ -98,7 +98,7 @@ export class ConfigProvider {
98
98
  const plugin = plugins.find(plugin => plugin.name === namespace);
99
99
  const config = plugin?.configs?.[name ?? ''];
100
100
  if (config) {
101
- this.set(config, held);
101
+ this.set(mergeConfig(config), held);
102
102
  }
103
103
  break;
104
104
  }
@@ -212,15 +212,22 @@ export class ConfigProvider {
212
212
  };
213
213
  }
214
214
  async _pathResolve(config, filePath) {
215
+ const optimizedConfig = mergeConfig(config);
215
216
  const dir = path.dirname(filePath);
216
217
  return {
217
- ...config,
218
- extends: await relPathToNameOrAbsPath(dir, config.extends),
219
- plugins: await relPathToNameOrAbsPath(dir, config.plugins, ['name']),
220
- parser: await relPathToNameOrAbsPath(dir, config.parser),
221
- specs: await relPathToNameOrAbsPath(dir, config.specs),
222
- excludeFiles: await relPathToNameOrAbsPath(dir, config.excludeFiles),
223
- overrides: await relPathToNameOrAbsPath(dir, config.overrides, undefined, true),
218
+ ...optimizedConfig,
219
+ extends: await relPathToNameOrAbsPath(dir, optimizedConfig.extends),
220
+ plugins: await relPathToNameOrAbsPath(dir, optimizedConfig.plugins, ['name']),
221
+ parser: await relPathToNameOrAbsPath(dir, optimizedConfig.parser),
222
+ specs: await relPathToNameOrAbsPath(dir, optimizedConfig.specs),
223
+ excludeFiles: await relPathToNameOrAbsPath(dir, optimizedConfig.excludeFiles),
224
+ pretenders: optimizedConfig.pretenders
225
+ ? {
226
+ ...optimizedConfig.pretenders,
227
+ files: await relPathToNameOrAbsPath(dir, optimizedConfig.pretenders?.files),
228
+ }
229
+ : undefined,
230
+ overrides: await relPathToNameOrAbsPath(dir, optimizedConfig.overrides, undefined, true),
224
231
  };
225
232
  }
226
233
  _validateConfig(config, filePath) {
@@ -1,6 +1,11 @@
1
+ import fs from 'node:fs/promises';
1
2
  import { createRequire } from 'node:module';
3
+ import path from 'node:path';
4
+ import { resolve } from 'import-meta-resolve';
2
5
  import { log } from './debug.js';
3
6
  const gLog = log.extend('general-import');
7
+ const gLogSuccess = gLog.extend('success');
8
+ const gLogError = gLog.extend('error');
4
9
  const cache = new Map();
5
10
  const require = createRequire(import.meta.url);
6
11
  export async function generalImport(name) {
@@ -10,6 +15,7 @@ export async function generalImport(name) {
10
15
  try {
11
16
  const imported = await import(name);
12
17
  const mod = imported?.default ?? imported ?? null;
18
+ gLogSuccess('Success by import("%s"): %O', name, mod);
13
19
  cache.set(name, mod);
14
20
  return mod;
15
21
  }
@@ -21,19 +27,40 @@ export async function generalImport(name) {
21
27
  error.code === 'ERR_IMPORT_ASSERTION_TYPE_MISSING') {
22
28
  try {
23
29
  const mod = require(name) ?? null;
30
+ gLogSuccess('Success by require("%s"): %O', name, mod);
24
31
  cache.set(name, mod);
25
32
  return mod;
26
33
  }
27
34
  catch (error) {
28
35
  if (error instanceof Error && /^parse failure/i.test(error.message)) {
29
- gLog('Error in `createRequire(import.meta.url)()`: %O', error);
36
+ gLogError('Error in `createRequire(import.meta.url)()`: %O', error);
30
37
  cache.set(name, null);
31
38
  return null;
32
39
  }
33
- gLog('Error in generalImport: %O', error);
40
+ gLogError('Error in generalImport: %O', error);
34
41
  }
35
42
  }
36
- gLog('Error in `import()`: %O', error);
43
+ if (error instanceof Error) {
44
+ const { filePath, packageName } = /Missing\s"(?<filePath>[^"]+)"\sspecifier\sin\s"(?<packageName>[^"]+)"\spackage/.exec(error.message)
45
+ ?.groups ?? {};
46
+ if (filePath && packageName) {
47
+ const modFile = resolve(packageName, import.meta.url);
48
+ const modPath = path.dirname(modFile);
49
+ const candidate = path.join(modPath, filePath);
50
+ gLog('Try import absolute path: "%s"', candidate);
51
+ const result = await generalImport(candidate);
52
+ cache.set(name, result);
53
+ return result;
54
+ }
55
+ }
56
+ if (path.isAbsolute(name) && name.endsWith('.json')) {
57
+ const file = await fs.readFile(name, 'utf8');
58
+ const json = JSON.parse(file);
59
+ gLogSuccess('Success by readFile("%s") and JSON.parse: %O', name, json);
60
+ cache.set(name, json);
61
+ return json;
62
+ }
63
+ gLogError('Error in `import()`: %O', error);
37
64
  cache.set(name, null);
38
65
  return null;
39
66
  }
package/lib/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export type { MLFile } from './ml-file/index.js';
2
2
  export * from './config-provider.js';
3
3
  export * from './resolve-files.js';
4
4
  export * from './resolve-parser.js';
5
+ export * from './resolve-pretenders.js';
5
6
  export * from './resolve-rules.js';
6
7
  export * from './resolve-specs.js';
7
8
  export * from './types.js';
package/lib/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './config-provider.js';
2
2
  export * from './resolve-files.js';
3
3
  export * from './resolve-parser.js';
4
+ export * from './resolve-pretenders.js';
4
5
  export * from './resolve-rules.js';
5
6
  export * from './resolve-specs.js';
6
7
  export * from './types.js';
@@ -0,0 +1,4 @@
1
+ import type { OptimizedConfig, Pretender } from '@markuplint/ml-config';
2
+ type PretendersConfig = OptimizedConfig['pretenders'];
3
+ export declare function resolvePretenders(config: PretendersConfig): Promise<Pretender[]>;
4
+ export {};
@@ -0,0 +1,32 @@
1
+ import { generalImport } from './general-import.js';
2
+ export async function resolvePretenders(config) {
3
+ if (!config) {
4
+ return [];
5
+ }
6
+ const data = [];
7
+ if (config.files) {
8
+ for (const file of config.files) {
9
+ const pretenderFile = await generalImport(file);
10
+ if (!pretenderFile?.data) {
11
+ continue;
12
+ }
13
+ data.push(...pretenderFile.data);
14
+ }
15
+ }
16
+ if (config.imports) {
17
+ for (const module of config.imports) {
18
+ const pretenderFile =
19
+ // eslint-disable-next-line unicorn/no-await-expression-member
20
+ (await generalImport(`${module}/package.json`))?.pretenders ??
21
+ (await generalImport(`${module}/pretenders.json`));
22
+ if (!pretenderFile?.data) {
23
+ continue;
24
+ }
25
+ data.push(...pretenderFile.data);
26
+ }
27
+ }
28
+ if (config.data) {
29
+ data.push(...config.data);
30
+ }
31
+ return data;
32
+ }
package/lib/types.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import type { Config } from '@markuplint/ml-config';
1
+ import type { OptimizedConfig } from '@markuplint/ml-config';
2
2
  import type { Plugin } from '@markuplint/ml-core';
3
3
  export interface ConfigSet {
4
- readonly config: Config;
4
+ readonly config: OptimizedConfig;
5
5
  readonly plugins: readonly Plugin[];
6
6
  readonly files: ReadonlySet<string>;
7
7
  readonly errs: readonly Readonly<Error>[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markuplint/file-resolver",
3
- "version": "4.7.2",
3
+ "version": "4.8.0",
4
4
  "description": "The file resolver of markuplint",
5
5
  "repository": "git@github.com:markuplint/markuplint.git",
6
6
  "author": "Yusuke Hirao <yusukehirao@me.com>",
@@ -24,23 +24,24 @@
24
24
  "clean": "tsc --build --clean"
25
25
  },
26
26
  "devDependencies": {
27
- "@types/node": "20.12.11"
27
+ "@types/node": "20.12.12"
28
28
  },
29
29
  "dependencies": {
30
- "@markuplint/html-parser": "4.6.2",
31
- "@markuplint/ml-ast": "4.3.1",
32
- "@markuplint/ml-config": "4.6.2",
33
- "@markuplint/ml-core": "4.7.2",
34
- "@markuplint/ml-spec": "4.6.0",
35
- "@markuplint/parser-utils": "4.6.2",
36
- "@markuplint/selector": "4.6.2",
37
- "@markuplint/shared": "4.4.0",
30
+ "@markuplint/html-parser": "4.6.3",
31
+ "@markuplint/ml-ast": "4.4.0",
32
+ "@markuplint/ml-config": "4.7.0",
33
+ "@markuplint/ml-core": "4.8.0",
34
+ "@markuplint/ml-spec": "4.6.1",
35
+ "@markuplint/parser-utils": "4.6.3",
36
+ "@markuplint/selector": "4.6.3",
37
+ "@markuplint/shared": "4.4.1",
38
38
  "cosmiconfig": "9.0.0",
39
39
  "debug": "4.3.4",
40
- "glob": "10.3.15",
40
+ "glob": "10.4.1",
41
41
  "ignore": "5.3.1",
42
+ "import-meta-resolve": "4.1.0",
42
43
  "jsonc": "2.0.0",
43
44
  "minimatch": "9.0.4"
44
45
  },
45
- "gitHead": "ca7dc6bf40eac4f2813e492878f889eb77751a70"
46
+ "gitHead": "bf70c41b1d2497e85b73c9ecd5551eb522e6bdfc"
46
47
  }