@teambit/dependencies 1.0.1237 → 1.0.1239
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/files-dependency-builder/detect-imported-packages.d.ts +21 -0
- package/dist/files-dependency-builder/detect-imported-packages.js +107 -0
- package/dist/files-dependency-builder/detect-imported-packages.js.map +1 -0
- package/dist/files-dependency-builder/detect-imported-packages.spec.d.ts +1 -0
- package/dist/files-dependency-builder/detect-imported-packages.spec.js +114 -0
- package/dist/files-dependency-builder/detect-imported-packages.spec.js.map +1 -0
- package/dist/files-dependency-builder/precinct/index.d.ts +8 -0
- package/dist/files-dependency-builder/precinct/index.js +19 -8
- package/dist/files-dependency-builder/precinct/index.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/files-dependency-builder/detect-imported-packages.spec.ts +74 -0
- package/files-dependency-builder/detect-imported-packages.ts +82 -0
- package/files-dependency-builder/precinct/index.ts +22 -10
- package/package.json +7 -6
- /package/dist/{preview-1792595323307.js → preview-1792615520466.js} +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type FileContent = {
|
|
2
|
+
relativePath: string;
|
|
3
|
+
content: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* the packages imported by the files of a component. a package that only dev files (e.g. tests) import is "dev".
|
|
7
|
+
*/
|
|
8
|
+
export type ImportedPackages = Map<string, 'runtime' | 'dev'>;
|
|
9
|
+
/**
|
|
10
|
+
* the import specifiers of a file per its path and content hash. files that didn't change between versions are parsed
|
|
11
|
+
* once. (not per content only, a detector may support a file by its name, e.g. env.jsonc). undefined when the file
|
|
12
|
+
* can't be parsed.
|
|
13
|
+
*/
|
|
14
|
+
export type ImportsCache = Map<string, string[] | undefined>;
|
|
15
|
+
/**
|
|
16
|
+
* the packages the given files import, found by parsing their content, without resolving the imports. a workspace
|
|
17
|
+
* resolves each import against node_modules (see AutoDetectDeps), a bare scope has the files in memory only.
|
|
18
|
+
* returns undefined when the imports of one of the files are unknown: it can't be parsed, or only an env detector
|
|
19
|
+
* supports its type.
|
|
20
|
+
*/
|
|
21
|
+
export declare function detectImportedPackages(files: FileContent[], isDevFile?: (relativePath: string) => boolean, cache?: ImportsCache): Promise<ImportedPackages | undefined>;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.detectImportedPackages = detectImportedPackages;
|
|
7
|
+
function _path() {
|
|
8
|
+
const data = _interopRequireDefault(require("path"));
|
|
9
|
+
_path = function () {
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
function _legacy() {
|
|
15
|
+
const data = require("@teambit/legacy.utils");
|
|
16
|
+
_legacy = function () {
|
|
17
|
+
return data;
|
|
18
|
+
};
|
|
19
|
+
return data;
|
|
20
|
+
}
|
|
21
|
+
function _toolboxCrypto() {
|
|
22
|
+
const data = require("@teambit/toolbox.crypto.sha1");
|
|
23
|
+
_toolboxCrypto = function () {
|
|
24
|
+
return data;
|
|
25
|
+
};
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
28
|
+
function _precinct() {
|
|
29
|
+
const data = _interopRequireDefault(require("./precinct"));
|
|
30
|
+
_precinct = function () {
|
|
31
|
+
return data;
|
|
32
|
+
};
|
|
33
|
+
return data;
|
|
34
|
+
}
|
|
35
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
36
|
+
/**
|
|
37
|
+
* the packages imported by the files of a component. a package that only dev files (e.g. tests) import is "dev".
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* the import specifiers of a file per its path and content hash. files that didn't change between versions are parsed
|
|
42
|
+
* once. (not per content only, a detector may support a file by its name, e.g. env.jsonc). undefined when the file
|
|
43
|
+
* can't be parsed.
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* files of these types have imports, but only an env detector finds them (see DependencyDetector). the env is not
|
|
48
|
+
* loaded here, so the imports of the component are unknown.
|
|
49
|
+
*/
|
|
50
|
+
const EXTENSIONS_OF_ENV_DETECTORS = ['.vue', '.svelte', '.astro'];
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* in files of these types, an import of a package starts with "~". without it, it's an import of a file, even when it's
|
|
54
|
+
* not relative (e.g. `@import 'variables'`), same as a workspace resolves it (see lookupStyling).
|
|
55
|
+
*/
|
|
56
|
+
const EXTENSIONS_OF_STYLE_FILES = ['.scss', '.sass', '.less'];
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* the packages the given files import, found by parsing their content, without resolving the imports. a workspace
|
|
60
|
+
* resolves each import against node_modules (see AutoDetectDeps), a bare scope has the files in memory only.
|
|
61
|
+
* returns undefined when the imports of one of the files are unknown: it can't be parsed, or only an env detector
|
|
62
|
+
* supports its type.
|
|
63
|
+
*/
|
|
64
|
+
async function detectImportedPackages(files, isDevFile = () => false, cache = new Map()) {
|
|
65
|
+
const importedPackages = new Map();
|
|
66
|
+
for (const file of files) {
|
|
67
|
+
const specifiers = await getImportSpecifiers(file, cache);
|
|
68
|
+
if (!specifiers) return undefined;
|
|
69
|
+
const type = isDevFile(file.relativePath) ? 'dev' : 'runtime';
|
|
70
|
+
const isStyleFile = EXTENSIONS_OF_STYLE_FILES.includes(_path().default.extname(file.relativePath));
|
|
71
|
+
specifiers.forEach(specifier => {
|
|
72
|
+
if (isStyleFile && !specifier.startsWith('~')) return;
|
|
73
|
+
const packageName = toPackageName(specifier);
|
|
74
|
+
if (!packageName || importedPackages.get(packageName) === 'runtime') return;
|
|
75
|
+
importedPackages.set(packageName, type);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return importedPackages;
|
|
79
|
+
}
|
|
80
|
+
async function getImportSpecifiers(file, cache) {
|
|
81
|
+
const ext = _path().default.extname(file.relativePath);
|
|
82
|
+
const key = `${file.relativePath}:${(0, _toolboxCrypto().sha1)(file.content)}`;
|
|
83
|
+
if (cache.has(key)) return cache.get(key);
|
|
84
|
+
let specifiers;
|
|
85
|
+
try {
|
|
86
|
+
specifiers = await _precinct().default.paperworkFromContent(file.relativePath, file.content, {
|
|
87
|
+
includeCore: false
|
|
88
|
+
});
|
|
89
|
+
// a file type with no detector has no imports, same as in a workspace whose env has no detector for it
|
|
90
|
+
if (!specifiers && !EXTENSIONS_OF_ENV_DETECTORS.includes(ext)) specifiers = [];
|
|
91
|
+
} catch {
|
|
92
|
+
specifiers = undefined; // a workspace doesn't snap it either, it reports a parsing error
|
|
93
|
+
}
|
|
94
|
+
cache.set(key, specifiers);
|
|
95
|
+
return specifiers;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* e.g. "@scope/pkg/dist/foo" => "@scope/pkg". undefined for an import of a file (relative), which is not a package.
|
|
100
|
+
*/
|
|
101
|
+
function toPackageName(specifier) {
|
|
102
|
+
if (specifier.startsWith('.') || specifier.startsWith('/') || specifier.startsWith('#')) return undefined;
|
|
103
|
+
if (specifier.includes('!') || /^https?:/.test(specifier)) return undefined; // webpack loaders and urls
|
|
104
|
+
return (0, _legacy().resolvePackageNameByPath)(specifier.replace(/^~/, ''));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
//# sourceMappingURL=detect-imported-packages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_path","data","_interopRequireDefault","require","_legacy","_toolboxCrypto","_precinct","e","__esModule","default","EXTENSIONS_OF_ENV_DETECTORS","EXTENSIONS_OF_STYLE_FILES","detectImportedPackages","files","isDevFile","cache","Map","importedPackages","file","specifiers","getImportSpecifiers","undefined","type","relativePath","isStyleFile","includes","path","extname","forEach","specifier","startsWith","packageName","toPackageName","get","set","ext","key","sha1","content","has","precinct","paperworkFromContent","includeCore","test","resolvePackageNameByPath","replace"],"sources":["detect-imported-packages.ts"],"sourcesContent":["import path from 'path';\nimport { resolvePackageNameByPath } from '@teambit/legacy.utils';\nimport { sha1 } from '@teambit/toolbox.crypto.sha1';\nimport precinct from './precinct';\n\nexport type FileContent = { relativePath: string; content: string };\n\n/**\n * the packages imported by the files of a component. a package that only dev files (e.g. tests) import is \"dev\".\n */\nexport type ImportedPackages = Map<string, 'runtime' | 'dev'>;\n\n/**\n * the import specifiers of a file per its path and content hash. files that didn't change between versions are parsed\n * once. (not per content only, a detector may support a file by its name, e.g. env.jsonc). undefined when the file\n * can't be parsed.\n */\nexport type ImportsCache = Map<string, string[] | undefined>;\n\n/**\n * files of these types have imports, but only an env detector finds them (see DependencyDetector). the env is not\n * loaded here, so the imports of the component are unknown.\n */\nconst EXTENSIONS_OF_ENV_DETECTORS = ['.vue', '.svelte', '.astro'];\n\n/**\n * in files of these types, an import of a package starts with \"~\". without it, it's an import of a file, even when it's\n * not relative (e.g. `@import 'variables'`), same as a workspace resolves it (see lookupStyling).\n */\nconst EXTENSIONS_OF_STYLE_FILES = ['.scss', '.sass', '.less'];\n\n/**\n * the packages the given files import, found by parsing their content, without resolving the imports. a workspace\n * resolves each import against node_modules (see AutoDetectDeps), a bare scope has the files in memory only.\n * returns undefined when the imports of one of the files are unknown: it can't be parsed, or only an env detector\n * supports its type.\n */\nexport async function detectImportedPackages(\n files: FileContent[],\n isDevFile: (relativePath: string) => boolean = () => false,\n cache: ImportsCache = new Map()\n): Promise<ImportedPackages | undefined> {\n const importedPackages: ImportedPackages = new Map();\n for (const file of files) {\n const specifiers = await getImportSpecifiers(file, cache);\n if (!specifiers) return undefined;\n const type = isDevFile(file.relativePath) ? 'dev' : 'runtime';\n const isStyleFile = EXTENSIONS_OF_STYLE_FILES.includes(path.extname(file.relativePath));\n specifiers.forEach((specifier) => {\n if (isStyleFile && !specifier.startsWith('~')) return;\n const packageName = toPackageName(specifier);\n if (!packageName || importedPackages.get(packageName) === 'runtime') return;\n importedPackages.set(packageName, type);\n });\n }\n return importedPackages;\n}\n\nasync function getImportSpecifiers(file: FileContent, cache: ImportsCache): Promise<string[] | undefined> {\n const ext = path.extname(file.relativePath);\n const key = `${file.relativePath}:${sha1(file.content)}`;\n if (cache.has(key)) return cache.get(key);\n let specifiers: string[] | undefined;\n try {\n specifiers = await precinct.paperworkFromContent(file.relativePath, file.content, { includeCore: false });\n // a file type with no detector has no imports, same as in a workspace whose env has no detector for it\n if (!specifiers && !EXTENSIONS_OF_ENV_DETECTORS.includes(ext)) specifiers = [];\n } catch {\n specifiers = undefined; // a workspace doesn't snap it either, it reports a parsing error\n }\n cache.set(key, specifiers);\n return specifiers;\n}\n\n/**\n * e.g. \"@scope/pkg/dist/foo\" => \"@scope/pkg\". undefined for an import of a file (relative), which is not a package.\n */\nfunction toPackageName(specifier: string): string | undefined {\n if (specifier.startsWith('.') || specifier.startsWith('/') || specifier.startsWith('#')) return undefined;\n if (specifier.includes('!') || /^https?:/.test(specifier)) return undefined; // webpack loaders and urls\n return resolvePackageNameByPath(specifier.replace(/^~/, ''));\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function _chai() {
|
|
4
|
+
const data = require("chai");
|
|
5
|
+
_chai = function () {
|
|
6
|
+
return data;
|
|
7
|
+
};
|
|
8
|
+
return data;
|
|
9
|
+
}
|
|
10
|
+
function _dependencyResolver() {
|
|
11
|
+
const data = require("@teambit/dependency-resolver");
|
|
12
|
+
_dependencyResolver = function () {
|
|
13
|
+
return data;
|
|
14
|
+
};
|
|
15
|
+
return data;
|
|
16
|
+
}
|
|
17
|
+
function _detectImportedPackages() {
|
|
18
|
+
const data = require("./detect-imported-packages");
|
|
19
|
+
_detectImportedPackages = function () {
|
|
20
|
+
return data;
|
|
21
|
+
};
|
|
22
|
+
return data;
|
|
23
|
+
}
|
|
24
|
+
describe('detectImportedPackages', () => {
|
|
25
|
+
const index = {
|
|
26
|
+
relativePath: 'index.ts',
|
|
27
|
+
content: `import a from './a';
|
|
28
|
+
import b from '@scope/b/dist/x';
|
|
29
|
+
import fs from 'fs';
|
|
30
|
+
import path from 'node:path';
|
|
31
|
+
import lodash from 'lodash';
|
|
32
|
+
const chalk = require('chalk');`
|
|
33
|
+
};
|
|
34
|
+
const spec = {
|
|
35
|
+
relativePath: 'index.spec.ts',
|
|
36
|
+
content: `import { expect } from 'chai';\nimport lodash from 'lodash';`
|
|
37
|
+
};
|
|
38
|
+
const isDevFile = relativePath => relativePath.endsWith('.spec.ts');
|
|
39
|
+
it('should return the imported packages, without files and node built-ins', async () => {
|
|
40
|
+
const packages = await (0, _detectImportedPackages().detectImportedPackages)([index], isDevFile);
|
|
41
|
+
(0, _chai().expect)(Object.fromEntries(packages)).to.deep.equal({
|
|
42
|
+
'@scope/b': 'runtime',
|
|
43
|
+
lodash: 'runtime',
|
|
44
|
+
chalk: 'runtime'
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
it('should set a package that only dev files import as dev', async () => {
|
|
48
|
+
const packages = await (0, _detectImportedPackages().detectImportedPackages)([spec, index], isDevFile);
|
|
49
|
+
(0, _chai().expect)(packages.get('chai')).to.equal('dev');
|
|
50
|
+
(0, _chai().expect)(packages.get('lodash')).to.equal('runtime');
|
|
51
|
+
});
|
|
52
|
+
it('should find packages imported by style files, not files imported without a relative path', async () => {
|
|
53
|
+
const scss = {
|
|
54
|
+
relativePath: 'style.scss',
|
|
55
|
+
content: `@import 'variables';\n@import '~@scope/theme/colors';`
|
|
56
|
+
};
|
|
57
|
+
const packages = await (0, _detectImportedPackages().detectImportedPackages)([scss]);
|
|
58
|
+
(0, _chai().expect)([...packages.keys()]).to.deep.equal(['@scope/theme']);
|
|
59
|
+
});
|
|
60
|
+
it('should ignore a file of a type without imports', async () => {
|
|
61
|
+
const png = {
|
|
62
|
+
relativePath: 'logo.png',
|
|
63
|
+
content: 'not-really-a-png'
|
|
64
|
+
};
|
|
65
|
+
const packages = await (0, _detectImportedPackages().detectImportedPackages)([png, index]);
|
|
66
|
+
(0, _chai().expect)(packages.size).to.equal(3);
|
|
67
|
+
});
|
|
68
|
+
it('should ignore a file with a @bit-no-check comment', async () => {
|
|
69
|
+
const noCheck = {
|
|
70
|
+
relativePath: 'no-check.ts',
|
|
71
|
+
content: `// @bit-no-check\nimport x from 'x';`
|
|
72
|
+
};
|
|
73
|
+
const packages = await (0, _detectImportedPackages().detectImportedPackages)([noCheck]);
|
|
74
|
+
(0, _chai().expect)(packages.size).to.equal(0);
|
|
75
|
+
});
|
|
76
|
+
it('should return undefined when only an env detector supports a file', async () => {
|
|
77
|
+
const vue = {
|
|
78
|
+
relativePath: 'comp.vue',
|
|
79
|
+
content: `<script>import x from 'x';</script>`
|
|
80
|
+
};
|
|
81
|
+
(0, _chai().expect)(await (0, _detectImportedPackages().detectImportedPackages)([vue, index])).to.equal(undefined);
|
|
82
|
+
});
|
|
83
|
+
it('should not share the imports of files with the same content and different names', async () => {
|
|
84
|
+
// e.g. the env.jsonc detector, which supports a file by its name
|
|
85
|
+
_dependencyResolver().DetectorHook.hooks.push({
|
|
86
|
+
isSupported: ({
|
|
87
|
+
filename
|
|
88
|
+
}) => filename.endsWith('env.jsonc'),
|
|
89
|
+
detect: () => ['@scope/base-env']
|
|
90
|
+
});
|
|
91
|
+
try {
|
|
92
|
+
const content = '{ "extends": "@scope/base-env" }';
|
|
93
|
+
const files = [{
|
|
94
|
+
relativePath: 'config.jsonc',
|
|
95
|
+
content
|
|
96
|
+
}, {
|
|
97
|
+
relativePath: 'env.jsonc',
|
|
98
|
+
content
|
|
99
|
+
}];
|
|
100
|
+
(0, _chai().expect)([...(await (0, _detectImportedPackages().detectImportedPackages)(files)).keys()]).to.deep.equal(['@scope/base-env']);
|
|
101
|
+
} finally {
|
|
102
|
+
_dependencyResolver().DetectorHook.hooks.pop();
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
it('should return undefined when a file can not be parsed', async () => {
|
|
106
|
+
const broken = {
|
|
107
|
+
relativePath: 'broken.js',
|
|
108
|
+
content: `import { from`
|
|
109
|
+
};
|
|
110
|
+
(0, _chai().expect)(await (0, _detectImportedPackages().detectImportedPackages)([broken, index])).to.equal(undefined);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
//# sourceMappingURL=detect-imported-packages.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_chai","data","require","_dependencyResolver","_detectImportedPackages","describe","index","relativePath","content","spec","isDevFile","endsWith","it","packages","detectImportedPackages","expect","Object","fromEntries","to","deep","equal","lodash","chalk","get","scss","keys","png","size","noCheck","vue","undefined","DetectorHook","hooks","push","isSupported","filename","detect","files","pop","broken"],"sources":["detect-imported-packages.spec.ts"],"sourcesContent":["import { expect } from 'chai';\nimport { DetectorHook } from '@teambit/dependency-resolver';\nimport { detectImportedPackages } from './detect-imported-packages';\n\ndescribe('detectImportedPackages', () => {\n const index = {\n relativePath: 'index.ts',\n content: `import a from './a';\nimport b from '@scope/b/dist/x';\nimport fs from 'fs';\nimport path from 'node:path';\nimport lodash from 'lodash';\nconst chalk = require('chalk');`,\n };\n const spec = {\n relativePath: 'index.spec.ts',\n content: `import { expect } from 'chai';\\nimport lodash from 'lodash';`,\n };\n const isDevFile = (relativePath: string) => relativePath.endsWith('.spec.ts');\n\n it('should return the imported packages, without files and node built-ins', async () => {\n const packages = await detectImportedPackages([index], isDevFile);\n expect(Object.fromEntries(packages!)).to.deep.equal({\n '@scope/b': 'runtime',\n lodash: 'runtime',\n chalk: 'runtime',\n });\n });\n it('should set a package that only dev files import as dev', async () => {\n const packages = await detectImportedPackages([spec, index], isDevFile);\n expect(packages!.get('chai')).to.equal('dev');\n expect(packages!.get('lodash')).to.equal('runtime');\n });\n it('should find packages imported by style files, not files imported without a relative path', async () => {\n const scss = { relativePath: 'style.scss', content: `@import 'variables';\\n@import '~@scope/theme/colors';` };\n const packages = await detectImportedPackages([scss]);\n expect([...packages!.keys()]).to.deep.equal(['@scope/theme']);\n });\n it('should ignore a file of a type without imports', async () => {\n const png = { relativePath: 'logo.png', content: 'not-really-a-png' };\n const packages = await detectImportedPackages([png, index]);\n expect(packages!.size).to.equal(3);\n });\n it('should ignore a file with a @bit-no-check comment', async () => {\n const noCheck = { relativePath: 'no-check.ts', content: `// @bit-no-check\\nimport x from 'x';` };\n const packages = await detectImportedPackages([noCheck]);\n expect(packages!.size).to.equal(0);\n });\n it('should return undefined when only an env detector supports a file', async () => {\n const vue = { relativePath: 'comp.vue', content: `<script>import x from 'x';</script>` };\n expect(await detectImportedPackages([vue, index])).to.equal(undefined);\n });\n it('should not share the imports of files with the same content and different names', async () => {\n // e.g. the env.jsonc detector, which supports a file by its name\n DetectorHook.hooks.push({\n isSupported: ({ filename }) => filename.endsWith('env.jsonc'),\n detect: () => ['@scope/base-env'],\n });\n try {\n const content = '{ \"extends\": \"@scope/base-env\" }';\n const files = [\n { relativePath: 'config.jsonc', content },\n { relativePath: 'env.jsonc', content },\n ];\n expect([...(await detectImportedPackages(files))!.keys()]).to.deep.equal(['@scope/base-env']);\n } finally {\n DetectorHook.hooks.pop();\n }\n });\n it('should return undefined when a file can not be parsed', async () => {\n const broken = { relativePath: 'broken.js', content: `import { from` };\n expect(await detectImportedPackages([broken, index])).to.equal(undefined);\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -6,8 +6,16 @@ type Options = {
|
|
|
6
6
|
type?: string;
|
|
7
7
|
[lang: string]: any;
|
|
8
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* returns undefined when the file type is not supported (no detector for it).
|
|
11
|
+
*/
|
|
12
|
+
declare const getDepsFromContent: (filename: string, content: string, options?: Options) => Promise<string[] | undefined>;
|
|
9
13
|
declare const getDepsFromFile: (filename: string, options?: Options) => Promise<string[]>;
|
|
10
14
|
declare const precinct: {
|
|
11
15
|
paperwork: typeof getDepsFromFile;
|
|
16
|
+
/**
|
|
17
|
+
* same as paperwork, for a file that is not on the filesystem (e.g. in a bare scope)
|
|
18
|
+
*/
|
|
19
|
+
paperworkFromContent: typeof getDepsFromContent;
|
|
12
20
|
};
|
|
13
21
|
export default precinct;
|
|
@@ -164,11 +164,10 @@ const assign = (o1, o2) => {
|
|
|
164
164
|
};
|
|
165
165
|
|
|
166
166
|
/**
|
|
167
|
-
* Get file info from the given file path.
|
|
167
|
+
* Get file info from the given file path and its content.
|
|
168
168
|
*/
|
|
169
|
-
const getFileInfo = filename => {
|
|
169
|
+
const getFileInfo = (filename, content) => {
|
|
170
170
|
const ext = _path().default.extname(filename);
|
|
171
|
-
const content = _fsExtra().default.readFileSync(filename, 'utf8');
|
|
172
171
|
return {
|
|
173
172
|
ext,
|
|
174
173
|
content,
|
|
@@ -264,26 +263,38 @@ const normalizeDeps = (deps, includeCore) => {
|
|
|
264
263
|
const normalizedDeps = Array.isArray(deps) ? deps : Object.keys(deps);
|
|
265
264
|
return includeCore ? normalizedDeps : normalizedDeps.filter(d => !(0, _module().isBuiltin)(d));
|
|
266
265
|
};
|
|
267
|
-
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* returns undefined when the file type is not supported (no detector for it).
|
|
269
|
+
*/
|
|
270
|
+
const getDepsFromContent = async (filename, content, options) => {
|
|
268
271
|
const normalizedOptions = assign({
|
|
269
272
|
includeCore: true
|
|
270
273
|
}, options || {});
|
|
271
|
-
const fileInfo = getFileInfo(filename);
|
|
272
|
-
if (
|
|
274
|
+
const fileInfo = getFileInfo(filename, content);
|
|
275
|
+
if (content.startsWith('// @bit-no-check') || content.startsWith('/* @bit-no-check')) {
|
|
273
276
|
debug(`skipping file ${filename}, it has a @bit-no-check comment`);
|
|
274
277
|
return [];
|
|
275
278
|
}
|
|
276
279
|
const detective = getDetector(fileInfo, normalizedOptions) || getJsDetector(fileInfo, normalizedOptions);
|
|
277
280
|
if (!detective) {
|
|
278
281
|
debug(`skipping unsupported file ${filename}`);
|
|
279
|
-
return
|
|
282
|
+
return undefined;
|
|
280
283
|
}
|
|
281
284
|
debug('module type: ', fileInfo.type);
|
|
282
285
|
const deps = await detective(fileInfo.ast, normalizedOptions[fileInfo.type]);
|
|
283
286
|
return normalizeDeps(deps, normalizedOptions?.includeCore);
|
|
284
287
|
};
|
|
288
|
+
const getDepsFromFile = async (filename, options) => {
|
|
289
|
+
const content = _fsExtra().default.readFileSync(filename, 'utf8');
|
|
290
|
+
return (await getDepsFromContent(filename, content, options)) || [];
|
|
291
|
+
};
|
|
285
292
|
const precinct = {
|
|
286
|
-
paperwork: getDepsFromFile
|
|
293
|
+
paperwork: getDepsFromFile,
|
|
294
|
+
/**
|
|
295
|
+
* same as paperwork, for a file that is not on the filesystem (e.g. in a bare scope)
|
|
296
|
+
*/
|
|
297
|
+
paperworkFromContent: getDepsFromContent
|
|
287
298
|
};
|
|
288
299
|
var _default = exports.default = precinct;
|
|
289
300
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_fsExtra","data","_interopRequireDefault","require","_path","_module","_moduleDefinition","_nodeSourceWalk","_detectiveAmd","_detectiveStylus","_mdxDepsDetectors","_nodeDepsDetectors","_stylingDepsDetectors","_stylingDepsDetectors2","_stylingDepsDetectors3","_stylingDepsDetectors4","_typescriptDepsDetectors","_dependencyResolver","e","__esModule","default","jsExt","extToType","typeToDetective","css","detectiveCss","sass","detectiveSass","less","detectiveLess","scss","detectiveScss","stylus","detectiveStylus","ts","detectiveTypeScript","commonjs","detectiveEs6","es6","amd","detectiveAmd","md","detectiveMdx","debug","detectorHook","DetectorHook","assign","o1","o2","key","hasOwnProperty","getFileInfo","filename","ext","path","extname","content","fs","readFileSync","type","ast","getDetector","fileInfo","options","normalizedOptions","envDetectors","detector","isSupported","detect","detective","jsx","undefined","getJsDetector","includes","walker","Walker","parse","message","useContent","getModuleType","fromSource","normalizeDeps","deps","includeCore","normalizedDeps","Array","isArray","Object","keys","filter","d","isBuiltin","getDepsFromFile","startsWith","precinct","paperwork","_default","exports"],"sources":["index.ts"],"sourcesContent":["/**\n * this file had been forked from https://github.com/dependents/node-precinct\n */\nimport fs from 'fs-extra';\nimport path from 'path';\n// @ts-ignore we currently have @types/node as v12, and this is available > 16. once updated, remove the ts-ignore\nimport { isBuiltin } from 'module';\n\nimport getModuleType from 'module-definition';\nimport Walker from 'node-source-walk';\n\nimport detectiveAmd from 'detective-amd';\nimport detectiveStylus from 'detective-stylus';\n\nimport detectiveMdx from '@teambit/mdx.deps-detectors.detective-mdx';\nimport detectiveEs6 from '@teambit/node.deps-detectors.detective-es6';\nimport detectiveCss from '@teambit/styling.deps-detectors.detective-css';\nimport detectiveLess from '@teambit/styling.deps-detectors.detective-less';\nimport detectiveSass from '@teambit/styling.deps-detectors.detective-sass';\nimport detectiveScss from '@teambit/styling.deps-detectors.detective-scss';\nimport detectiveTypeScript from '@teambit/typescript.deps-detectors.detective-typescript';\n\nimport type { DependencyDetector } from '@teambit/dependency-resolver';\nimport { DetectorHook } from '@teambit/dependency-resolver';\n\n/**\n * The file info object.\n * - `ext` is the file extension.\n * - `content` is the input file content.\n * - `type` is the parsed file type from ext or content.\n * - `ast` is the eventually consumed content by the corresponding detective.\n */\ntype FileInfo = {\n ext: string;\n content: string | object;\n type: string;\n ast: any;\n filename: string;\n};\n\ntype Options = {\n envDetectors?: DependencyDetector[];\n useContent?: boolean;\n includeCore?: boolean;\n type?: string;\n [lang: string]: any;\n};\n\ntype BuiltinDeps = string[] | Record<string, any>;\ntype Detective = (fileContent: string, options?: any) => BuiltinDeps;\n\nconst jsExt = ['.js', '.jsx', '.cjs', '.mjs'];\n\nconst extToType = {\n '.css': 'css',\n '.sass': 'sass',\n '.less': 'less',\n '.scss': 'scss',\n '.styl': 'stylus',\n '.mts': 'ts',\n '.cts': 'ts',\n '.ts': 'ts',\n '.tsx': 'ts',\n '.md': 'md',\n '.mdx': 'md',\n};\n\nconst typeToDetective: Record<string, Detective> = {\n css: detectiveCss,\n sass: detectiveSass,\n less: detectiveLess,\n scss: detectiveScss,\n stylus: detectiveStylus,\n ts: detectiveTypeScript,\n commonjs: detectiveEs6,\n es6: detectiveEs6,\n amd: detectiveAmd,\n md: detectiveMdx,\n};\n\nconst debug = require('debug')('precinct');\n\nconst detectorHook = new DetectorHook();\n\nconst assign = (o1, o2) => {\n // eslint-disable-next-line\n for (const key in o2) {\n // eslint-disable-next-line\n if (o2.hasOwnProperty(key)) {\n o1[key] = o2[key];\n }\n }\n\n return o1;\n};\n\n/**\n * Get file info from the given file path.\n */\nconst getFileInfo = (filename: string): FileInfo => {\n const ext = path.extname(filename);\n const content = fs.readFileSync(filename, 'utf8');\n return {\n ext,\n content,\n // determined later\n type: '',\n // initialized with the content\n ast: content,\n filename,\n };\n};\n\n/**\n * Get the non-JS detective for the given file info.\n * The type of the file would be determined as well.\n * Return undefined if no proper detective found, perhaps it's plain\n * JavaScript or unknown content. We can deal with it later.\n */\nconst getDetector = (fileInfo: FileInfo, options?: Options): Detective | undefined => {\n const { ext, filename } = fileInfo;\n const normalizedOptions: Options = options || {};\n\n // from env detectors\n if (options?.envDetectors) {\n for (const detector of options.envDetectors) {\n if (detector.isSupported({ ext, filename })) {\n fileInfo.type = detector.type || '';\n return detector.detect as Detective;\n }\n }\n }\n\n // from the global detector hook. checked before the builtin detectors so that an\n // aspect-registered detector (e.g. the mdx aspect's compile-based one) takes precedence over a\n // builtin detective for the same extension, same as env detectors do.\n if (detectorHook.isSupported(ext, filename)) {\n const detector = detectorHook.getDetector(ext, filename);\n if (detector) {\n fileInfo.type = ext;\n return detector.detect as Detective;\n }\n }\n\n // from builtin detectors\n // - check `fileInfo.type` first to support `precinct(content, { type })`\n const type = fileInfo.type || extToType[ext];\n if (typeToDetective[type]) {\n const detective = typeToDetective[type];\n fileInfo.type = type;\n // special logic for tsx files\n if (ext === '.tsx') {\n if (!normalizedOptions.ts) normalizedOptions.ts = {};\n normalizedOptions.ts.jsx = true;\n }\n return detective;\n }\n\n return undefined;\n};\n\n/**\n * Get the JS detective (amd/es6/cjs) for the given file info.\n * The type and ast of the file would be determined as well.\n */\nconst getJsDetector = (fileInfo: FileInfo, options?: Options): Detective | undefined => {\n if (!jsExt.includes(fileInfo.ext)) {\n return undefined;\n }\n\n if (typeof fileInfo.content !== 'object') {\n const walker = new Walker();\n try {\n fileInfo.ast = walker.parse(fileInfo.content);\n } catch (e: any) {\n debug('could not parse content: %s', e.message);\n throw e;\n }\n }\n\n const useContent = options?.useContent;\n const type = useContent ? getModuleType.fromSource(fileInfo.content) : getModuleType.fromSource(fileInfo.ast);\n const detector = typeToDetective[type];\n fileInfo.type = type;\n\n return detector;\n};\n\n/**\n * Normalize the deps into an array.\n */\nconst normalizeDeps = (deps: BuiltinDeps, includeCore?: boolean): string[] => {\n const normalizedDeps = Array.isArray(deps) ? deps : Object.keys(deps);\n return includeCore ? normalizedDeps : normalizedDeps.filter((d) => !isBuiltin(d));\n};\n\nconst getDepsFromFile = async (filename: string, options?: Options): Promise<string[]> => {\n const normalizedOptions: Options = assign({ includeCore: true }, options || {});\n const fileInfo = getFileInfo(filename);\n if (\n typeof fileInfo.content === 'string' &&\n (fileInfo.content.startsWith('// @bit-no-check') || fileInfo.content.startsWith('/* @bit-no-check'))\n ) {\n debug(`skipping file ${filename}, it has a @bit-no-check comment`);\n return [];\n }\n\n const detective = getDetector(fileInfo, normalizedOptions) || getJsDetector(fileInfo, normalizedOptions);\n if (!detective) {\n debug(`skipping unsupported file ${filename}`);\n return [];\n }\n debug('module type: ', fileInfo.type);\n\n const deps = await detective(fileInfo.ast, normalizedOptions[fileInfo.type]);\n\n return normalizeDeps(deps, normalizedOptions?.includeCore);\n};\n\nconst precinct = {\n paperwork: getDepsFromFile,\n};\n\nexport default precinct;\n"],"mappings":";;;;;;AAGA,SAAAA,SAAA;EAAA,MAAAC,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAH,QAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAG,MAAA;EAAA,MAAAH,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAC,KAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAI,QAAA;EAAA,MAAAJ,IAAA,GAAAE,OAAA;EAAAE,OAAA,YAAAA,CAAA;IAAA,OAAAJ,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAK,kBAAA;EAAA,MAAAL,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAG,iBAAA,YAAAA,CAAA;IAAA,OAAAL,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAM,gBAAA;EAAA,MAAAN,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAI,eAAA,YAAAA,CAAA;IAAA,OAAAN,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAO,cAAA;EAAA,MAAAP,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAK,aAAA,YAAAA,CAAA;IAAA,OAAAP,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAQ,iBAAA;EAAA,MAAAR,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAM,gBAAA,YAAAA,CAAA;IAAA,OAAAR,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAS,kBAAA;EAAA,MAAAT,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAO,iBAAA,YAAAA,CAAA;IAAA,OAAAT,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAU,mBAAA;EAAA,MAAAV,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAQ,kBAAA,YAAAA,CAAA;IAAA,OAAAV,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAW,sBAAA;EAAA,MAAAX,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAS,qBAAA,YAAAA,CAAA;IAAA,OAAAX,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAY,uBAAA;EAAA,MAAAZ,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAU,sBAAA,YAAAA,CAAA;IAAA,OAAAZ,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAa,uBAAA;EAAA,MAAAb,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAW,sBAAA,YAAAA,CAAA;IAAA,OAAAb,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAc,uBAAA;EAAA,MAAAd,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAY,sBAAA,YAAAA,CAAA;IAAA,OAAAd,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAe,yBAAA;EAAA,MAAAf,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAa,wBAAA,YAAAA,CAAA;IAAA,OAAAf,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAGA,SAAAgB,oBAAA;EAAA,MAAAhB,IAAA,GAAAE,OAAA;EAAAc,mBAAA,YAAAA,CAAA;IAAA,OAAAhB,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAA4D,SAAAC,uBAAAgB,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAvB5D;AACA;AACA;;AAGA;;AAoBA;AACA;AACA;AACA;AACA;AACA;AACA;;AAoBA,MAAMG,KAAK,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;AAE7C,MAAMC,SAAS,GAAG;EAChB,MAAM,EAAE,KAAK;EACb,OAAO,EAAE,MAAM;EACf,OAAO,EAAE,MAAM;EACf,OAAO,EAAE,MAAM;EACf,OAAO,EAAE,QAAQ;EACjB,MAAM,EAAE,IAAI;EACZ,MAAM,EAAE,IAAI;EACZ,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,KAAK,EAAE,IAAI;EACX,MAAM,EAAE;AACV,CAAC;AAED,MAAMC,eAA0C,GAAG;EACjDC,GAAG,EAAEC,+BAAY;EACjBC,IAAI,EAAEC,gCAAa;EACnBC,IAAI,EAAEC,gCAAa;EACnBC,IAAI,EAAEC,gCAAa;EACnBC,MAAM,EAAEC,0BAAe;EACvBC,EAAE,EAAEC,kCAAmB;EACvBC,QAAQ,EAAEC,4BAAY;EACtBC,GAAG,EAAED,4BAAY;EACjBE,GAAG,EAAEC,uBAAY;EACjBC,EAAE,EAAEC;AACN,CAAC;AAED,MAAMC,KAAK,GAAGxC,OAAO,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC;AAE1C,MAAMyC,YAAY,GAAG,KAAIC,kCAAY,EAAC,CAAC;AAEvC,MAAMC,MAAM,GAAGA,CAACC,EAAE,EAAEC,EAAE,KAAK;EACzB;EACA,KAAK,MAAMC,GAAG,IAAID,EAAE,EAAE;IACpB;IACA,IAAIA,EAAE,CAACE,cAAc,CAACD,GAAG,CAAC,EAAE;MAC1BF,EAAE,CAACE,GAAG,CAAC,GAAGD,EAAE,CAACC,GAAG,CAAC;IACnB;EACF;EAEA,OAAOF,EAAE;AACX,CAAC;;AAED;AACA;AACA;AACA,MAAMI,WAAW,GAAIC,QAAgB,IAAe;EAClD,MAAMC,GAAG,GAAGC,eAAI,CAACC,OAAO,CAACH,QAAQ,CAAC;EAClC,MAAMI,OAAO,GAAGC,kBAAE,CAACC,YAAY,CAACN,QAAQ,EAAE,MAAM,CAAC;EACjD,OAAO;IACLC,GAAG;IACHG,OAAO;IACP;IACAG,IAAI,EAAE,EAAE;IACR;IACAC,GAAG,EAAEJ,OAAO;IACZJ;EACF,CAAC;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,MAAMS,WAAW,GAAGA,CAACC,QAAkB,EAAEC,OAAiB,KAA4B;EACpF,MAAM;IAAEV,GAAG;IAAED;EAAS,CAAC,GAAGU,QAAQ;EAClC,MAAME,iBAA0B,GAAGD,OAAO,IAAI,CAAC,CAAC;;EAEhD;EACA,IAAIA,OAAO,EAAEE,YAAY,EAAE;IACzB,KAAK,MAAMC,QAAQ,IAAIH,OAAO,CAACE,YAAY,EAAE;MAC3C,IAAIC,QAAQ,CAACC,WAAW,CAAC;QAAEd,GAAG;QAAED;MAAS,CAAC,CAAC,EAAE;QAC3CU,QAAQ,CAACH,IAAI,GAAGO,QAAQ,CAACP,IAAI,IAAI,EAAE;QACnC,OAAOO,QAAQ,CAACE,MAAM;MACxB;IACF;EACF;;EAEA;EACA;EACA;EACA,IAAIxB,YAAY,CAACuB,WAAW,CAACd,GAAG,EAAED,QAAQ,CAAC,EAAE;IAC3C,MAAMc,QAAQ,GAAGtB,YAAY,CAACiB,WAAW,CAACR,GAAG,EAAED,QAAQ,CAAC;IACxD,IAAIc,QAAQ,EAAE;MACZJ,QAAQ,CAACH,IAAI,GAAGN,GAAG;MACnB,OAAOa,QAAQ,CAACE,MAAM;IACxB;EACF;;EAEA;EACA;EACA,MAAMT,IAAI,GAAGG,QAAQ,CAACH,IAAI,IAAIrC,SAAS,CAAC+B,GAAG,CAAC;EAC5C,IAAI9B,eAAe,CAACoC,IAAI,CAAC,EAAE;IACzB,MAAMU,SAAS,GAAG9C,eAAe,CAACoC,IAAI,CAAC;IACvCG,QAAQ,CAACH,IAAI,GAAGA,IAAI;IACpB;IACA,IAAIN,GAAG,KAAK,MAAM,EAAE;MAClB,IAAI,CAACW,iBAAiB,CAAC9B,EAAE,EAAE8B,iBAAiB,CAAC9B,EAAE,GAAG,CAAC,CAAC;MACpD8B,iBAAiB,CAAC9B,EAAE,CAACoC,GAAG,GAAG,IAAI;IACjC;IACA,OAAOD,SAAS;EAClB;EAEA,OAAOE,SAAS;AAClB,CAAC;;AAED;AACA;AACA;AACA;AACA,MAAMC,aAAa,GAAGA,CAACV,QAAkB,EAAEC,OAAiB,KAA4B;EACtF,IAAI,CAAC1C,KAAK,CAACoD,QAAQ,CAACX,QAAQ,CAACT,GAAG,CAAC,EAAE;IACjC,OAAOkB,SAAS;EAClB;EAEA,IAAI,OAAOT,QAAQ,CAACN,OAAO,KAAK,QAAQ,EAAE;IACxC,MAAMkB,MAAM,GAAG,KAAIC,yBAAM,EAAC,CAAC;IAC3B,IAAI;MACFb,QAAQ,CAACF,GAAG,GAAGc,MAAM,CAACE,KAAK,CAACd,QAAQ,CAACN,OAAO,CAAC;IAC/C,CAAC,CAAC,OAAOtC,CAAM,EAAE;MACfyB,KAAK,CAAC,6BAA6B,EAAEzB,CAAC,CAAC2D,OAAO,CAAC;MAC/C,MAAM3D,CAAC;IACT;EACF;EAEA,MAAM4D,UAAU,GAAGf,OAAO,EAAEe,UAAU;EACtC,MAAMnB,IAAI,GAAGmB,UAAU,GAAGC,2BAAa,CAACC,UAAU,CAAClB,QAAQ,CAACN,OAAO,CAAC,GAAGuB,2BAAa,CAACC,UAAU,CAAClB,QAAQ,CAACF,GAAG,CAAC;EAC7G,MAAMM,QAAQ,GAAG3C,eAAe,CAACoC,IAAI,CAAC;EACtCG,QAAQ,CAACH,IAAI,GAAGA,IAAI;EAEpB,OAAOO,QAAQ;AACjB,CAAC;;AAED;AACA;AACA;AACA,MAAMe,aAAa,GAAGA,CAACC,IAAiB,EAAEC,WAAqB,KAAe;EAC5E,MAAMC,cAAc,GAAGC,KAAK,CAACC,OAAO,CAACJ,IAAI,CAAC,GAAGA,IAAI,GAAGK,MAAM,CAACC,IAAI,CAACN,IAAI,CAAC;EACrE,OAAOC,WAAW,GAAGC,cAAc,GAAGA,cAAc,CAACK,MAAM,CAAEC,CAAC,IAAK,CAAC,IAAAC,mBAAS,EAACD,CAAC,CAAC,CAAC;AACnF,CAAC;AAED,MAAME,eAAe,GAAG,MAAAA,CAAOxC,QAAgB,EAAEW,OAAiB,KAAwB;EACxF,MAAMC,iBAA0B,GAAGlB,MAAM,CAAC;IAAEqC,WAAW,EAAE;EAAK,CAAC,EAAEpB,OAAO,IAAI,CAAC,CAAC,CAAC;EAC/E,MAAMD,QAAQ,GAAGX,WAAW,CAACC,QAAQ,CAAC;EACtC,IACE,OAAOU,QAAQ,CAACN,OAAO,KAAK,QAAQ,KACnCM,QAAQ,CAACN,OAAO,CAACqC,UAAU,CAAC,kBAAkB,CAAC,IAAI/B,QAAQ,CAACN,OAAO,CAACqC,UAAU,CAAC,kBAAkB,CAAC,CAAC,EACpG;IACAlD,KAAK,CAAC,iBAAiBS,QAAQ,kCAAkC,CAAC;IAClE,OAAO,EAAE;EACX;EAEA,MAAMiB,SAAS,GAAGR,WAAW,CAACC,QAAQ,EAAEE,iBAAiB,CAAC,IAAIQ,aAAa,CAACV,QAAQ,EAAEE,iBAAiB,CAAC;EACxG,IAAI,CAACK,SAAS,EAAE;IACd1B,KAAK,CAAC,6BAA6BS,QAAQ,EAAE,CAAC;IAC9C,OAAO,EAAE;EACX;EACAT,KAAK,CAAC,eAAe,EAAEmB,QAAQ,CAACH,IAAI,CAAC;EAErC,MAAMuB,IAAI,GAAG,MAAMb,SAAS,CAACP,QAAQ,CAACF,GAAG,EAAEI,iBAAiB,CAACF,QAAQ,CAACH,IAAI,CAAC,CAAC;EAE5E,OAAOsB,aAAa,CAACC,IAAI,EAAElB,iBAAiB,EAAEmB,WAAW,CAAC;AAC5D,CAAC;AAED,MAAMW,QAAQ,GAAG;EACfC,SAAS,EAAEH;AACb,CAAC;AAAC,IAAAI,QAAA,GAAAC,OAAA,CAAA7E,OAAA,GAEa0E,QAAQ","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_fsExtra","data","_interopRequireDefault","require","_path","_module","_moduleDefinition","_nodeSourceWalk","_detectiveAmd","_detectiveStylus","_mdxDepsDetectors","_nodeDepsDetectors","_stylingDepsDetectors","_stylingDepsDetectors2","_stylingDepsDetectors3","_stylingDepsDetectors4","_typescriptDepsDetectors","_dependencyResolver","e","__esModule","default","jsExt","extToType","typeToDetective","css","detectiveCss","sass","detectiveSass","less","detectiveLess","scss","detectiveScss","stylus","detectiveStylus","ts","detectiveTypeScript","commonjs","detectiveEs6","es6","amd","detectiveAmd","md","detectiveMdx","debug","detectorHook","DetectorHook","assign","o1","o2","key","hasOwnProperty","getFileInfo","filename","content","ext","path","extname","type","ast","getDetector","fileInfo","options","normalizedOptions","envDetectors","detector","isSupported","detect","detective","jsx","undefined","getJsDetector","includes","walker","Walker","parse","message","useContent","getModuleType","fromSource","normalizeDeps","deps","includeCore","normalizedDeps","Array","isArray","Object","keys","filter","d","isBuiltin","getDepsFromContent","startsWith","getDepsFromFile","fs","readFileSync","precinct","paperwork","paperworkFromContent","_default","exports"],"sources":["index.ts"],"sourcesContent":["/**\n * this file had been forked from https://github.com/dependents/node-precinct\n */\nimport fs from 'fs-extra';\nimport path from 'path';\n// @ts-ignore we currently have @types/node as v12, and this is available > 16. once updated, remove the ts-ignore\nimport { isBuiltin } from 'module';\n\nimport getModuleType from 'module-definition';\nimport Walker from 'node-source-walk';\n\nimport detectiveAmd from 'detective-amd';\nimport detectiveStylus from 'detective-stylus';\n\nimport detectiveMdx from '@teambit/mdx.deps-detectors.detective-mdx';\nimport detectiveEs6 from '@teambit/node.deps-detectors.detective-es6';\nimport detectiveCss from '@teambit/styling.deps-detectors.detective-css';\nimport detectiveLess from '@teambit/styling.deps-detectors.detective-less';\nimport detectiveSass from '@teambit/styling.deps-detectors.detective-sass';\nimport detectiveScss from '@teambit/styling.deps-detectors.detective-scss';\nimport detectiveTypeScript from '@teambit/typescript.deps-detectors.detective-typescript';\n\nimport type { DependencyDetector } from '@teambit/dependency-resolver';\nimport { DetectorHook } from '@teambit/dependency-resolver';\n\n/**\n * The file info object.\n * - `ext` is the file extension.\n * - `content` is the input file content.\n * - `type` is the parsed file type from ext or content.\n * - `ast` is the eventually consumed content by the corresponding detective.\n */\ntype FileInfo = {\n ext: string;\n content: string | object;\n type: string;\n ast: any;\n filename: string;\n};\n\ntype Options = {\n envDetectors?: DependencyDetector[];\n useContent?: boolean;\n includeCore?: boolean;\n type?: string;\n [lang: string]: any;\n};\n\ntype BuiltinDeps = string[] | Record<string, any>;\ntype Detective = (fileContent: string, options?: any) => BuiltinDeps;\n\nconst jsExt = ['.js', '.jsx', '.cjs', '.mjs'];\n\nconst extToType = {\n '.css': 'css',\n '.sass': 'sass',\n '.less': 'less',\n '.scss': 'scss',\n '.styl': 'stylus',\n '.mts': 'ts',\n '.cts': 'ts',\n '.ts': 'ts',\n '.tsx': 'ts',\n '.md': 'md',\n '.mdx': 'md',\n};\n\nconst typeToDetective: Record<string, Detective> = {\n css: detectiveCss,\n sass: detectiveSass,\n less: detectiveLess,\n scss: detectiveScss,\n stylus: detectiveStylus,\n ts: detectiveTypeScript,\n commonjs: detectiveEs6,\n es6: detectiveEs6,\n amd: detectiveAmd,\n md: detectiveMdx,\n};\n\nconst debug = require('debug')('precinct');\n\nconst detectorHook = new DetectorHook();\n\nconst assign = (o1, o2) => {\n // eslint-disable-next-line\n for (const key in o2) {\n // eslint-disable-next-line\n if (o2.hasOwnProperty(key)) {\n o1[key] = o2[key];\n }\n }\n\n return o1;\n};\n\n/**\n * Get file info from the given file path and its content.\n */\nconst getFileInfo = (filename: string, content: string): FileInfo => {\n const ext = path.extname(filename);\n return {\n ext,\n content,\n // determined later\n type: '',\n // initialized with the content\n ast: content,\n filename,\n };\n};\n\n/**\n * Get the non-JS detective for the given file info.\n * The type of the file would be determined as well.\n * Return undefined if no proper detective found, perhaps it's plain\n * JavaScript or unknown content. We can deal with it later.\n */\nconst getDetector = (fileInfo: FileInfo, options?: Options): Detective | undefined => {\n const { ext, filename } = fileInfo;\n const normalizedOptions: Options = options || {};\n\n // from env detectors\n if (options?.envDetectors) {\n for (const detector of options.envDetectors) {\n if (detector.isSupported({ ext, filename })) {\n fileInfo.type = detector.type || '';\n return detector.detect as Detective;\n }\n }\n }\n\n // from the global detector hook. checked before the builtin detectors so that an\n // aspect-registered detector (e.g. the mdx aspect's compile-based one) takes precedence over a\n // builtin detective for the same extension, same as env detectors do.\n if (detectorHook.isSupported(ext, filename)) {\n const detector = detectorHook.getDetector(ext, filename);\n if (detector) {\n fileInfo.type = ext;\n return detector.detect as Detective;\n }\n }\n\n // from builtin detectors\n // - check `fileInfo.type` first to support `precinct(content, { type })`\n const type = fileInfo.type || extToType[ext];\n if (typeToDetective[type]) {\n const detective = typeToDetective[type];\n fileInfo.type = type;\n // special logic for tsx files\n if (ext === '.tsx') {\n if (!normalizedOptions.ts) normalizedOptions.ts = {};\n normalizedOptions.ts.jsx = true;\n }\n return detective;\n }\n\n return undefined;\n};\n\n/**\n * Get the JS detective (amd/es6/cjs) for the given file info.\n * The type and ast of the file would be determined as well.\n */\nconst getJsDetector = (fileInfo: FileInfo, options?: Options): Detective | undefined => {\n if (!jsExt.includes(fileInfo.ext)) {\n return undefined;\n }\n\n if (typeof fileInfo.content !== 'object') {\n const walker = new Walker();\n try {\n fileInfo.ast = walker.parse(fileInfo.content);\n } catch (e: any) {\n debug('could not parse content: %s', e.message);\n throw e;\n }\n }\n\n const useContent = options?.useContent;\n const type = useContent ? getModuleType.fromSource(fileInfo.content) : getModuleType.fromSource(fileInfo.ast);\n const detector = typeToDetective[type];\n fileInfo.type = type;\n\n return detector;\n};\n\n/**\n * Normalize the deps into an array.\n */\nconst normalizeDeps = (deps: BuiltinDeps, includeCore?: boolean): string[] => {\n const normalizedDeps = Array.isArray(deps) ? deps : Object.keys(deps);\n return includeCore ? normalizedDeps : normalizedDeps.filter((d) => !isBuiltin(d));\n};\n\n/**\n * returns undefined when the file type is not supported (no detector for it).\n */\nconst getDepsFromContent = async (\n filename: string,\n content: string,\n options?: Options\n): Promise<string[] | undefined> => {\n const normalizedOptions: Options = assign({ includeCore: true }, options || {});\n const fileInfo = getFileInfo(filename, content);\n if (content.startsWith('// @bit-no-check') || content.startsWith('/* @bit-no-check')) {\n debug(`skipping file ${filename}, it has a @bit-no-check comment`);\n return [];\n }\n\n const detective = getDetector(fileInfo, normalizedOptions) || getJsDetector(fileInfo, normalizedOptions);\n if (!detective) {\n debug(`skipping unsupported file ${filename}`);\n return undefined;\n }\n debug('module type: ', fileInfo.type);\n\n const deps = await detective(fileInfo.ast, normalizedOptions[fileInfo.type]);\n\n return normalizeDeps(deps, normalizedOptions?.includeCore);\n};\n\nconst getDepsFromFile = async (filename: string, options?: Options): Promise<string[]> => {\n const content = fs.readFileSync(filename, 'utf8');\n return (await getDepsFromContent(filename, content, options)) || [];\n};\n\nconst precinct = {\n paperwork: getDepsFromFile,\n /**\n * same as paperwork, for a file that is not on the filesystem (e.g. in a bare scope)\n */\n paperworkFromContent: getDepsFromContent,\n};\n\nexport default precinct;\n"],"mappings":"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","ignoreList":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,3 +2,5 @@ import { DependenciesAspect } from './dependencies.aspect';
|
|
|
2
2
|
export type { DependenciesMain } from './dependencies.main.runtime';
|
|
3
3
|
export default DependenciesAspect;
|
|
4
4
|
export { DependenciesAspect };
|
|
5
|
+
export { detectImportedPackages } from './files-dependency-builder/detect-imported-packages';
|
|
6
|
+
export type { ImportedPackages, ImportsCache, FileContent } from './files-dependency-builder/detect-imported-packages';
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,12 @@ Object.defineProperty(exports, "DependenciesAspect", {
|
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
12
|
exports.default = void 0;
|
|
13
|
+
Object.defineProperty(exports, "detectImportedPackages", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () {
|
|
16
|
+
return _detectImportedPackages().detectImportedPackages;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
13
19
|
function _dependencies() {
|
|
14
20
|
const data = require("./dependencies.aspect");
|
|
15
21
|
_dependencies = function () {
|
|
@@ -17,6 +23,13 @@ function _dependencies() {
|
|
|
17
23
|
};
|
|
18
24
|
return data;
|
|
19
25
|
}
|
|
26
|
+
function _detectImportedPackages() {
|
|
27
|
+
const data = require("./files-dependency-builder/detect-imported-packages");
|
|
28
|
+
_detectImportedPackages = function () {
|
|
29
|
+
return data;
|
|
30
|
+
};
|
|
31
|
+
return data;
|
|
32
|
+
}
|
|
20
33
|
var _default = exports.default = _dependencies().DependenciesAspect;
|
|
21
34
|
|
|
22
35
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_dependencies","data","require","_default","exports","default","DependenciesAspect"],"sources":["index.ts"],"sourcesContent":["import { DependenciesAspect } from './dependencies.aspect';\n\nexport type { DependenciesMain } from './dependencies.main.runtime';\nexport default DependenciesAspect;\nexport { DependenciesAspect };\n"],"mappings":"
|
|
1
|
+
{"version":3,"names":["_dependencies","data","require","_detectImportedPackages","_default","exports","default","DependenciesAspect"],"sources":["index.ts"],"sourcesContent":["import { DependenciesAspect } from './dependencies.aspect';\n\nexport type { DependenciesMain } from './dependencies.main.runtime';\nexport default DependenciesAspect;\nexport { DependenciesAspect };\nexport { detectImportedPackages } from './files-dependency-builder/detect-imported-packages';\nexport type { ImportedPackages, ImportsCache, FileContent } from './files-dependency-builder/detect-imported-packages';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,SAAAA,cAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,aAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAKA,SAAAE,wBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,uBAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAA6F,IAAAG,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAF9EC,kCAAkB","ignoreList":[]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { DetectorHook } from '@teambit/dependency-resolver';
|
|
3
|
+
import { detectImportedPackages } from './detect-imported-packages';
|
|
4
|
+
|
|
5
|
+
describe('detectImportedPackages', () => {
|
|
6
|
+
const index = {
|
|
7
|
+
relativePath: 'index.ts',
|
|
8
|
+
content: `import a from './a';
|
|
9
|
+
import b from '@scope/b/dist/x';
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import lodash from 'lodash';
|
|
13
|
+
const chalk = require('chalk');`,
|
|
14
|
+
};
|
|
15
|
+
const spec = {
|
|
16
|
+
relativePath: 'index.spec.ts',
|
|
17
|
+
content: `import { expect } from 'chai';\nimport lodash from 'lodash';`,
|
|
18
|
+
};
|
|
19
|
+
const isDevFile = (relativePath: string) => relativePath.endsWith('.spec.ts');
|
|
20
|
+
|
|
21
|
+
it('should return the imported packages, without files and node built-ins', async () => {
|
|
22
|
+
const packages = await detectImportedPackages([index], isDevFile);
|
|
23
|
+
expect(Object.fromEntries(packages!)).to.deep.equal({
|
|
24
|
+
'@scope/b': 'runtime',
|
|
25
|
+
lodash: 'runtime',
|
|
26
|
+
chalk: 'runtime',
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
it('should set a package that only dev files import as dev', async () => {
|
|
30
|
+
const packages = await detectImportedPackages([spec, index], isDevFile);
|
|
31
|
+
expect(packages!.get('chai')).to.equal('dev');
|
|
32
|
+
expect(packages!.get('lodash')).to.equal('runtime');
|
|
33
|
+
});
|
|
34
|
+
it('should find packages imported by style files, not files imported without a relative path', async () => {
|
|
35
|
+
const scss = { relativePath: 'style.scss', content: `@import 'variables';\n@import '~@scope/theme/colors';` };
|
|
36
|
+
const packages = await detectImportedPackages([scss]);
|
|
37
|
+
expect([...packages!.keys()]).to.deep.equal(['@scope/theme']);
|
|
38
|
+
});
|
|
39
|
+
it('should ignore a file of a type without imports', async () => {
|
|
40
|
+
const png = { relativePath: 'logo.png', content: 'not-really-a-png' };
|
|
41
|
+
const packages = await detectImportedPackages([png, index]);
|
|
42
|
+
expect(packages!.size).to.equal(3);
|
|
43
|
+
});
|
|
44
|
+
it('should ignore a file with a @bit-no-check comment', async () => {
|
|
45
|
+
const noCheck = { relativePath: 'no-check.ts', content: `// @bit-no-check\nimport x from 'x';` };
|
|
46
|
+
const packages = await detectImportedPackages([noCheck]);
|
|
47
|
+
expect(packages!.size).to.equal(0);
|
|
48
|
+
});
|
|
49
|
+
it('should return undefined when only an env detector supports a file', async () => {
|
|
50
|
+
const vue = { relativePath: 'comp.vue', content: `<script>import x from 'x';</script>` };
|
|
51
|
+
expect(await detectImportedPackages([vue, index])).to.equal(undefined);
|
|
52
|
+
});
|
|
53
|
+
it('should not share the imports of files with the same content and different names', async () => {
|
|
54
|
+
// e.g. the env.jsonc detector, which supports a file by its name
|
|
55
|
+
DetectorHook.hooks.push({
|
|
56
|
+
isSupported: ({ filename }) => filename.endsWith('env.jsonc'),
|
|
57
|
+
detect: () => ['@scope/base-env'],
|
|
58
|
+
});
|
|
59
|
+
try {
|
|
60
|
+
const content = '{ "extends": "@scope/base-env" }';
|
|
61
|
+
const files = [
|
|
62
|
+
{ relativePath: 'config.jsonc', content },
|
|
63
|
+
{ relativePath: 'env.jsonc', content },
|
|
64
|
+
];
|
|
65
|
+
expect([...(await detectImportedPackages(files))!.keys()]).to.deep.equal(['@scope/base-env']);
|
|
66
|
+
} finally {
|
|
67
|
+
DetectorHook.hooks.pop();
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
it('should return undefined when a file can not be parsed', async () => {
|
|
71
|
+
const broken = { relativePath: 'broken.js', content: `import { from` };
|
|
72
|
+
expect(await detectImportedPackages([broken, index])).to.equal(undefined);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { resolvePackageNameByPath } from '@teambit/legacy.utils';
|
|
3
|
+
import { sha1 } from '@teambit/toolbox.crypto.sha1';
|
|
4
|
+
import precinct from './precinct';
|
|
5
|
+
|
|
6
|
+
export type FileContent = { relativePath: string; content: string };
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* the packages imported by the files of a component. a package that only dev files (e.g. tests) import is "dev".
|
|
10
|
+
*/
|
|
11
|
+
export type ImportedPackages = Map<string, 'runtime' | 'dev'>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* the import specifiers of a file per its path and content hash. files that didn't change between versions are parsed
|
|
15
|
+
* once. (not per content only, a detector may support a file by its name, e.g. env.jsonc). undefined when the file
|
|
16
|
+
* can't be parsed.
|
|
17
|
+
*/
|
|
18
|
+
export type ImportsCache = Map<string, string[] | undefined>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* files of these types have imports, but only an env detector finds them (see DependencyDetector). the env is not
|
|
22
|
+
* loaded here, so the imports of the component are unknown.
|
|
23
|
+
*/
|
|
24
|
+
const EXTENSIONS_OF_ENV_DETECTORS = ['.vue', '.svelte', '.astro'];
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* in files of these types, an import of a package starts with "~". without it, it's an import of a file, even when it's
|
|
28
|
+
* not relative (e.g. `@import 'variables'`), same as a workspace resolves it (see lookupStyling).
|
|
29
|
+
*/
|
|
30
|
+
const EXTENSIONS_OF_STYLE_FILES = ['.scss', '.sass', '.less'];
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* the packages the given files import, found by parsing their content, without resolving the imports. a workspace
|
|
34
|
+
* resolves each import against node_modules (see AutoDetectDeps), a bare scope has the files in memory only.
|
|
35
|
+
* returns undefined when the imports of one of the files are unknown: it can't be parsed, or only an env detector
|
|
36
|
+
* supports its type.
|
|
37
|
+
*/
|
|
38
|
+
export async function detectImportedPackages(
|
|
39
|
+
files: FileContent[],
|
|
40
|
+
isDevFile: (relativePath: string) => boolean = () => false,
|
|
41
|
+
cache: ImportsCache = new Map()
|
|
42
|
+
): Promise<ImportedPackages | undefined> {
|
|
43
|
+
const importedPackages: ImportedPackages = new Map();
|
|
44
|
+
for (const file of files) {
|
|
45
|
+
const specifiers = await getImportSpecifiers(file, cache);
|
|
46
|
+
if (!specifiers) return undefined;
|
|
47
|
+
const type = isDevFile(file.relativePath) ? 'dev' : 'runtime';
|
|
48
|
+
const isStyleFile = EXTENSIONS_OF_STYLE_FILES.includes(path.extname(file.relativePath));
|
|
49
|
+
specifiers.forEach((specifier) => {
|
|
50
|
+
if (isStyleFile && !specifier.startsWith('~')) return;
|
|
51
|
+
const packageName = toPackageName(specifier);
|
|
52
|
+
if (!packageName || importedPackages.get(packageName) === 'runtime') return;
|
|
53
|
+
importedPackages.set(packageName, type);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return importedPackages;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function getImportSpecifiers(file: FileContent, cache: ImportsCache): Promise<string[] | undefined> {
|
|
60
|
+
const ext = path.extname(file.relativePath);
|
|
61
|
+
const key = `${file.relativePath}:${sha1(file.content)}`;
|
|
62
|
+
if (cache.has(key)) return cache.get(key);
|
|
63
|
+
let specifiers: string[] | undefined;
|
|
64
|
+
try {
|
|
65
|
+
specifiers = await precinct.paperworkFromContent(file.relativePath, file.content, { includeCore: false });
|
|
66
|
+
// a file type with no detector has no imports, same as in a workspace whose env has no detector for it
|
|
67
|
+
if (!specifiers && !EXTENSIONS_OF_ENV_DETECTORS.includes(ext)) specifiers = [];
|
|
68
|
+
} catch {
|
|
69
|
+
specifiers = undefined; // a workspace doesn't snap it either, it reports a parsing error
|
|
70
|
+
}
|
|
71
|
+
cache.set(key, specifiers);
|
|
72
|
+
return specifiers;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* e.g. "@scope/pkg/dist/foo" => "@scope/pkg". undefined for an import of a file (relative), which is not a package.
|
|
77
|
+
*/
|
|
78
|
+
function toPackageName(specifier: string): string | undefined {
|
|
79
|
+
if (specifier.startsWith('.') || specifier.startsWith('/') || specifier.startsWith('#')) return undefined;
|
|
80
|
+
if (specifier.includes('!') || /^https?:/.test(specifier)) return undefined; // webpack loaders and urls
|
|
81
|
+
return resolvePackageNameByPath(specifier.replace(/^~/, ''));
|
|
82
|
+
}
|
|
@@ -95,11 +95,10 @@ const assign = (o1, o2) => {
|
|
|
95
95
|
};
|
|
96
96
|
|
|
97
97
|
/**
|
|
98
|
-
* Get file info from the given file path.
|
|
98
|
+
* Get file info from the given file path and its content.
|
|
99
99
|
*/
|
|
100
|
-
const getFileInfo = (filename: string): FileInfo => {
|
|
100
|
+
const getFileInfo = (filename: string, content: string): FileInfo => {
|
|
101
101
|
const ext = path.extname(filename);
|
|
102
|
-
const content = fs.readFileSync(filename, 'utf8');
|
|
103
102
|
return {
|
|
104
103
|
ext,
|
|
105
104
|
content,
|
|
@@ -194,13 +193,17 @@ const normalizeDeps = (deps: BuiltinDeps, includeCore?: boolean): string[] => {
|
|
|
194
193
|
return includeCore ? normalizedDeps : normalizedDeps.filter((d) => !isBuiltin(d));
|
|
195
194
|
};
|
|
196
195
|
|
|
197
|
-
|
|
196
|
+
/**
|
|
197
|
+
* returns undefined when the file type is not supported (no detector for it).
|
|
198
|
+
*/
|
|
199
|
+
const getDepsFromContent = async (
|
|
200
|
+
filename: string,
|
|
201
|
+
content: string,
|
|
202
|
+
options?: Options
|
|
203
|
+
): Promise<string[] | undefined> => {
|
|
198
204
|
const normalizedOptions: Options = assign({ includeCore: true }, options || {});
|
|
199
|
-
const fileInfo = getFileInfo(filename);
|
|
200
|
-
if (
|
|
201
|
-
typeof fileInfo.content === 'string' &&
|
|
202
|
-
(fileInfo.content.startsWith('// @bit-no-check') || fileInfo.content.startsWith('/* @bit-no-check'))
|
|
203
|
-
) {
|
|
205
|
+
const fileInfo = getFileInfo(filename, content);
|
|
206
|
+
if (content.startsWith('// @bit-no-check') || content.startsWith('/* @bit-no-check')) {
|
|
204
207
|
debug(`skipping file ${filename}, it has a @bit-no-check comment`);
|
|
205
208
|
return [];
|
|
206
209
|
}
|
|
@@ -208,7 +211,7 @@ const getDepsFromFile = async (filename: string, options?: Options): Promise<str
|
|
|
208
211
|
const detective = getDetector(fileInfo, normalizedOptions) || getJsDetector(fileInfo, normalizedOptions);
|
|
209
212
|
if (!detective) {
|
|
210
213
|
debug(`skipping unsupported file ${filename}`);
|
|
211
|
-
return
|
|
214
|
+
return undefined;
|
|
212
215
|
}
|
|
213
216
|
debug('module type: ', fileInfo.type);
|
|
214
217
|
|
|
@@ -217,8 +220,17 @@ const getDepsFromFile = async (filename: string, options?: Options): Promise<str
|
|
|
217
220
|
return normalizeDeps(deps, normalizedOptions?.includeCore);
|
|
218
221
|
};
|
|
219
222
|
|
|
223
|
+
const getDepsFromFile = async (filename: string, options?: Options): Promise<string[]> => {
|
|
224
|
+
const content = fs.readFileSync(filename, 'utf8');
|
|
225
|
+
return (await getDepsFromContent(filename, content, options)) || [];
|
|
226
|
+
};
|
|
227
|
+
|
|
220
228
|
const precinct = {
|
|
221
229
|
paperwork: getDepsFromFile,
|
|
230
|
+
/**
|
|
231
|
+
* same as paperwork, for a file that is not on the filesystem (e.g. in a bare scope)
|
|
232
|
+
*/
|
|
233
|
+
paperworkFromContent: getDepsFromContent,
|
|
222
234
|
};
|
|
223
235
|
|
|
224
236
|
export default precinct;
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teambit/dependencies",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1239",
|
|
4
4
|
"homepage": "https://bit.cloud/teambit/dependencies/dependencies",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"componentId": {
|
|
7
7
|
"scope": "teambit.dependencies",
|
|
8
8
|
"name": "dependencies",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.1239"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"archy": "1.0.0",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"@teambit/toolbox.fs.extension-getter": "0.0.22",
|
|
55
55
|
"@teambit/legacy.extension-data": "0.0.188",
|
|
56
56
|
"@teambit/toolbox.fs.last-modified": "0.0.24",
|
|
57
|
+
"@teambit/toolbox.crypto.sha1": "0.0.24",
|
|
57
58
|
"@teambit/styling.deps-lookups.lookup-styling": "0.0.4",
|
|
58
59
|
"@teambit/typescript.deps-lookups.lookup-typescript": "0.0.2",
|
|
59
60
|
"@teambit/mdx.deps-detectors.detective-mdx": "0.0.7",
|
|
@@ -63,10 +64,10 @@
|
|
|
63
64
|
"@teambit/styling.deps-detectors.detective-sass": "0.0.9",
|
|
64
65
|
"@teambit/styling.deps-detectors.detective-scss": "0.0.9",
|
|
65
66
|
"@teambit/typescript.deps-detectors.detective-typescript": "0.0.10",
|
|
66
|
-
"@teambit/graph": "1.0.
|
|
67
|
-
"@teambit/workspace": "1.0.
|
|
68
|
-
"@teambit/dev-files": "1.0.
|
|
69
|
-
"@teambit/scope": "1.0.
|
|
67
|
+
"@teambit/graph": "1.0.1238",
|
|
68
|
+
"@teambit/workspace": "1.0.1238",
|
|
69
|
+
"@teambit/dev-files": "1.0.1238",
|
|
70
|
+
"@teambit/scope": "1.0.1238"
|
|
70
71
|
},
|
|
71
72
|
"devDependencies": {
|
|
72
73
|
"@types/cli-table": "^0.3.0",
|
|
File without changes
|