smartbundle 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__do_not_import_directly__/args.mjs +18 -0
- package/__do_not_import_directly__/errors.mjs +17 -0
- package/__do_not_import_directly__/index.mjs +161 -0
- package/__do_not_import_directly__/packageJson.mjs +41 -0
- package/__do_not_import_directly__/writePackageJson.mjs +36 -0
- package/package.json +14 -0
- package/src/args.d.ts +9 -0
- package/src/bin.d.ts +1 -0
- package/src/bin.mjs +3 -0
- package/src/build.test.d.ts +1 -0
- package/src/errors.d.ts +14 -0
- package/src/fixtures/deep-structure/level1/dep1.d.ts +1 -0
- package/src/fixtures/deep-structure/level1/level2/entrypoint1.d.ts +1 -0
- package/src/fixtures/simple-bin-build/bin.d.ts +1 -0
- package/src/fixtures/ts-import/a.d.ts +1 -0
- package/src/fixtures/ts-import/entrypoint.d.ts +2 -0
- package/src/index.d.ts +13 -0
- package/src/packageJson.d.ts +35 -0
- package/src/packageJson.test.d.ts +1 -0
- package/src/writePackageJson.d.ts +10 -0
- package/types.d.ts +1 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
import yargs from "yargs";
|
2
|
+
import * as process from "node:process";
|
3
|
+
const args = yargs(process.argv.slice(2)).option("sourceDir", {
|
4
|
+
alias: "s",
|
5
|
+
type: "string",
|
6
|
+
describe: "path to the project directory. Default: current working directory"
|
7
|
+
}).option("packagePath", {
|
8
|
+
alias: "p",
|
9
|
+
type: "string",
|
10
|
+
describe: "path to the package.json. Default: cwd()/package.json"
|
11
|
+
}).option("outputDir", {
|
12
|
+
alias: "o",
|
13
|
+
type: "string",
|
14
|
+
describe: "path to the output directory. Default: cwd()/dist"
|
15
|
+
}).help("help").parseSync();
|
16
|
+
export {
|
17
|
+
args
|
18
|
+
};
|
@@ -0,0 +1,17 @@
|
|
1
|
+
const errors = {
|
2
|
+
exportsRequired: "The `exports` field is string. Please, verify the value. More info: https://nodejs.org/api/packages.html#package-entry-points",
|
3
|
+
exportsInvalid: "The `exports` field must be a path to entrypoint. Please, verify the value. More info: https://nodejs.org/api/packages.html#package-entry-points",
|
4
|
+
nameRequired: "The `name` field is required string. Please, verify the value. More info: https://docs.npmjs.com/cli/v10/configuring-npm/package-json#name",
|
5
|
+
nameMinLength: 'Min length of "name" is 1 character. More info: https://docs.npmjs.com/cli/v10/configuring-npm/package-json#name',
|
6
|
+
nameMaxLength: 'Max length of "name" is 214 characters. More info: https://docs.npmjs.com/cli/v10/configuring-npm/package-json#name',
|
7
|
+
nameStartsIllegalChars: "Name cannot start with `_` or `.` if it is not a scoped package. More info: https://docs.npmjs.com/cli/v10/configuring-npm/package-json#name",
|
8
|
+
versionRequired: "The `version` field is required string. Please, verify the value. More info: https://docs.npmjs.com/cli/v10/configuring-npm/package-json#version",
|
9
|
+
privateIsTrue: "The `private` field must be `true` for avoiding accidental publish. More info: https://docs.npmjs.com/cli/v10/configuring-npm/package-json#private",
|
10
|
+
descriptionString: "The `description` field must be a string. Please, verify the value. More info: https://docs.npmjs.com/cli/v10/configuring-npm/package-json#description",
|
11
|
+
dependenciesInvalid: "The `dependencies` field must be an Object<string, string>. Please, verify the value. More info: https://docs.npmjs.com/cli/v10/configuring-npm/package-json#dependencies",
|
12
|
+
binString: "The `bin` field must be a string. Please, verify the value. More info: https://docs.npmjs.com/cli/v10/configuring-npm/package-json#bin",
|
13
|
+
rollupError: "An error occurred while building the package. Please, report it to the issues on GitHub"
|
14
|
+
};
|
15
|
+
export {
|
16
|
+
errors
|
17
|
+
};
|
@@ -0,0 +1,161 @@
|
|
1
|
+
import { join, relative, isAbsolute } from "node:path";
|
2
|
+
import { rm, mkdir } from "node:fs/promises";
|
3
|
+
import { parsePackageJson } from "./packageJson.mjs";
|
4
|
+
import { build } from "vite";
|
5
|
+
import { writePackageJson } from "./writePackageJson.mjs";
|
6
|
+
import rollupts from "@rollup/plugin-typescript";
|
7
|
+
import { errors } from "./errors.mjs";
|
8
|
+
function myResolve(path1, path2) {
|
9
|
+
if (isAbsolute(path2)) {
|
10
|
+
return path2;
|
11
|
+
}
|
12
|
+
return join(path1, path2);
|
13
|
+
}
|
14
|
+
function mapToObject(map) {
|
15
|
+
const obj = {};
|
16
|
+
for (const [key, value] of map) {
|
17
|
+
obj[key] = value;
|
18
|
+
}
|
19
|
+
return obj;
|
20
|
+
}
|
21
|
+
function reverseMap(map) {
|
22
|
+
const reversed = /* @__PURE__ */ new Map();
|
23
|
+
for (const [key, value] of map) {
|
24
|
+
const noExtValue = value.replace(/\.[^.]+$/, "");
|
25
|
+
const arr = reversed.get(noExtValue) ?? [];
|
26
|
+
arr.push(key);
|
27
|
+
reversed.set(noExtValue, arr);
|
28
|
+
}
|
29
|
+
return reversed;
|
30
|
+
}
|
31
|
+
function setExports(exportsMap, exportName, mapFn) {
|
32
|
+
const entry = exportsMap.get(exportName) ?? {};
|
33
|
+
exportsMap.set(exportName, mapFn(entry));
|
34
|
+
}
|
35
|
+
async function run(args) {
|
36
|
+
var _a;
|
37
|
+
const sourceDir = myResolve(process.cwd(), args.sourceDir ?? ".");
|
38
|
+
const packagePath = myResolve(sourceDir, args.packagePath ?? "./package.json");
|
39
|
+
const outDir = myResolve(process.cwd(), args.outputDir ?? "./dist");
|
40
|
+
await rm(outDir, { recursive: true, force: true });
|
41
|
+
await mkdir(outDir, { recursive: true });
|
42
|
+
const packageJson = await parsePackageJson({ sourceDir, packagePath });
|
43
|
+
if (Array.isArray(packageJson)) {
|
44
|
+
console.log(packageJson);
|
45
|
+
return { error: true, errors: packageJson };
|
46
|
+
}
|
47
|
+
const entrypoints = /* @__PURE__ */ new Map();
|
48
|
+
if (packageJson.exports) {
|
49
|
+
const mainEntry = join(sourceDir, packageJson.exports);
|
50
|
+
entrypoints.set(".", mainEntry);
|
51
|
+
}
|
52
|
+
if (packageJson.bin) {
|
53
|
+
const binEntry = join(sourceDir, packageJson.bin);
|
54
|
+
entrypoints.set("__bin__", binEntry);
|
55
|
+
}
|
56
|
+
const hasTs = [...entrypoints.values()].some((entry) => entry.endsWith(".ts"));
|
57
|
+
const typescript = hasTs ? (
|
58
|
+
// @ts-expect-error
|
59
|
+
rollupts({
|
60
|
+
compilerOptions: {
|
61
|
+
declaration: true,
|
62
|
+
declarationDir: outDir
|
63
|
+
}
|
64
|
+
})
|
65
|
+
) : false;
|
66
|
+
const outputs = await build({
|
67
|
+
publicDir: false,
|
68
|
+
build: {
|
69
|
+
outDir,
|
70
|
+
write: true,
|
71
|
+
minify: false,
|
72
|
+
emptyOutDir: true,
|
73
|
+
assetsInlineLimit: 0,
|
74
|
+
terserOptions: {
|
75
|
+
compress: false,
|
76
|
+
mangle: false
|
77
|
+
},
|
78
|
+
lib: {
|
79
|
+
entry: mapToObject(entrypoints),
|
80
|
+
formats: ["es"],
|
81
|
+
fileName: (format, entryName) => {
|
82
|
+
const entrypoint = entrypoints.get(entryName);
|
83
|
+
if (!entrypoint) {
|
84
|
+
const noExt2 = entryName.replace(/\.[^.]+$/, "");
|
85
|
+
return "__do_not_import_directly__/" + noExt2 + ".mjs";
|
86
|
+
}
|
87
|
+
const relativePath = relative(sourceDir, entrypoint);
|
88
|
+
const noExt = relativePath.replace(/\.[^.]+$/, "");
|
89
|
+
if (format === "es") {
|
90
|
+
return `${noExt}.mjs`;
|
91
|
+
}
|
92
|
+
return noExt;
|
93
|
+
}
|
94
|
+
},
|
95
|
+
rollupOptions: {
|
96
|
+
plugins: [typescript],
|
97
|
+
external: (id, parentId, isResolved) => {
|
98
|
+
if (id.startsWith("node:")) {
|
99
|
+
return true;
|
100
|
+
}
|
101
|
+
if (packageJson.dependencies) {
|
102
|
+
return id in packageJson.dependencies;
|
103
|
+
}
|
104
|
+
return false;
|
105
|
+
},
|
106
|
+
output: {
|
107
|
+
preserveModules: true
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
});
|
112
|
+
if (!Array.isArray(outputs)) {
|
113
|
+
return { error: true, errors: [errors.rollupError] };
|
114
|
+
}
|
115
|
+
const exportsMap = /* @__PURE__ */ new Map();
|
116
|
+
const reversedEntrypoints = reverseMap(entrypoints);
|
117
|
+
for (const { output } of outputs) {
|
118
|
+
for (const el of output) {
|
119
|
+
switch (el.type) {
|
120
|
+
case "chunk":
|
121
|
+
const noExtPath = (_a = el.facadeModuleId) == null ? void 0 : _a.replace(/\.[^.]+$/, "");
|
122
|
+
if (noExtPath == null) {
|
123
|
+
continue;
|
124
|
+
}
|
125
|
+
const exportPath = reversedEntrypoints.get(noExtPath);
|
126
|
+
if (!exportPath) {
|
127
|
+
continue;
|
128
|
+
}
|
129
|
+
for (const path of exportPath) {
|
130
|
+
setExports(exportsMap, path, (entry) => {
|
131
|
+
entry.mjs = "./" + el.fileName;
|
132
|
+
return entry;
|
133
|
+
});
|
134
|
+
}
|
135
|
+
break;
|
136
|
+
case "asset":
|
137
|
+
if (el.fileName.endsWith(".d.ts")) {
|
138
|
+
const noExtPath2 = join(sourceDir, el.fileName.replace(/\.d\.ts$/, ""));
|
139
|
+
const exportPath2 = reversedEntrypoints.get(noExtPath2);
|
140
|
+
if (!exportPath2) {
|
141
|
+
continue;
|
142
|
+
}
|
143
|
+
for (const path of exportPath2) {
|
144
|
+
setExports(exportsMap, path, (entry) => {
|
145
|
+
entry.mdts = "./" + el.fileName;
|
146
|
+
return entry;
|
147
|
+
});
|
148
|
+
}
|
149
|
+
}
|
150
|
+
break;
|
151
|
+
}
|
152
|
+
}
|
153
|
+
}
|
154
|
+
await writePackageJson(outDir, packageJson, {
|
155
|
+
exportsMap
|
156
|
+
});
|
157
|
+
return { error: false };
|
158
|
+
}
|
159
|
+
export {
|
160
|
+
run
|
161
|
+
};
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import * as fs from "node:fs/promises";
|
2
|
+
import z from "zod";
|
3
|
+
import { errors } from "./errors.mjs";
|
4
|
+
import { join } from "node:path";
|
5
|
+
async function fileExists(filePath) {
|
6
|
+
try {
|
7
|
+
const stats = await fs.stat(filePath);
|
8
|
+
return stats.isFile();
|
9
|
+
} catch (error) {
|
10
|
+
return false;
|
11
|
+
}
|
12
|
+
}
|
13
|
+
function dependencies(errorText) {
|
14
|
+
return z.record(z.string({ message: errorText }), { message: errorText }).optional();
|
15
|
+
}
|
16
|
+
function createPackageJsonSchema(sourceDir) {
|
17
|
+
return z.object({
|
18
|
+
exports: z.string({ message: errors.exportsRequired }).refine((exports) => {
|
19
|
+
const mainFinalPath = join(sourceDir, exports);
|
20
|
+
return fileExists(mainFinalPath);
|
21
|
+
}, errors.exportsInvalid).optional(),
|
22
|
+
name: z.string({ message: errors.nameRequired }).min(1, errors.nameMinLength).max(214, errors.nameMaxLength).refine((name) => ["_", "."].every((start) => !name.startsWith(start)), errors.nameStartsIllegalChars),
|
23
|
+
version: z.string({ message: errors.versionRequired }),
|
24
|
+
private: z.boolean({ message: errors.privateIsTrue }).refine((value) => value, errors.privateIsTrue),
|
25
|
+
description: z.string({ message: errors.descriptionString }).optional(),
|
26
|
+
dependencies: dependencies(errors.dependenciesInvalid),
|
27
|
+
bin: z.string({ message: errors.binString }).optional()
|
28
|
+
});
|
29
|
+
}
|
30
|
+
async function parsePackageJson({ sourceDir, packagePath }) {
|
31
|
+
const rawJson = (await import(packagePath)).default;
|
32
|
+
const packageJsonSchema = createPackageJsonSchema(sourceDir);
|
33
|
+
const packageJson = await packageJsonSchema.safeParseAsync(rawJson);
|
34
|
+
if (!packageJson.success) {
|
35
|
+
return packageJson.error.errors.map((error) => error.message);
|
36
|
+
}
|
37
|
+
return packageJson.data;
|
38
|
+
}
|
39
|
+
export {
|
40
|
+
parsePackageJson
|
41
|
+
};
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { writeFile } from "node:fs/promises";
|
2
|
+
async function writePackageJson(outDir, parsed, { exportsMap }) {
|
3
|
+
var _a, _b, _c;
|
4
|
+
const allExports = {};
|
5
|
+
for (const [key, value] of exportsMap) {
|
6
|
+
if (key === "__bin__") {
|
7
|
+
continue;
|
8
|
+
}
|
9
|
+
const anExport = {
|
10
|
+
types: value.mdts
|
11
|
+
};
|
12
|
+
if (value.mjs || value.mdts) {
|
13
|
+
anExport.import = {
|
14
|
+
types: value.mdts,
|
15
|
+
default: value.mjs
|
16
|
+
};
|
17
|
+
}
|
18
|
+
anExport.default = value.mjs;
|
19
|
+
allExports[key] = anExport;
|
20
|
+
}
|
21
|
+
const res = {
|
22
|
+
name: parsed.name,
|
23
|
+
type: "module",
|
24
|
+
version: parsed.version,
|
25
|
+
bin: (_a = exportsMap.get("__bin__")) == null ? void 0 : _a.mjs,
|
26
|
+
types: (_b = allExports["."]) == null ? void 0 : _b.types,
|
27
|
+
module: (_c = allExports["."]) == null ? void 0 : _c.default,
|
28
|
+
description: parsed.description ?? "",
|
29
|
+
exports: allExports,
|
30
|
+
dependencies: parsed.dependencies ?? void 0
|
31
|
+
};
|
32
|
+
await writeFile(`${outDir}/package.json`, JSON.stringify(res, null, 2));
|
33
|
+
}
|
34
|
+
export {
|
35
|
+
writePackageJson
|
36
|
+
};
|
package/package.json
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
{
|
2
|
+
"name": "smartbundle",
|
3
|
+
"type": "module",
|
4
|
+
"version": "0.0.1",
|
5
|
+
"bin": "./src/bin.mjs",
|
6
|
+
"description": "",
|
7
|
+
"exports": {},
|
8
|
+
"dependencies": {
|
9
|
+
"@rollup/plugin-typescript": "^11.1.6",
|
10
|
+
"vite": "^5.3.4",
|
11
|
+
"yargs": "^17.7.2",
|
12
|
+
"zod": "^3.23.8"
|
13
|
+
}
|
14
|
+
}
|
package/src/args.d.ts
ADDED
package/src/bin.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/src/bin.mjs
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/src/errors.d.ts
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
export declare const errors: {
|
2
|
+
exportsRequired: string;
|
3
|
+
exportsInvalid: string;
|
4
|
+
nameRequired: string;
|
5
|
+
nameMinLength: string;
|
6
|
+
nameMaxLength: string;
|
7
|
+
nameStartsIllegalChars: string;
|
8
|
+
versionRequired: string;
|
9
|
+
privateIsTrue: string;
|
10
|
+
descriptionString: string;
|
11
|
+
dependenciesInvalid: string;
|
12
|
+
binString: string;
|
13
|
+
rollupError: string;
|
14
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const a = 1;
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare function foo(): void;
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const a = 1;
|
package/src/index.d.ts
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
import z from "zod";
|
2
|
+
declare function createPackageJsonSchema(sourceDir: string): z.ZodObject<{
|
3
|
+
exports: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
4
|
+
name: z.ZodEffects<z.ZodString, string, string>;
|
5
|
+
version: z.ZodString;
|
6
|
+
private: z.ZodEffects<z.ZodBoolean, boolean, boolean>;
|
7
|
+
description: z.ZodOptional<z.ZodString>;
|
8
|
+
dependencies: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
9
|
+
bin: z.ZodOptional<z.ZodString>;
|
10
|
+
}, "strip", z.ZodTypeAny, {
|
11
|
+
name: string;
|
12
|
+
version: string;
|
13
|
+
private: boolean;
|
14
|
+
exports?: string | undefined;
|
15
|
+
description?: string | undefined;
|
16
|
+
dependencies?: Record<string, string> | undefined;
|
17
|
+
bin?: string | undefined;
|
18
|
+
}, {
|
19
|
+
name: string;
|
20
|
+
version: string;
|
21
|
+
private: boolean;
|
22
|
+
exports?: string | undefined;
|
23
|
+
description?: string | undefined;
|
24
|
+
dependencies?: Record<string, string> | undefined;
|
25
|
+
bin?: string | undefined;
|
26
|
+
}>;
|
27
|
+
type PackageJsonSchema = ReturnType<typeof createPackageJsonSchema>;
|
28
|
+
export type PackageJson = z.infer<PackageJsonSchema>;
|
29
|
+
type Errors = Array<string>;
|
30
|
+
type ParsePackageJsonArg = {
|
31
|
+
packagePath: string;
|
32
|
+
sourceDir: string;
|
33
|
+
};
|
34
|
+
export declare function parsePackageJson({ sourceDir, packagePath, }: ParsePackageJsonArg): Promise<PackageJson | Errors>;
|
35
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { PackageJson } from "./packageJson.js";
|
2
|
+
export type ExportsObject = {
|
3
|
+
mjs?: string;
|
4
|
+
mdts?: string;
|
5
|
+
};
|
6
|
+
type BuildResult = {
|
7
|
+
exportsMap: Map<string, ExportsObject>;
|
8
|
+
};
|
9
|
+
export declare function writePackageJson(outDir: string, parsed: PackageJson, { exportsMap }: BuildResult): Promise<void>;
|
10
|
+
export {};
|
package/types.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
import "vitest-directory-snapshot/dist/types.js";
|