@sdk-usage/core 0.0.0-next-a13a5b4 → 0.0.0-next-193dba9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdk-usage/core",
3
- "version": "0.0.0-next-a13a5b4",
3
+ "version": "0.0.0-next-193dba9",
4
4
  "description": "sdk-usage core functionalities",
5
5
  "keywords": [
6
6
  "analyze",
@@ -41,13 +41,13 @@
41
41
  ],
42
42
  "dependencies": {
43
43
  "@open-vanilla/visitor": "^1.0.0",
44
- "@swc/core": "^1.13.5",
44
+ "@swc/core": "^1.15.33",
45
45
  "fdir": "^6.5.0",
46
- "picomatch": "^4.0.3"
46
+ "picomatch": "^4.0.4"
47
47
  },
48
48
  "devDependencies": {
49
- "@types/node": "22.18.12",
50
- "quickbundle": "2.8.0"
49
+ "@types/node": "24.12.4",
50
+ "quickbundle": "3.0.0"
51
51
  },
52
52
  "publishConfig": {
53
53
  "access": "public",
package/dist/index.cjs DELETED
@@ -1,286 +0,0 @@
1
- 'use strict';
2
-
3
- var node_fs = require('node:fs');
4
- var node_path = require('node:path');
5
- var fdir = require('fdir');
6
- var node_module = require('node:module');
7
- var node_child_process = require('node:child_process');
8
- var core = require('@swc/core');
9
- var visitor = require('@open-vanilla/visitor');
10
-
11
- var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
12
- const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
13
- const resolvePackageJson = (fromPath)=>{
14
- const filepath = node_path.join(fromPath, "./package.json");
15
- if (node_fs.existsSync(filepath)) {
16
- return filepath;
17
- }
18
- return resolvePackageJson(node_path.join(fromPath, "../"));
19
- };
20
- /**
21
- * Execute an external command.
22
- * @param command - The command to execute.
23
- * @param options - Options including current working directory configuration.
24
- * @param options.cwd - Configure the current working directory.
25
- * @returns The output (either the command output or error).
26
- * @example
27
- * exec("ls");
28
- */ const exec = async (command, options = {})=>{
29
- return new Promise((resolve, reject)=>{
30
- let stdout = "";
31
- let stderr = "";
32
- const [bin, ...arguments_] = command.split(" ");
33
- // eslint-disable-next-line sonarjs/os-command
34
- const childProcess = node_child_process.spawn(bin, arguments_, {
35
- cwd: options.cwd,
36
- shell: true,
37
- stdio: "pipe"
38
- });
39
- childProcess.stdout.on("data", (chunk)=>{
40
- stdout += chunk;
41
- });
42
- childProcess.stderr.on("data", (chunk)=>{
43
- stderr += chunk;
44
- });
45
- childProcess.on("close", (exitCode)=>{
46
- if (exitCode !== 0) {
47
- const output = `${stderr}${stdout}`;
48
- reject(new Error(output.trim()));
49
- } else {
50
- resolve(stdout.trim());
51
- }
52
- });
53
- });
54
- };
55
-
56
- const scan = async (path, options = {})=>{
57
- const excludedFolders = options.excludeFolders ?? DEFAULT_EXCLUDED_FOLDERS;
58
- const includedFiles = options.includeFiles ?? DEFAULT_INCLUDED_FILES;
59
- const projectPaths = new fdir.fdir().withBasePath().glob("**/package.json").exclude((directoryName)=>excludedFolders.includes(directoryName)).crawl(path).sync();
60
- const projects = [];
61
- for (const projectPath of projectPaths){
62
- const metadata = require$1(projectPath);
63
- const folder = node_path.dirname(projectPath);
64
- let link;
65
- try {
66
- link = await exec("git config --get remote.origin.url", {
67
- cwd: folder
68
- });
69
- } catch {
70
- link = "";
71
- }
72
- projects.push({
73
- folder,
74
- link,
75
- metadata
76
- });
77
- }
78
- return projects.map((project)=>{
79
- const files = new fdir.fdir().withBasePath().glob(...includedFiles).exclude((directoryName)=>excludedFolders.includes(directoryName)).crawl(project.folder).sync();
80
- return {
81
- ...project,
82
- files
83
- };
84
- });
85
- };
86
- const DEFAULT_EXCLUDED_FOLDERS = [
87
- ".git",
88
- "node_modules",
89
- "dist",
90
- "out"
91
- ];
92
- const DEFAULT_INCLUDED_FILES = [
93
- "**/*/!(test|*.test|stories|*.stories).?(m){j,t}s?(x)"
94
- ];
95
-
96
- const parse = async (code, { onAdd, plugins })=>{
97
- const context = {
98
- imports: new Map()
99
- };
100
- let ast;
101
- try {
102
- ast = await core.parse(code, {
103
- syntax: "typescript",
104
- tsx: true
105
- });
106
- } catch {
107
- ast = undefined;
108
- // TODO: log error with file path
109
- }
110
- if (ast === undefined) return;
111
- const visitor$1 = {
112
- ImportDeclaration (node) {
113
- const module = node.source.value;
114
- node.specifiers.forEach((specifier)=>{
115
- const specifierValue = specifier.local.value;
116
- context.imports.set(specifierValue, {
117
- name: // @ts-expect-error `imported` field is not exposed by `ImportSpecifier` node (issue in `@swc/core` type definition).
118
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
119
- specifier.imported?.value ?? specifierValue,
120
- alias: specifierValue,
121
- module
122
- });
123
- });
124
- }
125
- };
126
- for (const plugin of plugins){
127
- const pluginOutput = plugin(context, {
128
- getJSXAttributeValue
129
- });
130
- const nodeKeys = Object.keys(pluginOutput);
131
- for (const nodeKey of nodeKeys){
132
- const currentVisitorFunction = visitor$1[nodeKey];
133
- visitor$1[nodeKey] = (node)=>{
134
- if (typeof currentVisitorFunction === "function") {
135
- currentVisitorFunction(node);
136
- }
137
- const output = pluginOutput[nodeKey]?.(node);
138
- if (output) {
139
- onAdd(output);
140
- }
141
- };
142
- }
143
- }
144
- visitor.visit(ast, visitor$1);
145
- };
146
- const getJSXAttributeValue = (node)=>{
147
- if (!node) {
148
- return true;
149
- }
150
- switch(node.type){
151
- case "NullLiteral":
152
- {
153
- return null;
154
- }
155
- case "StringLiteral":
156
- case "NumericLiteral":
157
- case "BigIntLiteral":
158
- case "BooleanLiteral":
159
- case "JSXText":
160
- {
161
- return node.value;
162
- }
163
- case "JSXExpressionContainer":
164
- {
165
- return getJSXAttributeValue(node.expression);
166
- }
167
- case "JSXElement":
168
- case "JSXFragment":
169
- case "RegExpLiteral":
170
- default:
171
- {
172
- return createUnknownToken(node.type);
173
- }
174
- }
175
- };
176
- /**
177
- * Helper to unify the way unknown AST token are managed.
178
- * @param token - AST token value.
179
- * @returns Formatted AST token.
180
- * @example
181
- * createUnknownToken("VariableDeclaration");
182
- */ const createUnknownToken = (token)=>`#${token}`;
183
-
184
- const createLocation = ({ code, file, link, module, offset, path })=>{
185
- const linesTillOffset = code.slice(0, Math.max(0, offset)).split(/\n/);
186
- const line = linesTillOffset.length;
187
- const column = linesTillOffset[line - 1].length;
188
- return {
189
- column,
190
- file: `./${node_path.relative(path, file)}`,
191
- line,
192
- link,
193
- module
194
- };
195
- };
196
-
197
- /**
198
- * Aggregate factory that creates an item.
199
- * @param input - Factory variables.
200
- * @param input.name - Name.
201
- * @param input.type - Component type.
202
- * @param input.module - Source module.
203
- * @param input.version - Module version.
204
- * @param input.location - Location.
205
- * @param input.input - Parameter list and metadata describing the way it's passed.
206
- * @returns Created item.
207
- * @example
208
- * createItem({ ... });
209
- */ const createItem = ({ name, input, location, module, type, version })=>{
210
- const item = {
211
- name,
212
- type,
213
- module,
214
- version,
215
- createdAt: new Date().toISOString(),
216
- location: createLocation(location),
217
- input: {
218
- metadata: {
219
- withSpreading: input?.metadata.withSpreading ?? false
220
- },
221
- data: input?.data ?? {}
222
- }
223
- };
224
- return item;
225
- };
226
-
227
- const createInstance = (path, options)=>{
228
- return {
229
- async getItems () {
230
- const projects = await scan(path);
231
- const items = [];
232
- for (const project of projects){
233
- const module = project.metadata.name;
234
- const dependencies = {
235
- ...project.metadata.devDependencies,
236
- ...project.metadata.optionalDependencies,
237
- ...project.metadata.dependencies
238
- };
239
- const link = project.link;
240
- for (const file of project.files){
241
- const code = node_fs.readFileSync(file, "utf8");
242
- await parse(code, {
243
- onAdd (item) {
244
- if (options.includeModules && options.includeModules.length > 0 && !options.includeModules.includes(item.module)) {
245
- return;
246
- }
247
- let version = dependencies[item.module] ?? "";
248
- if (options.resolveInstalledVersions) {
249
- try {
250
- version = require$1(resolvePackageJson(require$1.resolve(item.module, {
251
- paths: [
252
- file
253
- ]
254
- }))).version;
255
- } catch {
256
- // @TODO: No operation (later warnings can be added).
257
- }
258
- }
259
- items.push(createItem({
260
- ...item,
261
- location: {
262
- code,
263
- file,
264
- link,
265
- module,
266
- offset: item.offset,
267
- path
268
- },
269
- version
270
- }));
271
- },
272
- plugins: options.plugins ?? []
273
- });
274
- }
275
- }
276
- return items;
277
- }
278
- };
279
- };
280
-
281
- const createPlugin = (input)=>{
282
- return input;
283
- };
284
-
285
- exports.createInstance = createInstance;
286
- exports.createPlugin = createPlugin;
package/dist/index.d.ts DELETED
@@ -1,96 +0,0 @@
1
- import { ImportDeclaration, JSXAttrValue, JSXOpeningElement, TsType } from '@swc/core';
2
-
3
- type Primitive = bigint | boolean | number | string | null | undefined;
4
- type Nodes = {
5
- ImportDeclaration: ImportDeclaration;
6
- JSXAttrValue: JSXAttrValue;
7
- JSXOpeningElement: JSXOpeningElement;
8
- TsType: TsType;
9
- };
10
- /**
11
- * Import entity to model an import statement.
12
- */
13
- type Import = {
14
- name: string;
15
- alias: string;
16
- module: string;
17
- };
18
- /**
19
- * Package entity to model `package.json` metadata.
20
- */
21
- type Package = {
22
- name: string;
23
- description: string;
24
- dependencies?: Record<string, string>;
25
- devDependencies?: Record<string, string>;
26
- optionalDependencies?: Record<string, string>;
27
- peerDependencies?: Record<string, string>;
28
- version: string;
29
- };
30
-
31
- type ScanOptions = {
32
- /**
33
- * A list of folders to ignore.
34
- */
35
- excludeFolders?: string[];
36
- /**
37
- * A list of files to include (following glob matcher).
38
- */
39
- includeFiles?: string[];
40
- };
41
-
42
- type Location = {
43
- column: number;
44
- file: string;
45
- line: number;
46
- link: string;
47
- module: string;
48
- };
49
-
50
- type Item = {
51
- name: string;
52
- createdAt: string;
53
- input: {
54
- data: Record<string, unknown>;
55
- metadata: {
56
- withSpreading: boolean;
57
- };
58
- };
59
- location: Location;
60
- module: Package["name"];
61
- type: string;
62
- version: Package["version"];
63
- };
64
- type ItemDTO = Partial<Pick<Item, "input">> & Pick<Item, "module" | "name" | "type"> & {
65
- offset: number;
66
- };
67
-
68
- declare const createPlugin: (input: Plugin) => Plugin;
69
- type Plugin = (context: {
70
- imports: Map<Import["alias"], Import>;
71
- }, helpers: {
72
- getJSXAttributeValue: (node: Nodes["JSXAttrValue"] | undefined) => Primitive;
73
- }) => {
74
- [Key in keyof Nodes]?: (node: Nodes[Key]) => ItemDTO | undefined;
75
- };
76
-
77
- type Options = Partial<Pick<ScanOptions, "excludeFolders" | "includeFiles"> & {
78
- /**
79
- * Only analyze components imported from the specificied module list.
80
- */
81
- includeModules: string[];
82
- /**
83
- * A list of plugins to enable.
84
- */
85
- plugins: Plugin[];
86
- /**
87
- * Attempt to resolve installed versions of modules. If false or not possible, the specified version from the package.json will be used.
88
- * @default false
89
- */
90
- resolveInstalledVersions: boolean;
91
- }>;
92
- declare const createInstance: (path: string, options: Options) => {
93
- getItems(): Promise<Item[]>;
94
- };
95
-
96
- export { createInstance, createPlugin };
package/dist/index.mjs DELETED
@@ -1,282 +0,0 @@
1
- import { existsSync, readFileSync } from 'node:fs';
2
- import { join, dirname, relative } from 'node:path';
3
- import { fdir } from 'fdir';
4
- import { createRequire } from 'node:module';
5
- import { spawn } from 'node:child_process';
6
- import { parse as parse$1 } from '@swc/core';
7
- import { visit } from '@open-vanilla/visitor';
8
-
9
- const require = createRequire(import.meta.url);
10
- const resolvePackageJson = (fromPath)=>{
11
- const filepath = join(fromPath, "./package.json");
12
- if (existsSync(filepath)) {
13
- return filepath;
14
- }
15
- return resolvePackageJson(join(fromPath, "../"));
16
- };
17
- /**
18
- * Execute an external command.
19
- * @param command - The command to execute.
20
- * @param options - Options including current working directory configuration.
21
- * @param options.cwd - Configure the current working directory.
22
- * @returns The output (either the command output or error).
23
- * @example
24
- * exec("ls");
25
- */ const exec = async (command, options = {})=>{
26
- return new Promise((resolve, reject)=>{
27
- let stdout = "";
28
- let stderr = "";
29
- const [bin, ...arguments_] = command.split(" ");
30
- // eslint-disable-next-line sonarjs/os-command
31
- const childProcess = spawn(bin, arguments_, {
32
- cwd: options.cwd,
33
- shell: true,
34
- stdio: "pipe"
35
- });
36
- childProcess.stdout.on("data", (chunk)=>{
37
- stdout += chunk;
38
- });
39
- childProcess.stderr.on("data", (chunk)=>{
40
- stderr += chunk;
41
- });
42
- childProcess.on("close", (exitCode)=>{
43
- if (exitCode !== 0) {
44
- const output = `${stderr}${stdout}`;
45
- reject(new Error(output.trim()));
46
- } else {
47
- resolve(stdout.trim());
48
- }
49
- });
50
- });
51
- };
52
-
53
- const scan = async (path, options = {})=>{
54
- const excludedFolders = options.excludeFolders ?? DEFAULT_EXCLUDED_FOLDERS;
55
- const includedFiles = options.includeFiles ?? DEFAULT_INCLUDED_FILES;
56
- const projectPaths = new fdir().withBasePath().glob("**/package.json").exclude((directoryName)=>excludedFolders.includes(directoryName)).crawl(path).sync();
57
- const projects = [];
58
- for (const projectPath of projectPaths){
59
- const metadata = require(projectPath);
60
- const folder = dirname(projectPath);
61
- let link;
62
- try {
63
- link = await exec("git config --get remote.origin.url", {
64
- cwd: folder
65
- });
66
- } catch {
67
- link = "";
68
- }
69
- projects.push({
70
- folder,
71
- link,
72
- metadata
73
- });
74
- }
75
- return projects.map((project)=>{
76
- const files = new fdir().withBasePath().glob(...includedFiles).exclude((directoryName)=>excludedFolders.includes(directoryName)).crawl(project.folder).sync();
77
- return {
78
- ...project,
79
- files
80
- };
81
- });
82
- };
83
- const DEFAULT_EXCLUDED_FOLDERS = [
84
- ".git",
85
- "node_modules",
86
- "dist",
87
- "out"
88
- ];
89
- const DEFAULT_INCLUDED_FILES = [
90
- "**/*/!(test|*.test|stories|*.stories).?(m){j,t}s?(x)"
91
- ];
92
-
93
- const parse = async (code, { onAdd, plugins })=>{
94
- const context = {
95
- imports: new Map()
96
- };
97
- let ast;
98
- try {
99
- ast = await parse$1(code, {
100
- syntax: "typescript",
101
- tsx: true
102
- });
103
- } catch {
104
- ast = undefined;
105
- // TODO: log error with file path
106
- }
107
- if (ast === undefined) return;
108
- const visitor = {
109
- ImportDeclaration (node) {
110
- const module = node.source.value;
111
- node.specifiers.forEach((specifier)=>{
112
- const specifierValue = specifier.local.value;
113
- context.imports.set(specifierValue, {
114
- name: // @ts-expect-error `imported` field is not exposed by `ImportSpecifier` node (issue in `@swc/core` type definition).
115
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
116
- specifier.imported?.value ?? specifierValue,
117
- alias: specifierValue,
118
- module
119
- });
120
- });
121
- }
122
- };
123
- for (const plugin of plugins){
124
- const pluginOutput = plugin(context, {
125
- getJSXAttributeValue
126
- });
127
- const nodeKeys = Object.keys(pluginOutput);
128
- for (const nodeKey of nodeKeys){
129
- const currentVisitorFunction = visitor[nodeKey];
130
- visitor[nodeKey] = (node)=>{
131
- if (typeof currentVisitorFunction === "function") {
132
- currentVisitorFunction(node);
133
- }
134
- const output = pluginOutput[nodeKey]?.(node);
135
- if (output) {
136
- onAdd(output);
137
- }
138
- };
139
- }
140
- }
141
- visit(ast, visitor);
142
- };
143
- const getJSXAttributeValue = (node)=>{
144
- if (!node) {
145
- return true;
146
- }
147
- switch(node.type){
148
- case "NullLiteral":
149
- {
150
- return null;
151
- }
152
- case "StringLiteral":
153
- case "NumericLiteral":
154
- case "BigIntLiteral":
155
- case "BooleanLiteral":
156
- case "JSXText":
157
- {
158
- return node.value;
159
- }
160
- case "JSXExpressionContainer":
161
- {
162
- return getJSXAttributeValue(node.expression);
163
- }
164
- case "JSXElement":
165
- case "JSXFragment":
166
- case "RegExpLiteral":
167
- default:
168
- {
169
- return createUnknownToken(node.type);
170
- }
171
- }
172
- };
173
- /**
174
- * Helper to unify the way unknown AST token are managed.
175
- * @param token - AST token value.
176
- * @returns Formatted AST token.
177
- * @example
178
- * createUnknownToken("VariableDeclaration");
179
- */ const createUnknownToken = (token)=>`#${token}`;
180
-
181
- const createLocation = ({ code, file, link, module, offset, path })=>{
182
- const linesTillOffset = code.slice(0, Math.max(0, offset)).split(/\n/);
183
- const line = linesTillOffset.length;
184
- const column = linesTillOffset[line - 1].length;
185
- return {
186
- column,
187
- file: `./${relative(path, file)}`,
188
- line,
189
- link,
190
- module
191
- };
192
- };
193
-
194
- /**
195
- * Aggregate factory that creates an item.
196
- * @param input - Factory variables.
197
- * @param input.name - Name.
198
- * @param input.type - Component type.
199
- * @param input.module - Source module.
200
- * @param input.version - Module version.
201
- * @param input.location - Location.
202
- * @param input.input - Parameter list and metadata describing the way it's passed.
203
- * @returns Created item.
204
- * @example
205
- * createItem({ ... });
206
- */ const createItem = ({ name, input, location, module, type, version })=>{
207
- const item = {
208
- name,
209
- type,
210
- module,
211
- version,
212
- createdAt: new Date().toISOString(),
213
- location: createLocation(location),
214
- input: {
215
- metadata: {
216
- withSpreading: input?.metadata.withSpreading ?? false
217
- },
218
- data: input?.data ?? {}
219
- }
220
- };
221
- return item;
222
- };
223
-
224
- const createInstance = (path, options)=>{
225
- return {
226
- async getItems () {
227
- const projects = await scan(path);
228
- const items = [];
229
- for (const project of projects){
230
- const module = project.metadata.name;
231
- const dependencies = {
232
- ...project.metadata.devDependencies,
233
- ...project.metadata.optionalDependencies,
234
- ...project.metadata.dependencies
235
- };
236
- const link = project.link;
237
- for (const file of project.files){
238
- const code = readFileSync(file, "utf8");
239
- await parse(code, {
240
- onAdd (item) {
241
- if (options.includeModules && options.includeModules.length > 0 && !options.includeModules.includes(item.module)) {
242
- return;
243
- }
244
- let version = dependencies[item.module] ?? "";
245
- if (options.resolveInstalledVersions) {
246
- try {
247
- version = require(resolvePackageJson(require.resolve(item.module, {
248
- paths: [
249
- file
250
- ]
251
- }))).version;
252
- } catch {
253
- // @TODO: No operation (later warnings can be added).
254
- }
255
- }
256
- items.push(createItem({
257
- ...item,
258
- location: {
259
- code,
260
- file,
261
- link,
262
- module,
263
- offset: item.offset,
264
- path
265
- },
266
- version
267
- }));
268
- },
269
- plugins: options.plugins ?? []
270
- });
271
- }
272
- }
273
- return items;
274
- }
275
- };
276
- };
277
-
278
- const createPlugin = (input)=>{
279
- return input;
280
- };
281
-
282
- export { createInstance, createPlugin };