@prosopo/config 3.3.0 → 3.3.2
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/.turbo/turbo-build$colon$cjs.log +4 -4
- package/.turbo/turbo-build$colon$tsc.log +4 -4
- package/.turbo/turbo-build.log +5 -5
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +10 -0
- package/dist/cjs/vite/vite.backend.config.cjs +8 -1
- package/dist/cjs/webpack/webpack.config.cjs +8 -6
- package/dist/vite/vite.backend.config.d.ts +1 -1
- package/dist/vite/vite.backend.config.d.ts.map +1 -1
- package/dist/vite/vite.backend.config.js +8 -1
- package/dist/vite/vite.backend.config.js.map +1 -1
- package/dist/vite/vite.commonjs.config.d.ts +1 -1
- package/dist/vite/vite.commonjs.config.d.ts.map +1 -1
- package/dist/vite/vite.commonjs.config.js.map +1 -1
- package/dist/vite/vite.esm.config.d.ts +1 -1
- package/dist/vite/vite.esm.config.d.ts.map +1 -1
- package/dist/vite/vite.esm.config.js.map +1 -1
- package/dist/webpack/webpack.config.d.ts +1 -6
- package/dist/webpack/webpack.config.d.ts.map +1 -1
- package/dist/webpack/webpack.config.js +8 -6
- package/dist/webpack/webpack.config.js.map +1 -1
- package/package.json +4 -3
- package/src/dependencies.ts +246 -0
- package/src/index.ts +16 -0
- package/src/vite/NodejsPolarsDirnamePlugin.ts +45 -0
- package/src/vite/NodejsPolarsNativeFilePlugin.ts +83 -0
- package/src/vite/TsNoCheckPlugin.ts +27 -0
- package/src/vite/index.ts +25 -0
- package/src/vite/types.ts +13 -0
- package/src/vite/vite-plugin-close-and-copy.ts +76 -0
- package/src/vite/vite-plugin-copy.ts +67 -0
- package/src/vite/vite-plugin-fix-absolute-imports.ts +40 -0
- package/src/vite/vite-plugin-remove-unused-translations.ts +128 -0
- package/src/vite/vite-plugin-sourcemap-exclude.ts +36 -0
- package/src/vite/vite.backend.config.ts +148 -0
- package/src/vite/vite.commonjs.config.ts +96 -0
- package/src/vite/vite.esm.config.ts +87 -0
- package/src/vite/vite.frontend.config.ts +265 -0
- package/src/vite/vite.test.config.ts +111 -0
- package/src/vite/vite.threads.test.config.ts +109 -0
- package/src/webpack/index.ts +14 -0
- package/src/webpack/webpack.config.ts +152 -0
- package/tsconfig.cjs.json +9 -0
- package/tsconfig.json +17 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/tsconfig.types.json +9 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
import fs from "node:fs";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
|
|
18
|
+
export const nodejsPolarsNativeFilePlugin = (
|
|
19
|
+
nodeFiles: string[],
|
|
20
|
+
outDir: string,
|
|
21
|
+
) => {
|
|
22
|
+
const name = "nodejs-polars-native-file-plugin";
|
|
23
|
+
return {
|
|
24
|
+
name,
|
|
25
|
+
// biome-ignore lint/suspicious/noExplicitAny: TODO not sure of options type
|
|
26
|
+
resolveId(source: string, importer: string | undefined, options: any) {
|
|
27
|
+
// return the id if this plugin can resolve the import
|
|
28
|
+
for (const file of nodeFiles) {
|
|
29
|
+
if (path.basename(source) === path.basename(file)) {
|
|
30
|
+
console.debug(name, "resolves", source, "imported by", importer);
|
|
31
|
+
return source;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return null; // otherwise return null indicating that this plugin can't handle the import
|
|
35
|
+
},
|
|
36
|
+
transform(code: string, id: string) {
|
|
37
|
+
for (const file of nodeFiles) {
|
|
38
|
+
// rewrite the code to import the .node file
|
|
39
|
+
if (path.basename(id) === path.basename(file)) {
|
|
40
|
+
console.debug(name, "transform", id);
|
|
41
|
+
// https://stackoverflow.com/questions/66378682/nodejs-loading-es-modules-and-native-addons-in-the-same-project
|
|
42
|
+
// this makes the .node file load at runtime from an esm context. .node files aren't native to esm, so we have to create a custom require function to load them. The custom require function is equivalent to the require function in commonjs, thus allowing the .node file to be loaded.
|
|
43
|
+
return `
|
|
44
|
+
// create a custom require function to load .node files
|
|
45
|
+
import { createRequire } from 'module';
|
|
46
|
+
const customRequire = createRequire(import.meta.url)
|
|
47
|
+
|
|
48
|
+
// load the .node file expecting it to be in the same directory as the output bundle
|
|
49
|
+
const content = customRequire('./${file}')
|
|
50
|
+
|
|
51
|
+
// export the content straight back out again
|
|
52
|
+
export default content
|
|
53
|
+
`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return code;
|
|
57
|
+
},
|
|
58
|
+
load(id: string) {
|
|
59
|
+
for (const file of nodeFiles) {
|
|
60
|
+
if (path.basename(id) === path.basename(file)) {
|
|
61
|
+
console.debug(name, "load", id);
|
|
62
|
+
// whenever we encounter an import of the .node file, we return an empty string. This makes it look like the .node file is empty to the bundler. This is because we're going to copy the .node file to the output directory ourselves, so we don't want the bundler to include it in the output bundle (also because the bundler can't handle .node files, it tries to read them as js and then complains that it's invalid js)
|
|
63
|
+
const newCode = "";
|
|
64
|
+
return newCode;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
},
|
|
69
|
+
// biome-ignore lint/suspicious/noExplicitAny: TODO not sure of options/bundle type
|
|
70
|
+
generateBundle(options: any, bundle: any) {
|
|
71
|
+
for (const fileAbs of nodeFiles) {
|
|
72
|
+
const file = path.basename(fileAbs);
|
|
73
|
+
// copy the .node file to the output directory
|
|
74
|
+
const out = `${outDir}/${file}`;
|
|
75
|
+
const src = `${fileAbs}`;
|
|
76
|
+
console.debug(name, "copy", src, "to", out);
|
|
77
|
+
const nodeFile = fs.readFileSync(src);
|
|
78
|
+
fs.mkdirSync(path.dirname(out), { recursive: true });
|
|
79
|
+
fs.writeFileSync(out, nodeFile);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
export function tsNoCheckPlugin() {
|
|
15
|
+
return {
|
|
16
|
+
name: "vite-plugin-ts-nocheck",
|
|
17
|
+
// biome-ignore lint/suspicious/noExplicitAny: TODO not sure of options/bundle type (same as NodejsPolarsNativeFilePlugin)
|
|
18
|
+
generateBundle(_: any, bundle: any) {
|
|
19
|
+
for (const fileName in bundle) {
|
|
20
|
+
const chunk = bundle[fileName];
|
|
21
|
+
if (chunk.type === "chunk" && chunk.code) {
|
|
22
|
+
chunk.code = `// @ts-nocheck\n${chunk.code}`;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
export { default as VitePluginCloseAndCopy } from "./vite-plugin-close-and-copy.js";
|
|
15
|
+
export { default as ViteTestConfig } from "./vite.test.config.js";
|
|
16
|
+
export { default as ViteThreadsTestConfig } from "./vite.threads.test.config.js";
|
|
17
|
+
export { default as VitePluginSourceMapExclude } from "./vite-plugin-sourcemap-exclude.js";
|
|
18
|
+
export { default as ViteFrontendConfig } from "./vite.frontend.config.js";
|
|
19
|
+
export { default as ViteBackendConfig } from "./vite.backend.config.js";
|
|
20
|
+
export { default as VitePluginFixAbsoluteImports } from "./vite-plugin-fix-absolute-imports.js";
|
|
21
|
+
export { default as ViteCommonJSConfig } from "./vite.commonjs.config.js";
|
|
22
|
+
export { default as ViteEsmConfig } from "./vite.esm.config.js";
|
|
23
|
+
export { default as VitePluginRemoveUnusedTranslations } from "./vite-plugin-remove-unused-translations.js";
|
|
24
|
+
export * from "./TsNoCheckPlugin.js";
|
|
25
|
+
export { default as VitePluginCopy } from "./vite-plugin-copy.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
import fs from "node:fs";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import type { Plugin } from "vite";
|
|
18
|
+
|
|
19
|
+
export interface ClosePluginOptions {
|
|
20
|
+
srcDir: string;
|
|
21
|
+
destDir: string[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* description: Closes Vite after the bundle has been build. Optionally copies the bundle to a different directory.
|
|
26
|
+
* @param { ClosePluginOptions } options - The options object
|
|
27
|
+
**/
|
|
28
|
+
export default function VitePluginCloseAndCopy(
|
|
29
|
+
options?: ClosePluginOptions,
|
|
30
|
+
): Plugin {
|
|
31
|
+
const __dirname = path.resolve();
|
|
32
|
+
return {
|
|
33
|
+
name: "close-plugin", // required, will show up in warnings and errors
|
|
34
|
+
buildStart() {
|
|
35
|
+
console.info("Bundle build started");
|
|
36
|
+
},
|
|
37
|
+
buildEnd(error) {
|
|
38
|
+
console.info("Build end");
|
|
39
|
+
if (error) {
|
|
40
|
+
console.log(error);
|
|
41
|
+
console.error(error);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
closeBundle() {
|
|
45
|
+
if (options) {
|
|
46
|
+
for (const destDir of options.destDir) {
|
|
47
|
+
clearOutputDirJS(__dirname, destDir);
|
|
48
|
+
console.info(`Bundle cleared from ${options.destDir}`);
|
|
49
|
+
copyBundle(__dirname, options.srcDir, destDir);
|
|
50
|
+
console.info(`Bundle copied to ${options.destDir}`);
|
|
51
|
+
}
|
|
52
|
+
console.info("Bundle closed");
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const clearOutputDirJS = (__dirname: string, destDir: string) =>
|
|
59
|
+
fs
|
|
60
|
+
.readdirSync(path.resolve(__dirname, destDir))
|
|
61
|
+
.filter((file) => file.endsWith("js"))
|
|
62
|
+
.map((file) => {
|
|
63
|
+
fs.rmSync(path.resolve(__dirname, destDir, file));
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const copyBundle = (__dirname: string, srcDir: string, destDir: string) => {
|
|
67
|
+
console.info(
|
|
68
|
+
"Copying",
|
|
69
|
+
path.resolve(__dirname, srcDir),
|
|
70
|
+
"to",
|
|
71
|
+
path.resolve(__dirname, destDir),
|
|
72
|
+
);
|
|
73
|
+
fs.cpSync(path.resolve(__dirname, srcDir), path.resolve(__dirname, destDir), {
|
|
74
|
+
recursive: true,
|
|
75
|
+
});
|
|
76
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
import fs from "node:fs";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import fg from "fast-glob";
|
|
18
|
+
import type { Plugin } from "vite";
|
|
19
|
+
|
|
20
|
+
interface CopyPluginOptions {
|
|
21
|
+
srcDir: string;
|
|
22
|
+
destDir: string;
|
|
23
|
+
include?: string[]; // Optional: glob patterns for files to include
|
|
24
|
+
exclude?: string[]; // Optional: glob patterns for files to exclude
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function ensureDirExists(filePath: string) {
|
|
28
|
+
const dir = path.dirname(filePath);
|
|
29
|
+
if (!fs.existsSync(dir)) {
|
|
30
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default function VitePluginCopy(options: CopyPluginOptions): Plugin {
|
|
35
|
+
const __dirname = path.resolve();
|
|
36
|
+
return {
|
|
37
|
+
name: "copy-plugin",
|
|
38
|
+
async closeBundle() {
|
|
39
|
+
const srcAbs = path.resolve(__dirname, options.srcDir);
|
|
40
|
+
const destAbs = path.resolve(__dirname, options.destDir);
|
|
41
|
+
const include =
|
|
42
|
+
options.include && options.include.length > 0
|
|
43
|
+
? options.include
|
|
44
|
+
: undefined;
|
|
45
|
+
const exclude = options.exclude || [];
|
|
46
|
+
if (!include) {
|
|
47
|
+
console.info(
|
|
48
|
+
"[copy-plugin] No include globs specified, nothing to copy.",
|
|
49
|
+
);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const files = await fg(include, {
|
|
53
|
+
cwd: srcAbs,
|
|
54
|
+
ignore: exclude,
|
|
55
|
+
onlyFiles: true,
|
|
56
|
+
absolute: false,
|
|
57
|
+
});
|
|
58
|
+
for (const relFile of files) {
|
|
59
|
+
const srcFile = path.join(srcAbs, relFile);
|
|
60
|
+
const destFile = path.join(destAbs, relFile);
|
|
61
|
+
ensureDirExists(destFile);
|
|
62
|
+
console.info(`[copy-plugin] copying ${srcFile} to ${destFile}`);
|
|
63
|
+
fs.copyFileSync(srcFile, destFile);
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import { builtinModules } from "node:module";
|
|
15
|
+
import type { Plugin } from "vite";
|
|
16
|
+
|
|
17
|
+
export default function VitePluginFixAbsoluteImports(): Plugin {
|
|
18
|
+
return {
|
|
19
|
+
name: "fix-absolute-imports",
|
|
20
|
+
transform(code: string, id: string) {
|
|
21
|
+
for (const module of builtinModules) {
|
|
22
|
+
const moduleImportRegex = new RegExp(
|
|
23
|
+
`from "(${module}(/.*)*/.*.js)";`,
|
|
24
|
+
"g",
|
|
25
|
+
);
|
|
26
|
+
// if matches, replace match with _module
|
|
27
|
+
const matches = code.match(moduleImportRegex);
|
|
28
|
+
if (matches) {
|
|
29
|
+
for (const match of matches) {
|
|
30
|
+
code = code.replace(match, `from "${module}";`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
code,
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
enforce: "post",
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import fs from "node:fs/promises";
|
|
15
|
+
import glob from "fast-glob";
|
|
16
|
+
import type { Plugin } from "vite";
|
|
17
|
+
|
|
18
|
+
const used = new Set<string>();
|
|
19
|
+
|
|
20
|
+
export const flatten = (obj: object, prefix = ""): Record<string, string> => {
|
|
21
|
+
const flattenedObj: Record<string, string> = {};
|
|
22
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
23
|
+
if (value instanceof Object) {
|
|
24
|
+
Object.assign(flattenedObj, flatten(value, `${prefix + key}.`));
|
|
25
|
+
} else {
|
|
26
|
+
flattenedObj[prefix + key] = value;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return flattenedObj;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
type UnflattenObject =
|
|
33
|
+
| Record<string, string | number | boolean | undefined>
|
|
34
|
+
| string[]
|
|
35
|
+
| number[]
|
|
36
|
+
| boolean[];
|
|
37
|
+
|
|
38
|
+
export const unflatten = (
|
|
39
|
+
obj: Record<string, string | number | boolean>,
|
|
40
|
+
): Record<string, string | number | boolean | UnflattenObject> => {
|
|
41
|
+
const result: Record<string, string | number | boolean | UnflattenObject> =
|
|
42
|
+
{};
|
|
43
|
+
|
|
44
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
45
|
+
const keys = key.split(".");
|
|
46
|
+
keys.reduce((acc, k, i) => {
|
|
47
|
+
if (i === keys.length - 1) {
|
|
48
|
+
(acc as Record<string, string | number | boolean | UnflattenObject>)[
|
|
49
|
+
k
|
|
50
|
+
] = value;
|
|
51
|
+
} else {
|
|
52
|
+
if (!acc[k]) {
|
|
53
|
+
acc[k] = Number.isNaN(Number(keys[i + 1])) ? {} : [];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return acc[k] as Record<
|
|
57
|
+
string,
|
|
58
|
+
string | number | boolean | UnflattenObject
|
|
59
|
+
>;
|
|
60
|
+
}, result);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return result;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export default function VitePluginRemoveUnusedTranslations(
|
|
67
|
+
translationKeys: string[],
|
|
68
|
+
jsonPattern: string,
|
|
69
|
+
): Plugin {
|
|
70
|
+
return {
|
|
71
|
+
name: "remove-unused-translations",
|
|
72
|
+
transform(code: string) {
|
|
73
|
+
// Collect translation keys used in the source files
|
|
74
|
+
for (const key of translationKeys) {
|
|
75
|
+
if (code.includes(key) && !used.has(key)) {
|
|
76
|
+
console.info(`Found key: ${key}`);
|
|
77
|
+
used.add(key);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return { code };
|
|
81
|
+
},
|
|
82
|
+
enforce: "post",
|
|
83
|
+
|
|
84
|
+
async writeBundle() {
|
|
85
|
+
// Find all matching JSON files
|
|
86
|
+
const jsonFiles = await glob(jsonPattern, { absolute: true });
|
|
87
|
+
|
|
88
|
+
console.info(`Found ${jsonFiles.length} JSON files at ${jsonPattern}`);
|
|
89
|
+
|
|
90
|
+
const filePromises = [];
|
|
91
|
+
for (const filePath of jsonFiles) {
|
|
92
|
+
try {
|
|
93
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
94
|
+
const jsonData = JSON.parse(content);
|
|
95
|
+
const jsonDataFlattened = flatten(jsonData);
|
|
96
|
+
|
|
97
|
+
// Remove keys that are not in `used`
|
|
98
|
+
const filteredData = Object.fromEntries(
|
|
99
|
+
Object.entries(jsonDataFlattened).filter(([key]) => used.has(key)),
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const unflattened = unflatten(filteredData);
|
|
103
|
+
|
|
104
|
+
// log.info(unflattened);
|
|
105
|
+
|
|
106
|
+
// Write back the filtered JSON
|
|
107
|
+
filePromises.push(
|
|
108
|
+
fs
|
|
109
|
+
.writeFile(
|
|
110
|
+
filePath,
|
|
111
|
+
JSON.stringify(unflattened, null, 2),
|
|
112
|
+
"utf-8",
|
|
113
|
+
)
|
|
114
|
+
.then(() => {
|
|
115
|
+
console.info(`Updated ${filePath}`);
|
|
116
|
+
})
|
|
117
|
+
.catch((e) => {
|
|
118
|
+
console.error(`Failed to update ${filePath}:`, e);
|
|
119
|
+
}),
|
|
120
|
+
);
|
|
121
|
+
} catch (error: unknown) {
|
|
122
|
+
console.error(`Failed to process ${filePath}:`, error);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
await Promise.all(filePromises);
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import type { Plugin } from "vite";
|
|
15
|
+
|
|
16
|
+
interface SourcemapExclude {
|
|
17
|
+
excludeNodeModules?: boolean;
|
|
18
|
+
}
|
|
19
|
+
// Taken from https://github.com/vitejs/vite/issues/2433#issuecomment-1487472995 to prevent memory leaks
|
|
20
|
+
export default function VitePluginSourcemapExclude(
|
|
21
|
+
opts?: SourcemapExclude,
|
|
22
|
+
): Plugin {
|
|
23
|
+
return {
|
|
24
|
+
name: "sourcemap-exclude",
|
|
25
|
+
transform(code: string, id: string) {
|
|
26
|
+
if (opts?.excludeNodeModules && id.includes("node_modules")) {
|
|
27
|
+
return {
|
|
28
|
+
code,
|
|
29
|
+
// https://github.com/rollup/rollup/blob/master/docs/plugin-development/index.md#source-code-transformations
|
|
30
|
+
map: { mappings: "" },
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return;
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
import { builtinModules } from "node:module";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import { wasm } from "@rollup/plugin-wasm";
|
|
18
|
+
import type { Drop } from "esbuild";
|
|
19
|
+
import css from "rollup-plugin-import-css";
|
|
20
|
+
import type { UserConfig } from "vite";
|
|
21
|
+
import { filterDependencies, getDependencies } from "../dependencies.js";
|
|
22
|
+
import { default as ClosePlugin } from "./vite-plugin-close-and-copy.js";
|
|
23
|
+
import VitePluginFixAbsoluteImports from "./vite-plugin-fix-absolute-imports.js";
|
|
24
|
+
|
|
25
|
+
export default async function (
|
|
26
|
+
packageName: string,
|
|
27
|
+
packageVersion: string,
|
|
28
|
+
bundleName: string,
|
|
29
|
+
packageDir: string,
|
|
30
|
+
entry: string | string[] | Record<string, string>,
|
|
31
|
+
command?: string,
|
|
32
|
+
mode?: string,
|
|
33
|
+
outputDir?: string,
|
|
34
|
+
): Promise<UserConfig> {
|
|
35
|
+
const isProduction = mode === "production";
|
|
36
|
+
|
|
37
|
+
// Get all dependencies of the current package
|
|
38
|
+
const { dependencies: deps, optionalPeerDependencies } =
|
|
39
|
+
await getDependencies(packageName, true);
|
|
40
|
+
|
|
41
|
+
// Output directory is custom or relative to directory of the package
|
|
42
|
+
const outDir = outputDir
|
|
43
|
+
? path.resolve(outputDir)
|
|
44
|
+
: path.resolve(packageDir, "dist/bundle");
|
|
45
|
+
|
|
46
|
+
// Get rid of any dependencies we don't want to bundle
|
|
47
|
+
const { external, internal } = filterDependencies(deps, [
|
|
48
|
+
"aws",
|
|
49
|
+
"webpack",
|
|
50
|
+
"vite",
|
|
51
|
+
"biome",
|
|
52
|
+
]);
|
|
53
|
+
|
|
54
|
+
// Add the node builtins (path, fs, os, etc.) to the external list
|
|
55
|
+
const allExternal = [
|
|
56
|
+
...builtinModules,
|
|
57
|
+
...builtinModules.map((m) => `node:${m}`),
|
|
58
|
+
...external,
|
|
59
|
+
...optionalPeerDependencies,
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
console.info(
|
|
63
|
+
`Bundling. ${JSON.stringify(internal.slice(0, 10), null, 2)}... ${internal.length} deps`,
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const define = {
|
|
67
|
+
"process.env.WS_NO_BUFFER_UTIL": "true",
|
|
68
|
+
"process.env.WS_NO_UTF_8_VALIDATE": "true",
|
|
69
|
+
"process.env.PROSOPO_PACKAGE_VERSION": JSON.stringify(packageVersion),
|
|
70
|
+
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || mode),
|
|
71
|
+
...(process.env.PROSOPO_DEFAULT_ENVIRONMENT && {
|
|
72
|
+
"process.env.PROSOPO_DEFAULT_ENVIRONMENT": JSON.stringify(
|
|
73
|
+
process.env.PROSOPO_DEFAULT_ENVIRONMENT,
|
|
74
|
+
),
|
|
75
|
+
}),
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
console.info(`Defined vars ${JSON.stringify(define, null, 2)}`);
|
|
79
|
+
|
|
80
|
+
let entriesAbsolute: string[];
|
|
81
|
+
if (typeof entry === "string") {
|
|
82
|
+
entriesAbsolute = [path.resolve(packageDir, entry)];
|
|
83
|
+
} else if (Array.isArray(entry)) {
|
|
84
|
+
entriesAbsolute = entry.map((e) => path.resolve(packageDir, e));
|
|
85
|
+
} else {
|
|
86
|
+
entriesAbsolute = Object.fromEntries(
|
|
87
|
+
Object.entries(entry).map(([key, value]) => [
|
|
88
|
+
key,
|
|
89
|
+
path.resolve(packageDir, value),
|
|
90
|
+
]),
|
|
91
|
+
) as unknown as string[];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// drop console logs if in production mode
|
|
95
|
+
const drop: Drop[] | undefined =
|
|
96
|
+
mode === "production" ? ["console", "debugger"] : undefined;
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
ssr: {
|
|
100
|
+
noExternal: true,
|
|
101
|
+
external: allExternal,
|
|
102
|
+
},
|
|
103
|
+
optimizeDeps: {
|
|
104
|
+
include: ["linked-dep", "node_modules"],
|
|
105
|
+
esbuildOptions: {
|
|
106
|
+
loader: {
|
|
107
|
+
".node": "file",
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
esbuild: {
|
|
112
|
+
platform: "node",
|
|
113
|
+
target: "node24",
|
|
114
|
+
// drop,
|
|
115
|
+
legalComments: "none",
|
|
116
|
+
},
|
|
117
|
+
define,
|
|
118
|
+
build: {
|
|
119
|
+
outDir,
|
|
120
|
+
minify: isProduction,
|
|
121
|
+
ssr: true,
|
|
122
|
+
target: "node24",
|
|
123
|
+
lib: {
|
|
124
|
+
entry: entriesAbsolute,
|
|
125
|
+
name: bundleName,
|
|
126
|
+
fileName: `${bundleName}.[name].bundle.js`,
|
|
127
|
+
formats: ["es"],
|
|
128
|
+
},
|
|
129
|
+
modulePreload: { polyfill: false },
|
|
130
|
+
rollupOptions: {
|
|
131
|
+
treeshake: "smallest",
|
|
132
|
+
external: allExternal,
|
|
133
|
+
watch: false,
|
|
134
|
+
output: {
|
|
135
|
+
entryFileNames: `${bundleName}.[name].bundle.js`,
|
|
136
|
+
},
|
|
137
|
+
// biome-ignore lint/suspicious/noExplicitAny: has to be any to represent object prototype
|
|
138
|
+
plugins: [css() as any, wasm() as any],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
plugins: [
|
|
142
|
+
// plugin to replace stuff like import blah from string_encoder/lib/string_encoder.js with import blah from string_encoder
|
|
143
|
+
VitePluginFixAbsoluteImports(),
|
|
144
|
+
// plugin to close the bundle after build if not in serve mode
|
|
145
|
+
command !== "serve" ? ClosePlugin() : undefined,
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
}
|