@vistta/cli 1.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.
@@ -0,0 +1,62 @@
1
+ name: Development Workflow
2
+ on:
3
+ push:
4
+ branches:
5
+ - development
6
+ env:
7
+ module: cli
8
+ jobs:
9
+ Validation:
10
+ runs-on: ubuntu-latest
11
+ container:
12
+ image: node:latest
13
+ steps:
14
+ - name: Checkout
15
+ uses: tiagomta/checkout@v1
16
+ with:
17
+ repository: vistta/workspace
18
+ ref: main
19
+ token: ${{ secrets.TOKEN }}
20
+ fetch-depth: 0
21
+ submodules: true
22
+ - name: Close Issues
23
+ uses: tiagomta/gitea@v1
24
+ with:
25
+ token: ${{ secrets.TOKEN }}
26
+ working-directory: ./packages/${{ env.module }}
27
+ command: issues close --fromCommit
28
+ - name: Setup Node
29
+ run: npm ci
30
+ - name: Module Validation
31
+ working-directory: ./packages/${{ env.module }}
32
+ run: npx vistta project outdated
33
+ continue-on-error: true
34
+ - name: Eslint Validation
35
+ working-directory: ./packages/${{ env.module }}
36
+ run: npx eslint .
37
+ continue-on-error: true
38
+ - name: Typescript Validation
39
+ working-directory: ./packages/${{ env.module }}
40
+ run: npx tsc
41
+ continue-on-error: true
42
+ - name: Unit Tests
43
+ working-directory: ./packages/${{ env.module }}
44
+ run: npx vistta test
45
+
46
+ PreRelease:
47
+ needs: Validation
48
+ runs-on: ubuntu-latest
49
+ container:
50
+ image: node:latest
51
+ steps:
52
+ - name: Checkout
53
+ uses: tiagomta/checkout@v1
54
+ - name: PreRelease
55
+ uses: tiagomta/npm@v1
56
+ with:
57
+ command: version prerelease SNAPSHOT-${{ gitea.run_id }} --email devops@vistta.org
58
+ - name: Publish PreRelease (Gitea)
59
+ uses: tiagomta/npm@v1
60
+ with:
61
+ command: publish --scope vistta --registry https://git.vistta.org/api/packages/vistta/npm/ --tag snapshot
62
+ token: ${{ secrets.TOKEN }}
@@ -0,0 +1,124 @@
1
+ name: Release Workflow
2
+ on:
3
+ workflow_dispatch:
4
+ inputs:
5
+ type:
6
+ description: "Release Type"
7
+ required: true
8
+ type: choice
9
+ options:
10
+ - Patch
11
+ - Minor
12
+ - Major
13
+ npm_publish:
14
+ description: "Publish to NPM Registry"
15
+ required: false
16
+ default: true
17
+ type: boolean
18
+ gitea_publish:
19
+ description: "Publish to Gitea Registry"
20
+ required: false
21
+ default: true
22
+ type: boolean
23
+
24
+ env:
25
+ module: cli
26
+ ref: refs/heads/development
27
+ jobs:
28
+ Validation:
29
+ runs-on: ubuntu-latest
30
+ container:
31
+ image: node:latest
32
+ steps:
33
+ - name: Checkout
34
+ uses: tiagomta/checkout@v1
35
+ with:
36
+ repository: vistta/workspace
37
+ ref: main
38
+ token: ${{ secrets.TOKEN }}
39
+ fetch-depth: 0
40
+ submodules: true
41
+ - name: Setup Node
42
+ run: npm ci
43
+ - name: Module Validation
44
+ working-directory: ./packages/${{ env.module }}
45
+ run: npx vistta project outdated
46
+ - name: Eslint Validation
47
+ working-directory: ./packages/${{ env.module }}
48
+ run: npx eslint .
49
+ - name: Typescript Validation
50
+ working-directory: ./packages/${{ env.module }}
51
+ run: npx tsc
52
+ - name: Unit Tests
53
+ working-directory: ./packages/${{ env.module }}
54
+ run: npx vistta test
55
+
56
+ Release:
57
+ needs: Validation
58
+ runs-on: ubuntu-latest
59
+ container:
60
+ image: node:latest
61
+ if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/development'
62
+ steps:
63
+ - name: Checkout
64
+ uses: tiagomta/checkout@v1
65
+ with:
66
+ ref: ${{ env.ref }}
67
+ token: ${{ secrets.TOKEN }}
68
+ - name: NPM Release
69
+ uses: tiagomta/nodejs-run@v1
70
+ id: npm
71
+ with:
72
+ target: inline
73
+ run: |
74
+ await git.config("user.email", "devops@vistta.org");
75
+ const version = await npm.version("${{ inputs.type }}".toLowerCase());
76
+ // Release Gitea
77
+ if (`${{ inputs.gitea_publish }}`.toLowerCase() === "true") {
78
+ await npm.config("set", "@vistta:registry", "https://git.vistta.org/api/packages/vistta/npm/");
79
+ await npm.config("set", "--", "//git.vistta.org/api/packages/vistta/npm/:_authToken", "${{ secrets.TOKEN }}");
80
+ await npm.publish();
81
+ }
82
+ // Release NPM
83
+ if (`${{ inputs.npm_publish }}`.toLowerCase() === "true") {
84
+ await npm.config("set", "@vistta:registry", "https://registry.npmjs.org/");
85
+ await npm.config("set", "--", "//registry.npmjs.org/:_authToken", "${{ secrets.NPM_TOKEN }}");
86
+ await npm.publish("--access", "public");
87
+ }
88
+ // Update Branches
89
+ await git.push("origin", "${{ env.ref }}", "--tags");
90
+ await git.fetch("origin", "master");
91
+ await git.checkout("master");
92
+ await git.reset("--hard", "${{ env.ref }}");
93
+ await git.push("origin", "master", "--force");
94
+ result = version;
95
+ - name: Gitea Release
96
+ uses: tiagomta/nodejs-run@v1
97
+ with:
98
+ target: inline
99
+ run: |
100
+ const version = (`${{ steps.npm.outputs.result }}`).trim();
101
+ const milestone = await gitea.milestones.create("${{ inputs.type }} (" + version + ")");
102
+ const issues = await gitea.issues.list({ state: "closed" });
103
+ const types = {};
104
+ for (let issue of issues) {
105
+ const type =
106
+ issue.labels.find((l) => l.name.startsWith("Project/"))?.name.slice(8) +
107
+ "s";
108
+ if (type && issue.milestone == milestone.id) {
109
+ if (!types[type]) types[type] = `## ${type}\n`;
110
+ types[type] += `- ${issue.title} (#${issue.number})\n`;
111
+ } else if (issue.milestone == null) {
112
+ await gitea.issues.update(issue.number, { milestone: milestone.id });
113
+ if (type) {
114
+ if (!types[type]) types[type] = `## ${type}\n`;
115
+ types[type] += `- ${issue.title} (#${issue.number})\n`;
116
+ }
117
+ }
118
+ }
119
+ await gitea.releases.create({
120
+ tag_name: version,
121
+ name: "${{ inputs.type }} (" + version + ")",
122
+ body: Object.values(types).join("\n")
123
+ });
124
+ await gitea.milestones.close(milestone.id);
package/LICENSE ADDED
@@ -0,0 +1,188 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ =======================================================================
6
+ Commons Clause License Condition v1.0
7
+ =======================================================================
8
+
9
+ The Software is provided under the terms of the Apache License 2.0, with the following additional restriction:
10
+
11
+ You may not sell, license, host, or otherwise make available the Software for a fee, nor include the Software in a product or service that is primarily the Software itself.
12
+
13
+ For clarity, this restriction does not limit your right to:
14
+
15
+ - Use the Software to build or operate a business.
16
+ - Include the Software as a component of a larger product or service.
17
+ - Charge for your own work that uses or extends the Software.
18
+
19
+ What is prohibited is selling or redistributing the Software itself, unmodified or minimally modified, as a standalone product.
20
+
21
+ =======================================================================
22
+ Apache License, Version 2.0
23
+ =======================================================================
24
+
25
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
26
+
27
+ 1. Definitions.
28
+
29
+ "License" shall mean the terms and conditions for use, reproduction,
30
+ and distribution as defined by Sections 1 through 9 of this document.
31
+
32
+ "Licensor" shall mean the copyright owner or entity authorized by
33
+ the copyright owner that is granting the License.
34
+
35
+ "Legal Entity" shall mean the union of the acting entity and all
36
+ other entities that control, are controlled by, or are under common
37
+ control with that entity. For the purposes of this definition,
38
+ "control" means (i) the power, direct or indirect, to cause the
39
+ direction or management of such entity, whether by contract or
40
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
41
+ outstanding shares, or (iii) beneficial ownership of such entity.
42
+
43
+ "You" (or "Your") shall mean an individual or Legal Entity
44
+ exercising permissions granted by this License.
45
+
46
+ "Source" form shall mean the preferred form for making modifications,
47
+ including but not limited to software source code, documentation
48
+ source, and configuration files.
49
+
50
+ "Object" form shall mean any form resulting from mechanical
51
+ transformation or translation of a Source form, including but
52
+ not limited to compiled object code, generated documentation,
53
+ and conversions to other media types.
54
+
55
+ "Work" shall mean the work of authorship, whether in Source or
56
+ Object form, made available under the License, as indicated by a
57
+ copyright notice that is included in or attached to the work
58
+ (an example is provided in the Appendix below).
59
+
60
+ "Derivative Works" shall mean any work, whether in Source or Object
61
+ form, that is based on (or derived from) the Work and for which the
62
+ editorial revisions, annotations, elaborations, or other modifications
63
+ represent, as a whole, an original work of authorship. For the purposes
64
+ of this License, Derivative Works shall not include works that remain
65
+ separable from, or merely link (or bind by name) to the interfaces of,
66
+ the Work and Derivative Works thereof.
67
+
68
+ "Contribution" shall mean any work of authorship, including
69
+ the original version of the Work and any modifications or additions
70
+ to that Work or Derivative Works thereof, that is intentionally
71
+ submitted to Licensor for inclusion in the Work by the copyright owner
72
+ or by an individual or Legal Entity authorized to submit on behalf of
73
+ the copyright owner. For the purposes of this definition, "submitted"
74
+ means any form of electronic, verbal, or written communication sent
75
+ to the Licensor or its representatives, including but not limited to
76
+ communication on electronic mailing lists, source code control systems,
77
+ and issue tracking systems that are managed by, or on behalf of, the
78
+ Licensor for the purpose of discussing and improving the Work, but
79
+ excluding communication that is conspicuously marked or otherwise
80
+ designated in writing by the copyright owner as "Not a Contribution."
81
+
82
+ "Contributor" shall mean Licensor and any individual or Legal Entity
83
+ on behalf of whom a Contribution has been received by Licensor and
84
+ subsequently incorporated within the Work.
85
+
86
+ 2. Grant of Copyright License. Subject to the terms and conditions of
87
+ this License, each Contributor hereby grants to You a perpetual,
88
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
89
+ copyright license to reproduce, prepare Derivative Works of,
90
+ publicly display, publicly perform, sublicense, and distribute the
91
+ Work and such Derivative Works in Source or Object form.
92
+
93
+ 3. Grant of Patent License. Subject to the terms and conditions of
94
+ this License, each Contributor hereby grants to You a perpetual,
95
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
96
+ (except as stated in this section) patent license to make, have made,
97
+ use, offer to sell, sell, import, and otherwise transfer the Work,
98
+ where such license applies only to those patent claims licensable
99
+ by such Contributor that are necessarily infringed by their
100
+ Contribution(s) alone or by combination of their Contribution(s)
101
+ with the Work to which such Contribution(s) was submitted. If You
102
+ institute patent litigation against any entity (including a
103
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
104
+ or a Contribution incorporated within the Work constitutes direct
105
+ or contributory patent infringement, then any patent licenses
106
+ granted to You under this License for that Work shall terminate
107
+ as of the date such litigation is filed.
108
+
109
+ 4. Redistribution. You may reproduce and distribute copies of the
110
+ Work or Derivative Works thereof in any medium, with or without
111
+ modifications, and in Source or Object form, provided that You
112
+ meet the following conditions:
113
+ (a) You must give any other recipients of the Work or
114
+ Derivative Works a copy of this License; and
115
+ (b) You must cause any modified files to carry prominent notices
116
+ stating that You changed the files; and
117
+ (c) You must retain, in the Source form of any Derivative Works
118
+ that You distribute, all copyright, patent, trademark, and
119
+ attribution notices from the Source form of the Work,
120
+ excluding those notices that do not pertain to any part of
121
+ the Derivative Works; and
122
+ (d) If the Work includes a "NOTICE" text file as part of its
123
+ distribution, then any Derivative Works that You distribute must
124
+ include a readable copy of the attribution notices contained
125
+ within such NOTICE file, excluding those notices that do not
126
+ pertain to any part of the Derivative Works, in at least one
127
+ of the following places: within a NOTICE text file distributed
128
+ as part of the Derivative Works; within the Source form or
129
+ documentation, if provided along with the Derivative Works; or,
130
+ within a display generated by the Derivative Works, if and
131
+ wherever such third-party notices normally appear. The contents
132
+ of the NOTICE file are for informational purposes only and
133
+ do not modify the License. You may add Your own attribution
134
+ notices within Derivative Works that You distribute, alongside
135
+ or as an addendum to the NOTICE text from the Work, provided
136
+ that such additional attribution notices cannot be construed
137
+ as modifying the License.
138
+ (e) You may not offer or impose any terms on the Work that restrict
139
+ use, reproduction, or distribution of the Work beyond those
140
+ expressly permitted by this License.
141
+
142
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
143
+ any Contribution intentionally submitted for inclusion in the Work
144
+ by You to the Licensor shall be under the terms and conditions of
145
+ this License, without any additional terms or conditions.
146
+ Notwithstanding the above, nothing herein shall supersede or modify
147
+ the terms of any separate license agreement you may have executed
148
+ with Licensor regarding such Contributions.
149
+
150
+ 6. Trademarks. This License does not grant permission to use the trade
151
+ names, trademarks, service marks, or product names of the Licensor,
152
+ except as required for reasonable and customary use in describing the
153
+ origin of the Work and reproducing the content of the NOTICE file.
154
+
155
+ 7. Disclaimer of Warranty. Unless required by applicable law or
156
+ agreed to in writing, Licensor provides the Work (and each
157
+ Contributor provides its Contributions) on an "AS IS" BASIS,
158
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
159
+ implied, including, without limitation, any warranties or conditions
160
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
161
+ PARTICULAR PURPOSE. You are solely responsible for determining the
162
+ appropriateness of using or redistributing the Work and assume any
163
+ risks associated with Your exercise of permissions under this License.
164
+
165
+ 8. Limitation of Liability. In no event and under no legal theory,
166
+ whether in tort (including negligence), contract, or otherwise,
167
+ unless required by applicable law (such as deliberate and grossly
168
+ negligent acts) or agreed to in writing, shall any Contributor be
169
+ liable to You for damages, including any direct, indirect, special,
170
+ incidental, or consequential damages of any character arising as a
171
+ result of this License or out of the use or inability to use the
172
+ Work (including but not limited to damages for loss of goodwill,
173
+ work stoppage, computer failure or malfunction, or any and all
174
+ other commercial damages or losses), even if such Contributor
175
+ has been advised of the possibility of such damages.
176
+
177
+ 9. Accepting Warranty or Additional Liability. While redistributing
178
+ the Work or Derivative Works thereof, You may choose to offer,
179
+ and charge a fee for, acceptance of support, warranty, indemnity,
180
+ or other liability obligations and/or rights consistent with this
181
+ License. However, in accepting such obligations, You may act only
182
+ on Your own behalf and on Your sole responsibility, not on behalf
183
+ of any other Contributor, and only if You agree to indemnify,
184
+ defend, and hold each Contributor harmless for any liability
185
+ incurred by, or claims asserted against, such Contributor by reason
186
+ of your accepting any such warranty or additional liability.
187
+
188
+ END OF TERMS AND CONDITIONS
package/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # **Vistta CLI**
2
+
3
+ Vistta CLI is a framework for extending the Node.js loader API and building reusable, customizable commands tools.
4
+ It enables you to create custom loaders, and define your own commands for any projects.
5
+ Compatible with either jsconfig or tsconfig json files.
6
+
7
+ ## Features
8
+
9
+ - **Custom Loaders:** Register and use your own file loaders for any extension or import attribute.
10
+ - **Custom Commands:** Create custom commands by extending the Command class or any other and wiring them into your project.
11
+
12
+ ## Getting Started
13
+
14
+ ### Installation
15
+
16
+ ```sh
17
+ npm install @vistta/cli
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ### Built-in Commands
23
+
24
+ - `vistta`
25
+ Runs the default command, which can be configured in your project's `jsconfig.json` or `tsconfig.json`.
26
+
27
+ - `vistta bundle <filename> [outdir]`
28
+ Bundle an entry file and its dependencies.
29
+
30
+ - `vistta project name`
31
+ Outputs the current project name from `package.json`.
32
+
33
+ - `vistta project version [major|minor|patch]`
34
+ Outputs the current project version. If a level (`major`, `minor`, `patch`) is provided, it increments the version accordingly.
35
+
36
+ - `vistta project outdated`
37
+ Lists all outdated dependencies in the project.
38
+
39
+ - `vistta patch [module-name]` or `vistta project patch [module-name]`
40
+ Updates the version of a specific module (or all outdated modules if none is specified) to the latest patch version in `package.json`.
41
+
42
+ - `vistta update [module-name]` or `vistta project update [module-name]`
43
+ Updates the version of a specific module (or all outdated modules if none is specified) to its latest available version in `package.json`.
44
+
45
+ - `vistta test [pattern]`
46
+ Run tests matching the specified pattern.
47
+
48
+ ## Extending the CLI
49
+
50
+ You can create custom loaders and commands to fit your workflow.
51
+
52
+ ### 1. Create a Custom Loader
53
+
54
+ ```js
55
+ // my-loader.js
56
+ import { Loader } from "vistta/cli";
57
+
58
+ export default class MyLoader extends Loader {
59
+ async load(...args) {
60
+ // Your loader logic here
61
+ }
62
+ }
63
+ ```
64
+
65
+ ### 2. Create a Custom CLI Command and Register the Loader
66
+
67
+ ```js
68
+ // my-command.js
69
+ import { Command } from "vistta/cli";
70
+
71
+ export default class MyCommand extends Command {
72
+ constructor(options) {
73
+ super(options);
74
+ // Register loaders, add resolvers, define env or global variables
75
+ // this.register(path, { type, filter });
76
+ // this.resolve("ts");
77
+ // this.define("env"/"global", key, value);
78
+ }
79
+
80
+ async help(...args) {
81
+ // Your command help logic here
82
+ }
83
+
84
+ async main(...args) {
85
+ // Your command logic here
86
+ }
87
+ }
88
+ ```
89
+
90
+ ### 3. Register Your Command in `jsconfig.json` or `tsconfig.json`
91
+
92
+ ```json
93
+ {
94
+ "extends": "@vistta/cli/config", // Optional/Recomended
95
+ "cli": {
96
+ "commands": {
97
+ "my-command": "./cli/my-command.js"
98
+ }
99
+ }
100
+ }
101
+ ```
102
+
103
+ ### 4. Run Your Custom Command
104
+
105
+ ```sh
106
+ vistta my-command [options]
107
+ ```
108
+
109
+ ## **License**
110
+
111
+ Apache 2.0 with Commons Clause
112
+
113
+ ## **Contributing**
114
+
115
+ Thank you for your interest in contributing to this project! Please ensure that any contributions respect the licensing terms specified. If you encounter any issues or have suggestions, feel free to report them. All issues will be well received and addressed to thQe best of our ability. We appreciate your support and contributions!
116
+
117
+ ### **Authors**
118
+
119
+ - [Tiago Terenas Almeida](https://github.com/tiagomta)
package/bin.js ADDED
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ import fs from "@vistta/fs";
4
+ import { fork } from "node:child_process";
5
+ import { pathToFileURL } from "node:url";
6
+ import { ENABLED_NODE_OPTIONS, importEnv, importJSON } from "./utils.js";
7
+
8
+ const dirname = import.meta.dirname;
9
+ const cwd = process.cwd();
10
+ const rootPackage = await importJSON(fs.resolve(dirname, "package.json"));
11
+ const projectPackage = await importJSON(fs.resolve(cwd, "package.json"));
12
+ const env = await importEnv(fs.resolve(cwd, ".env"));
13
+ const projectEnvKeys = Object.keys(projectPackage?.env || {});
14
+ for (let i = 0, len = projectEnvKeys.length; i < len; i++) env[projectEnvKeys[i]] = projectPackage.env[projectEnvKeys[i]];
15
+ env.NODE_ENV = "production";
16
+ env.CLI_VERSION = rootPackage.version;
17
+ env.PROJECT_PATH = cwd;
18
+ env.PROJECT_NAME = projectPackage.name;
19
+ env.PROJECT_VERSION = projectPackage.version;
20
+
21
+ const argv = [];
22
+ const execArgv = ["--import", pathToFileURL(fs.resolve(dirname, "register.js")), "--experimental-sqlite", "--title=VISTTA"];
23
+ for (let i = 2, len = process.argv.length; i < len; i++) {
24
+ const [arg, value] = process.argv[i].toLowerCase().split("=");
25
+ const nodeOption = ENABLED_NODE_OPTIONS[arg];
26
+ if (nodeOption) {
27
+ if (typeof nodeOption === "string") env[nodeOption] = value || true;
28
+ execArgv.push(arg + "=" + value);
29
+ } else if (arg === "-d" || arg === "--dev") env.NODE_ENV = "development";
30
+ else if (arg === "-h" || arg === "--help") env.NODE_HELP = true;
31
+ else if (arg === "-t" || arg === "--trace") env.NODE_TRACE = true;
32
+ else if (arg === "--debug") env.NODE_DEBUG = true;
33
+ else if (arg === "--silent") env.NODE_SILENT = true;
34
+ else if (arg === "--auto-restart") env.NODE_AUTO_RESTART = true;
35
+ else if (arg === "--crash-report") env.NODE_CRASH_REPORT = true;
36
+ else argv.push(process.argv[i]);
37
+ }
38
+ if (argv.length === 0) env.NODE_HELP = true;
39
+ if (!env.NODE_DEBUG) execArgv.unshift("--no-warnings");
40
+ start(fs.resolve(dirname, "main.js"), argv, {
41
+ env,
42
+ execArgv,
43
+ stdio: env.NODE_SILENT ? "ignore" : "inherit",
44
+ });
45
+
46
+ function start(...args) {
47
+ fork(...args).on("exit", (code) => {
48
+ if (env.NODE_AUTO_RESTART && code != 0) start(...args);
49
+ else process.exit(code);
50
+ });
51
+ }
@@ -0,0 +1,116 @@
1
+ import fs from "@vistta/fs";
2
+ import { build } from "esbuild";
3
+ import { pathToFileURL } from "node:url";
4
+ import { assign, extract } from "../utils.js";
5
+ import { Command } from "./command.js";
6
+ import { Runtime } from "./runtime.js";
7
+
8
+ export class Bundler {
9
+ #loader;
10
+ #options;
11
+
12
+ constructor(arg1) {
13
+ if (arg1 instanceof Runtime) this.#loader = arg1;
14
+ else if (arg1 instanceof Command) this.#loader = new Runtime(arg1);
15
+ else if (!arg1) this.#loader = new Runtime(process.vistta);
16
+ else throw new Error("Invalid first argument. Expected Loader or CLI instance.");
17
+ this.#options = this.#loader?.options?.bundler ?? {};
18
+ }
19
+
20
+ async run(filename, options = {}) {
21
+ const files = [];
22
+ const resources = {};
23
+ assign(options, this.#options);
24
+ const [paths, exports] = extract(options, "paths", "exports");
25
+ options.entryPoints = [exports ? "@exports" : filename];
26
+ options.bundle = true;
27
+ options.outdir ??= "dist";
28
+ options.legalComments ??= "none";
29
+ options.keepNames ??= true;
30
+ options.treeShaking ??= true;
31
+ options.define ??= {};
32
+ options.plugins = [];
33
+ options.minify ??= process.env.NODE_ENV === "production";
34
+ options.format ??= options.globalName ? "iife" : "esm";
35
+ options.target ??= "esnext";
36
+ options.define[`process`] = "undefined";
37
+ const keys = Object.keys(process.env);
38
+ for (let i = 0, len = keys.length; i < len; i++) {
39
+ if (/[():;,.\s]/.test(keys[i])) continue;
40
+ options.define[`process.env.${keys[i]}`] = JSON.stringify(process.env[keys[i]]);
41
+ }
42
+ options.plugins.unshift(
43
+ setup({
44
+ loader: this.#loader,
45
+ paths,
46
+ filename,
47
+ files,
48
+ resources,
49
+ exports,
50
+ platform: options.platform,
51
+ }),
52
+ );
53
+ const { outputFiles, errors, warnings } = await build(options);
54
+ return {
55
+ code: outputFiles?.[0]?.text ?? "",
56
+ files: Array.from(new Set(files)),
57
+ resources,
58
+ errors,
59
+ warnings,
60
+ };
61
+ }
62
+
63
+ async import(filename, options = {}) {
64
+ options.write = false;
65
+ const { code, errors, warning } = await this.run(filename, options);
66
+ if (code === "") return { errors, warning };
67
+ return await import(`data:text/javascript;base64,${Buffer.from(code).toString(`base64`)}`);
68
+ }
69
+ }
70
+
71
+ function setup({ files: bundlerFiles, resources: bundlerResources, filename, loader, paths = {}, exports, platform }) {
72
+ const filter = /.*/;
73
+ const basename = fs.basename(filename);
74
+ const dirname = fs.dirname(filename);
75
+ return {
76
+ name: "vistta",
77
+ setup: (build) => (
78
+ build.onResolve({ filter }, async ({ path, importer, resolveDir }) => {
79
+ if (path === "@exports") return { path: basename, namespace: "exports" };
80
+ if (paths[path]) return paths[path];
81
+ if (!fs.isAbsolute(importer)) importer = fs.resolve(resolveDir, importer);
82
+ const { final, builtin, file } = await loader.resolve(
83
+ path,
84
+ {
85
+ conditions: ["bundler"],
86
+ parentURL: pathToFileURL(importer).href,
87
+ },
88
+ (final, { builtin, file }) => ({ final, builtin, file }),
89
+ );
90
+ if (!builtin && file) return { path: final };
91
+ if (platform === "node") return { external: true };
92
+ if (!builtin) return {};
93
+ return { path: final, namespace: "ignore" };
94
+ }),
95
+ build.onLoad({ filter }, async ({ path, namespace, with: importAttributes = {} }) => {
96
+ if (namespace === "ignore") return { contents: "" };
97
+ if (namespace === "window") return { contents: `module.exports = window.${path};` };
98
+ if (namespace === "global") return { contents: `module.exports = global.${path};` };
99
+ if (namespace === "exports")
100
+ return {
101
+ contents: `export { ${exports} } from "./${basename}";`,
102
+ resolveDir: dirname,
103
+ };
104
+ importAttributes.bundler = true;
105
+ const { source, resources, files = [] } = await loader.load(path, { importAttributes }, () => ({}));
106
+ bundlerFiles.push(...files);
107
+ if (!source) return { loader: "js" };
108
+ for (let i = 0, len = resources?.length || 0; i < len; i++) {
109
+ const { hash, path, code, compiler } = resources[i];
110
+ bundlerResources[hash] = path || code || compiler;
111
+ }
112
+ return { contents: source, loader: "js" };
113
+ })
114
+ ),
115
+ };
116
+ }