create-windowless-app 11.0.0-beta.0 → 11.0.0

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/README.md CHANGED
@@ -13,7 +13,7 @@
13
13
  ![visitors](https://visitor-badge.glitch.me/badge?page_id=yoavain.create-windowless-app)
14
14
  ![Downloads](https://img.shields.io/npm/dm/create-windowless-app.svg)
15
15
 
16
- Create a windowless NodeJS app.
16
+ Create a windowless Node.js app.
17
17
 
18
18
  You can also start from this template repository [create-windowless-app-template](https://github.com/yoavain/create-windowless-app-template)
19
19
 
@@ -22,8 +22,9 @@ If something doesn't work, please [file an issue](https://github.com/yoavain/cre
22
22
 
23
23
 
24
24
  Pre-Requisites for template to work:
25
- * `NodeJS` version `14.17.0` or higher
25
+ * `NodeJS` version `20.0.0` or higher
26
26
  * `MSBuild.exe` must be in the PATH environment variable
27
+ * `signtool` must be in the PATH environment variable
27
28
 
28
29
  ## Quick Overview
29
30
 
@@ -69,6 +70,7 @@ create-windowless-app creates the following files:
69
70
  my-app
70
71
  ├── node_modules
71
72
  ├── package.json
73
+ ├── sea-config.json
72
74
  ├── tsconfig.json
73
75
  ├── tsconfig.build.json
74
76
  ├── webpack.config.js
@@ -97,7 +99,7 @@ Then you can find in your my-app\dist folder the following files:
97
99
  <img src='https://raw.githubusercontent.com/yoavain/create-windowless-app/main/resources/docs/dist.png' width='157' alt='dist files'>
98
100
  </p>
99
101
 
100
- * *my-app.exe* is the compiled app, with NodeJS bundled (using [Single Executable Applications](https://nodejs.org/api/single-executable-applications.html))
102
+ * *my-app.exe* is the compiled app, with Node.js bundled (using [Single Executable Applications](https://nodejs.org/api/single-executable-applications.html))
101
103
  * *my-app-launcher.exe* is the compiled launcher.cs file that executes my-app.exe without a console window
102
104
  * *snoretoast-x64.exe* allows windows notification (using [node-notifier](https://github.com/mikaelbr/node-notifier))
103
105
  * *my-app.log* will be generated on first run (using [winston logger](https://github.com/winstonjs/winston))
@@ -110,7 +112,6 @@ create-windowless-app <project-directory> [options]
110
112
  Options:
111
113
  --no-typescript use javascript rather than typescript
112
114
  --no-husky do not install husky pre-commit hook for building launcher
113
- --skip-install writes dependencies to package.json without installing them
114
115
  --icon <icon> override default launcher icon file
115
116
 
116
117
  --interactive interactive mode
@@ -120,12 +121,12 @@ Only <project-directory> is required.
120
121
 
121
122
  ## Why?
122
123
 
123
- NodeJS does not have a native windowless mode (like java has javaw).
124
+ Node.js does not have a native windowless mode (like java has javaw).
124
125
  Sometimes, you want to run an app as a scheduled task that runs in the background, or run a long task (i.e. a server) but do not want a console that must always be open.
125
- Best solution I could find is using a script that executes the NodeJS in windowless mode
126
+ Best solution I could find is using a script that executes the Node.js in windowless mode
126
127
 
127
128
  This package comes to do the following:
128
- 1) Compile a NodeJS (javascript/typescript) project into an *.exe file bundled with NodeJS, so no installation is needed
129
+ 1) Compile a Node.js (javascript/typescript) project into an *.exe file bundled with Node.js, so no installation is needed
129
130
  2) Compile a C# launcher that executes the compiled project, in windowless mode
130
131
 
131
132
  ## Template project
@@ -137,5 +138,5 @@ The "Hello World" template is a POC containing 2 features you might want when ru
137
138
  The template project build script does the following things
138
139
  1) Compiles TypeScript to JavaScript (if in a TypeScript template)
139
140
  2) Runs WebPack to bundle all JavaScript into a single file, and copy binary files into the "dist" folder
140
- 3) Runs Node's single executable applications scripts to compile the single WebPack JavaScript output file to an exe file bundled with NodeJS (Currently experimental in NodeJS 20)
141
+ 3) Runs Node's single executable applications scripts to compile the single WebPack JavaScript output file to an exe file bundled with Node.js (Currently experimental in Node.js 20)
141
142
 
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkNodeRuntimeVersion = void 0;
4
+ const MIN_MAJOR_VERSION = 20;
5
+ const MIN_MINOR_VERSION = 0;
6
+ const checkNodeRuntimeVersion = () => {
7
+ const currentNodeVersion = process.versions.node;
8
+ const semver = currentNodeVersion.split(".");
9
+ const major = Number(semver[0]);
10
+ const minor = Number(semver[1]);
11
+ if (Number.isNaN(major) || Number.isNaN(minor) || major < MIN_MAJOR_VERSION || (major === MIN_MAJOR_VERSION && minor < MIN_MINOR_VERSION)) {
12
+ console.error(`You are running NodeJS ${currentNodeVersion}.\nCreate Windowless App requires NodeJS ${MIN_MAJOR_VERSION}.${MIN_MINOR_VERSION} or higher.\nPlease update your version of Node.`);
13
+ process.exit(1);
14
+ }
15
+ };
16
+ exports.checkNodeRuntimeVersion = checkNodeRuntimeVersion;
package/dist/cliParser.js CHANGED
@@ -20,10 +20,11 @@ const yargs_1 = __importDefault(require("yargs"));
20
20
  const helpers_1 = require("yargs/helpers");
21
21
  const interactive_1 = require("./interactive");
22
22
  const validation_1 = require("./validation");
23
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
23
24
  const packageJson = require(`../${createWindowlessAppUtils_1.PACKAGE_JSON_FILENAME}`);
24
25
  const validateInput = (argv) => {
25
26
  if (argv.icon && !(0, fs_extra_1.pathExistsSync)(argv.icon)) {
26
- console.log(`Cannot find icon in ${chalk_1.default.red(argv.icon)}. Switching to ${chalk_1.default.green("default")} icon.`);
27
+ console.warn(`Cannot find icon in ${chalk_1.default.red(argv.icon)}. Switching to ${chalk_1.default.green("default")} icon.`);
27
28
  delete argv.icon;
28
29
  }
29
30
  return argv;
@@ -57,11 +58,6 @@ const parseCommand = (argv) => __awaiter(void 0, void 0, void 0, function* () {
57
58
  type: "boolean",
58
59
  description: "install husky pre-commit hook for building launcher",
59
60
  default: true
60
- })
61
- .option("skip-install", {
62
- alias: "s",
63
- type: "boolean",
64
- description: "write dependencies to package.json without installing"
65
61
  })
66
62
  .option("icon", {
67
63
  alias: "c",
@@ -92,7 +88,6 @@ const parseCommand = (argv) => __awaiter(void 0, void 0, void 0, function* () {
92
88
  verbose: command.verbose,
93
89
  typescript: command.typescript,
94
90
  husky: command.husky,
95
- skipInstall: command["skip-install"],
96
91
  icon: command.icon
97
92
  };
98
93
  }
@@ -35,152 +35,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
35
35
  return (mod && mod.__esModule) ? mod : { "default": mod };
36
36
  };
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.createWindowlessApp = exports.buildLauncher = void 0;
38
+ exports.createWindowlessApp = void 0;
39
39
  const chalk_1 = __importDefault(require("chalk"));
40
40
  const path = __importStar(require("path"));
41
41
  const fs_extra_1 = require("fs-extra");
42
- const cross_spawn_1 = __importDefault(require("cross-spawn"));
43
42
  const launcherCompiler_1 = require("./launcherCompiler");
44
43
  const consts_1 = require("./consts");
45
44
  const createWindowlessAppUtils_1 = require("./createWindowlessAppUtils");
46
- const fileUtils_1 = require("./fileUtils");
47
45
  const nodeUtils_1 = require("./nodeUtils");
48
46
  const cliParser_1 = require("./cliParser");
49
- // TypeScript
50
- const tsWebpackConfigResourceLocation = "../templates/typescript/webpack.config.ts";
51
- const tsConfigBuildResourceLocation = "../templates/typescript/tsconfig.build.json";
52
- const tsConfigResourceLocation = "../templates/typescript/tsconfig.json";
53
- const tsIndexResourceLocation = "../templates/typescript/src/index.ts";
54
- const tsLauncherCompilerLocation = "../templates/typescript/launcher/launcherCompiler.ts";
55
- // JavaScript
56
- const jsWebpackConfigResourceLocation = "../templates/javascript/webpack.config.js";
57
- const jsIndexResourceLocation = "../templates/javascript/src/index.js";
58
- const jsLauncherCompilerLocation = "../templates/javascript/launcher/launcherCompiler.js";
59
- // Launcher Source
60
- const launcherSrcResourceLocation = "../templates/common/src/launcher.cs";
61
- const launcherSrcModifiedLocation = "launcher/launcher.cs";
62
- const launcherProjResourceLocation = "../templates/common/launcher.csproj";
63
- const launcherProjModifiedLocation = "launcher/launcher.csproj";
64
- // Single executable applications config
65
- const seaConfigResourceLocation = "../templates/common/sea-config.json";
66
- // Default icon location
67
- const defaultLauncherIconLocation = "../templates/common/resources/windows-launcher.ico";
68
- // Husky config file
69
- const huskyConfigFileLocation = "../templates/common/husky/pre-commit";
70
- const install = (root, dependencies, isDev, programConfig) => __awaiter(void 0, void 0, void 0, function* () {
71
- const { verbose, skipInstall } = programConfig;
72
- if (!skipInstall) {
73
- const command = "npm";
74
- const args = ["install", isDev ? "--save-dev" : "--save", "--save-exact", "--loglevel", "error"].concat(dependencies);
75
- if (verbose) {
76
- args.push("--verbose");
77
- }
78
- console.log(`Installing ${chalk_1.default.green(isDev ? "dev dependencies" : "dependencies")}.`);
79
- console.log();
80
- cross_spawn_1.default.sync(command, args, { stdio: "inherit" });
81
- }
82
- else {
83
- console.log(`Adding ${chalk_1.default.green(isDev ? "dev dependencies" : "dependencies")} to package.json (skipping installation)`);
84
- console.log();
85
- const dependenciesObject = dependencies.reduce((acc, dep) => {
86
- var _a, _b, _c;
87
- let depName = dep;
88
- let depVersion = "^x.x.x";
89
- if (dep.lastIndexOf("@") > 0) {
90
- depName = dep.substring(0, dep.lastIndexOf("@"));
91
- const depVersionString = dep.substring(dep.lastIndexOf("@")).split(".");
92
- depVersion = `^${(_a = depVersionString === null || depVersionString === void 0 ? void 0 : depVersionString[0]) !== null && _a !== void 0 ? _a : "x"}.${(_b = depVersionString === null || depVersionString === void 0 ? void 0 : depVersionString[1]) !== null && _b !== void 0 ? _b : "x"}.${(_c = depVersionString === null || depVersionString === void 0 ? void 0 : depVersionString[2]) !== null && _c !== void 0 ? _c : "x"}`;
93
- }
94
- acc[depName] = depVersion;
95
- return acc;
96
- }, {});
97
- (0, createWindowlessAppUtils_1.mergeIntoPackageJson)(root, isDev ? "devDependencies" : "dependencies", dependenciesObject);
98
- }
99
- });
100
- const buildTypeScriptProject = (root, appName, husky) => {
101
- console.log(`Building project ${chalk_1.default.green("files")}.`);
102
- console.log();
103
- (0, fileUtils_1.writeJson)(path.resolve(root, "tsconfig.build.json"), (0, fileUtils_1.readJsonResource)(tsConfigBuildResourceLocation));
104
- (0, fileUtils_1.writeJson)(path.resolve(root, "tsconfig.json"), (0, fileUtils_1.readJsonResource)(tsConfigResourceLocation));
105
- (0, fileUtils_1.writeFile)(path.resolve(root, "webpack.config.ts"), (0, createWindowlessAppUtils_1.replaceAppNamePlaceholder)((0, fileUtils_1.readResource)(tsWebpackConfigResourceLocation), appName));
106
- (0, fs_extra_1.ensureDirSync)(path.resolve(root, "src"));
107
- (0, fileUtils_1.writeFile)(path.resolve(root, "src", "index.ts"), (0, createWindowlessAppUtils_1.replaceAppNamePlaceholder)((0, fileUtils_1.readResource)(tsIndexResourceLocation), appName));
108
- // Add scripts
109
- const scripts = Object.assign(Object.assign({ "start": "ts-node src/index.ts", "type-check": "tsc --build tsconfig.json", "prewebpack": "rimraf build && rimraf dist", "webpack": "webpack" }, (0, createWindowlessAppUtils_1.getSingleExecutableApplicationsScripts)(appName)), { "build": "npm run type-check && npm run webpack && npm run node-sea", "check-msbuild": "ts-node -e \"require(\"\"./launcher/launcherCompiler\"\").checkMsbuildInPath(true)\"", "rebuild-launcher": "msbuild launcher/launcher.csproj" });
110
- // Add husky
111
- if (husky) {
112
- scripts["prepare"] = "git config --get core.hookspath || husky install";
113
- scripts["pre-commit"] = `git diff HEAD --exit-code --stat launcher/* || npm run check-msbuild && npm run rebuild-launcher && git add resources/bin/${appName}-launcher.exe`;
114
- (0, fs_extra_1.ensureDirSync)(path.resolve(root, ".husky"));
115
- (0, fileUtils_1.writeFile)(path.resolve(root, ".husky", "pre-commit"), (0, fileUtils_1.readResource)(huskyConfigFileLocation));
116
- }
117
- (0, createWindowlessAppUtils_1.mergeIntoPackageJson)(root, "scripts", scripts);
118
- };
119
- const buildJavaScriptProject = (root, appName, husky) => {
120
- console.log(`Building project ${chalk_1.default.green("files")}.`);
121
- console.log();
122
- (0, fileUtils_1.writeFile)(path.resolve(root, "webpack.config.js"), (0, createWindowlessAppUtils_1.replaceAppNamePlaceholder)((0, fileUtils_1.readResource)(jsWebpackConfigResourceLocation), appName));
123
- (0, fs_extra_1.ensureDirSync)(path.resolve(root, "src"));
124
- (0, fileUtils_1.writeFile)(path.resolve(root, "src", "index.js"), (0, createWindowlessAppUtils_1.replaceAppNamePlaceholder)((0, fileUtils_1.readResource)(jsIndexResourceLocation), appName));
125
- // Add scripts
126
- const scripts = Object.assign(Object.assign({ "start": "node src/index.js", "prewebpack": "rimraf build && rimraf dist", "webpack": "webpack" }, (0, createWindowlessAppUtils_1.getSingleExecutableApplicationsScripts)(appName)), { "build": "npm run webpack && npm run node-sea", "check-msbuild": "node -e \"require(\"\"./launcher/launcherCompiler\"\").checkMsbuildInPath(true)\"", "rebuild-launcher": "msbuild launcher/launcher.csproj" });
127
- // Add husky
128
- if (husky) {
129
- scripts["prepare"] = "git config --get core.hookspath || husky install";
130
- scripts["pre-commit"] = `git diff HEAD --exit-code --stat launcher/* || npm run check-msbuild && npm run rebuild-launcher && git add resources/bin/${appName}-launcher.exe`;
131
- (0, fs_extra_1.ensureDirSync)(path.resolve(root, ".husky"));
132
- (0, fileUtils_1.writeFile)(path.resolve(root, ".husky", "pre-commit"), (0, fileUtils_1.readResource)(huskyConfigFileLocation));
133
- }
134
- (0, createWindowlessAppUtils_1.mergeIntoPackageJson)(root, "scripts", scripts);
135
- };
136
- const buildLauncher = (root, appName, icon, typescript) => {
137
- console.log(`Building project ${chalk_1.default.green("launcher")}.`);
138
- console.log();
139
- (0, fs_extra_1.ensureDirSync)(path.resolve("launcher"));
140
- (0, fileUtils_1.writeFile)(path.resolve(launcherSrcModifiedLocation), (0, createWindowlessAppUtils_1.replaceAppNamePlaceholder)((0, fileUtils_1.readResource)(launcherSrcResourceLocation), appName));
141
- (0, fileUtils_1.writeFile)(path.resolve(launcherProjModifiedLocation), (0, createWindowlessAppUtils_1.replaceAppNamePlaceholder)((0, fileUtils_1.readResource)(launcherProjResourceLocation), appName));
142
- if (typescript) {
143
- (0, fileUtils_1.copyFile)(path.resolve(__dirname, tsLauncherCompilerLocation), path.resolve(root, "launcher", "launcherCompiler.ts"));
144
- }
145
- else {
146
- (0, fileUtils_1.copyFile)(path.resolve(__dirname, jsLauncherCompilerLocation), path.resolve(root, "launcher", "launcherCompiler.js"));
147
- }
148
- // Resolve icon
149
- let iconLocation;
150
- if (icon) {
151
- iconLocation = path.resolve(icon);
152
- console.log(`Building launcher with icon: ${chalk_1.default.green(icon)}.`);
153
- }
154
- else {
155
- iconLocation = path.resolve(__dirname, defaultLauncherIconLocation);
156
- console.log(`Building launcher with ${chalk_1.default.green("default")} icon.`);
157
- }
158
- (0, fileUtils_1.copyFile)(iconLocation, path.resolve(root, "launcher", "launcher.ico"));
159
- return (0, launcherCompiler_1.compileLauncher)();
160
- };
161
- exports.buildLauncher = buildLauncher;
47
+ const packageJson_1 = require("./packageJson");
48
+ const dependencies_1 = require("./dependencies");
49
+ const files_1 = require("./files");
162
50
  const run = (root, appName, originalDirectory, programConfig) => __awaiter(void 0, void 0, void 0, function* () {
163
- const { typescript, husky, icon } = programConfig;
164
- const dependencies = [...consts_1.consts.dependencies];
165
- const devDependencies = [...consts_1.consts.devDependencies];
166
- if (typescript) {
167
- devDependencies.push(...consts_1.consts.tsDevDependencies);
168
- }
169
- if (husky) {
170
- devDependencies.push(...consts_1.consts.huskyDependencies);
171
- }
51
+ const { typescript, husky, icon, verbose } = programConfig;
172
52
  try {
173
- yield install(root, dependencies, false, programConfig);
174
- yield install(root, devDependencies, true, programConfig);
175
- if (typescript) {
176
- buildTypeScriptProject(root, appName, husky);
177
- }
178
- else {
179
- buildJavaScriptProject(root, appName, husky);
180
- }
53
+ const dependenciesManager = new dependencies_1.DependenciesManager(typescript, husky);
54
+ yield dependenciesManager.installAll(verbose);
55
+ const fileManager = new files_1.FileManager(root, appName, typescript, husky, icon);
56
+ yield fileManager.copyTemplate();
181
57
  // Launcher
182
58
  (0, fs_extra_1.ensureDirSync)(path.resolve(root, "resources", "bin"));
183
- yield (0, exports.buildLauncher)(root, appName, icon, typescript);
59
+ yield (0, launcherCompiler_1.compileLauncher)();
184
60
  console.log("Done");
185
61
  }
186
62
  catch (reason) {
@@ -217,8 +93,8 @@ const run = (root, appName, originalDirectory, programConfig) => __awaiter(void
217
93
  process.exit(1);
218
94
  }
219
95
  });
220
- const createApp = (programConfig) => {
221
- const { projectName } = programConfig;
96
+ const createApp = (programConfig) => __awaiter(void 0, void 0, void 0, function* () {
97
+ const { projectName, typescript, husky } = programConfig;
222
98
  const root = path.resolve(projectName);
223
99
  const appName = path.basename(root);
224
100
  (0, createWindowlessAppUtils_1.checkAppName)(appName);
@@ -228,21 +104,28 @@ const createApp = (programConfig) => {
228
104
  }
229
105
  console.log(`Creating a new windowless app in ${chalk_1.default.green(root)}.`);
230
106
  console.log();
231
- const packageJson = {
232
- name: appName,
233
- version: "0.1.0",
234
- private: true,
235
- main: "_build/index.js"
236
- };
237
- (0, fileUtils_1.writeJson)(path.join(root, "package.json"), packageJson);
238
- (0, fileUtils_1.copyFile)(path.resolve(__dirname, seaConfigResourceLocation), path.resolve(root, "sea-config.json"));
239
107
  const originalDirectory = process.cwd();
240
108
  process.chdir(root);
241
109
  if (!(0, nodeUtils_1.checkThatNpmCanReadCwd)()) {
110
+ process.chdir(originalDirectory);
242
111
  process.exit(1);
243
112
  }
244
- return run(root, appName, originalDirectory, programConfig);
245
- };
113
+ try {
114
+ // package.json
115
+ const packageJson = new packageJson_1.PackageJsonBuilder(appName);
116
+ if (!typescript) {
117
+ packageJson.withJavaScript();
118
+ }
119
+ if (husky) {
120
+ packageJson.withHusky();
121
+ }
122
+ (0, files_1.writeJson)(path.join(root, "package.json"), packageJson.build());
123
+ yield run(root, appName, originalDirectory, programConfig);
124
+ }
125
+ finally {
126
+ process.chdir(originalDirectory);
127
+ }
128
+ });
246
129
  const createWindowlessApp = (argv) => __awaiter(void 0, void 0, void 0, function* () {
247
130
  const programConfig = yield (0, cliParser_1.parseCommand)(argv);
248
131
  if (programConfig.projectName) {
@@ -3,11 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.replaceAppNamePlaceholder = exports.mergeIntoPackageJson = exports.getSingleExecutableApplicationsScripts = exports.checkAppName = exports.isSafeToCreateProjectIn = exports.PACKAGE_JSON_FILENAME = void 0;
6
+ exports.replaceAppNamePlaceholder = exports.checkAppName = exports.isSafeToCreateProjectIn = exports.PACKAGE_JSON_FILENAME = void 0;
7
7
  const validate_npm_package_name_1 = __importDefault(require("validate-npm-package-name"));
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
9
  const path_1 = __importDefault(require("path"));
10
- const fileUtils_1 = require("./fileUtils");
11
10
  const consts_1 = require("./consts");
12
11
  const fs_extra_1 = require("fs-extra");
13
12
  // These files should be allowed to remain on a failed install, but then silently removed during the next create.
@@ -73,35 +72,7 @@ const checkAppName = (appName) => {
73
72
  }
74
73
  };
75
74
  exports.checkAppName = checkAppName;
76
- const getSingleExecutableApplicationsScripts = (appName) => {
77
- return {
78
- "prenode-sea:build-blob": "rimraf _blob && mkdir _blob",
79
- "node-sea:build-blob": "node --experimental-sea-config sea-config.json",
80
- "node-sea:copy-node": `node -e "require('fs').copyFileSync(process.execPath, 'dist/${appName}.exe')"`,
81
- "node-sea:unsign": `signtool remove /s dist/${appName}.exe`,
82
- "node-sea:inject-blob": `postject dist/${appName}.exe NODE_SEA_BLOB _blob\\sea-prep.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2`,
83
- "node-sea:sign": `signtool sign /fd SHA256 dist/${appName}.exe`,
84
- "node-sea": "npm run node-sea:build-blob && npm run node-sea:copy-node && npm run node-sea:unsign && npm run node-sea:inject-blob"
85
- };
86
- };
87
- exports.getSingleExecutableApplicationsScripts = getSingleExecutableApplicationsScripts;
88
- const mergeIntoPackageJson = (root, field, data) => {
89
- const packageJsonPath = path_1.default.resolve(root, exports.PACKAGE_JSON_FILENAME);
90
- const packageJson = (0, fileUtils_1.readJsonFile)(packageJsonPath);
91
- if (Array.isArray(data)) {
92
- const list = (packageJson[field] || []).concat(data).reduce((acc, cur) => {
93
- acc[cur] = cur;
94
- return acc;
95
- }, {});
96
- packageJson[field] = Object.keys(list);
97
- }
98
- else {
99
- packageJson[field] = Object.assign(packageJson[field] || {}, data);
100
- }
101
- (0, fileUtils_1.writeJson)(packageJsonPath, packageJson);
102
- };
103
- exports.mergeIntoPackageJson = mergeIntoPackageJson;
104
- const replaceAppNamePlaceholder = (str, appName) => {
75
+ const replaceAppNamePlaceholder = (appName, str) => {
105
76
  return str.replace(/##APPNAME##/g, `${appName}`);
106
77
  };
107
78
  exports.replaceAppNamePlaceholder = replaceAppNamePlaceholder;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
12
+ if (kind === "m") throw new TypeError("Private method is not writable");
13
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
14
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
15
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
16
+ };
17
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
18
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
19
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
20
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
21
+ };
22
+ var __importDefault = (this && this.__importDefault) || function (mod) {
23
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
+ };
25
+ var _DependenciesManager_dependencies, _DependenciesManager_devDependencies;
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.DependenciesManager = void 0;
28
+ const chalk_1 = __importDefault(require("chalk"));
29
+ const cross_spawn_1 = __importDefault(require("cross-spawn"));
30
+ const dependencies = [
31
+ "node-notifier",
32
+ "winston"
33
+ ];
34
+ const devDependencies = [
35
+ "fs-extra",
36
+ "jest",
37
+ "webpack",
38
+ "webpack-cli",
39
+ "copy-webpack-plugin",
40
+ "rimraf",
41
+ "cross-spawn",
42
+ "postject"
43
+ ];
44
+ const tsDevDependencies = [
45
+ "@types/jest",
46
+ "@types/node",
47
+ "@tsconfig/node20",
48
+ "@types/node-notifier",
49
+ "@types/winston",
50
+ "ts-loader",
51
+ "ts-node",
52
+ "typescript",
53
+ "@types/cross-spawn"
54
+ ];
55
+ const huskyDependencies = [
56
+ "husky"
57
+ ];
58
+ const install = (dependencies, isDev, verbose) => __awaiter(void 0, void 0, void 0, function* () {
59
+ const command = "npm";
60
+ const args = ["install", isDev ? "--save-dev" : "--save", "--save-exact", "--loglevel", "error"].concat(dependencies);
61
+ if (verbose) {
62
+ args.push("--verbose");
63
+ }
64
+ console.log(`Installing ${chalk_1.default.green(isDev ? "dev dependencies" : "dependencies")}.`);
65
+ console.log();
66
+ cross_spawn_1.default.sync(command, args, { stdio: "inherit" });
67
+ });
68
+ class DependenciesManager {
69
+ constructor(typescript, husky) {
70
+ _DependenciesManager_dependencies.set(this, []);
71
+ _DependenciesManager_devDependencies.set(this, []);
72
+ __classPrivateFieldSet(this, _DependenciesManager_dependencies, dependencies, "f");
73
+ __classPrivateFieldSet(this, _DependenciesManager_devDependencies, devDependencies, "f");
74
+ if (typescript) {
75
+ __classPrivateFieldSet(this, _DependenciesManager_devDependencies, __classPrivateFieldGet(this, _DependenciesManager_devDependencies, "f").concat(tsDevDependencies), "f");
76
+ }
77
+ if (husky) {
78
+ __classPrivateFieldSet(this, _DependenciesManager_devDependencies, __classPrivateFieldGet(this, _DependenciesManager_devDependencies, "f").concat(huskyDependencies), "f");
79
+ }
80
+ }
81
+ installAll(verbose) {
82
+ return __awaiter(this, void 0, void 0, function* () {
83
+ yield install(__classPrivateFieldGet(this, _DependenciesManager_dependencies, "f"), false, verbose);
84
+ yield install(__classPrivateFieldGet(this, _DependenciesManager_devDependencies, "f"), true, verbose);
85
+ });
86
+ }
87
+ }
88
+ exports.DependenciesManager = DependenciesManager;
89
+ _DependenciesManager_dependencies = new WeakMap(), _DependenciesManager_devDependencies = new WeakMap();
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./dependenciesManager"), exports);
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
12
+ if (kind === "m") throw new TypeError("Private method is not writable");
13
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
14
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
15
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
16
+ };
17
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
18
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
19
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
20
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
21
+ };
22
+ var __importDefault = (this && this.__importDefault) || function (mod) {
23
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
+ };
25
+ var _FileManager_templatesRoot, _FileManager_targetRoot, _FileManager_typeScript, _FileManager_husky, _FileManager_icon, _FileManager_formatter;
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.FileManager = void 0;
28
+ const _1 = require(".");
29
+ const createWindowlessAppUtils_1 = require("../createWindowlessAppUtils");
30
+ const fs_extra_1 = require("fs-extra");
31
+ const path_1 = __importDefault(require("path"));
32
+ class FileManager {
33
+ constructor(targetRoot, appName, typeScript, husky, icon) {
34
+ _FileManager_templatesRoot.set(this, void 0);
35
+ _FileManager_targetRoot.set(this, void 0);
36
+ _FileManager_typeScript.set(this, void 0);
37
+ _FileManager_husky.set(this, void 0);
38
+ _FileManager_icon.set(this, void 0);
39
+ _FileManager_formatter.set(this, void 0);
40
+ __classPrivateFieldSet(this, _FileManager_templatesRoot, path_1.default.resolve(__dirname, "..", "..", "templates"), "f");
41
+ __classPrivateFieldSet(this, _FileManager_targetRoot, targetRoot, "f");
42
+ __classPrivateFieldSet(this, _FileManager_typeScript, typeScript, "f");
43
+ __classPrivateFieldSet(this, _FileManager_husky, husky, "f");
44
+ __classPrivateFieldSet(this, _FileManager_icon, icon, "f");
45
+ __classPrivateFieldSet(this, _FileManager_formatter, (str) => (0, createWindowlessAppUtils_1.replaceAppNamePlaceholder)(appName, str), "f");
46
+ }
47
+ copyTemplate() {
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ // common files
50
+ (0, _1.copyFolderRecursiveSync)(path_1.default.resolve(__classPrivateFieldGet(this, _FileManager_templatesRoot, "f"), "common"), path_1.default.resolve(__classPrivateFieldGet(this, _FileManager_targetRoot, "f")), __classPrivateFieldGet(this, _FileManager_formatter, "f"));
51
+ // TypeScript or JavaScript
52
+ if (__classPrivateFieldGet(this, _FileManager_typeScript, "f")) {
53
+ (0, _1.copyFolderRecursiveSync)(path_1.default.resolve(__classPrivateFieldGet(this, _FileManager_templatesRoot, "f"), "typescript"), path_1.default.resolve(__classPrivateFieldGet(this, _FileManager_targetRoot, "f")), __classPrivateFieldGet(this, _FileManager_formatter, "f"));
54
+ }
55
+ else {
56
+ (0, _1.copyFolderRecursiveSync)(path_1.default.resolve(__classPrivateFieldGet(this, _FileManager_templatesRoot, "f"), "javascript"), path_1.default.resolve(__classPrivateFieldGet(this, _FileManager_targetRoot, "f")), __classPrivateFieldGet(this, _FileManager_formatter, "f"));
57
+ }
58
+ // Husky
59
+ if (__classPrivateFieldGet(this, _FileManager_husky, "f")) {
60
+ (0, _1.copyFolderRecursiveSync)(path_1.default.resolve(__classPrivateFieldGet(this, _FileManager_templatesRoot, "f"), ".husky"), path_1.default.resolve(__classPrivateFieldGet(this, _FileManager_targetRoot, "f"), ".husky"), __classPrivateFieldGet(this, _FileManager_formatter, "f"));
61
+ }
62
+ // Launcher
63
+ (0, _1.copyFolderRecursiveSync)(path_1.default.resolve(__classPrivateFieldGet(this, _FileManager_templatesRoot, "f"), "launcher"), path_1.default.resolve(__classPrivateFieldGet(this, _FileManager_targetRoot, "f"), "launcher"), __classPrivateFieldGet(this, _FileManager_formatter, "f"));
64
+ // Icon
65
+ if (__classPrivateFieldGet(this, _FileManager_icon, "f")) {
66
+ (0, fs_extra_1.copyFileSync)(path_1.default.resolve(__classPrivateFieldGet(this, _FileManager_icon, "f")), path_1.default.resolve(__classPrivateFieldGet(this, _FileManager_targetRoot, "f"), "launcher", "launcher.ico"));
67
+ }
68
+ });
69
+ }
70
+ }
71
+ exports.FileManager = FileManager;
72
+ _FileManager_templatesRoot = new WeakMap(), _FileManager_targetRoot = new WeakMap(), _FileManager_typeScript = new WeakMap(), _FileManager_husky = new WeakMap(), _FileManager_icon = new WeakMap(), _FileManager_formatter = new WeakMap();
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.copyFolderRecursiveSync = exports.writeJson = void 0;
7
+ const fs_extra_1 = require("fs-extra");
8
+ const path_1 = __importDefault(require("path"));
9
+ const os_1 = __importDefault(require("os"));
10
+ const writeJson = (fileName, json) => {
11
+ (0, fs_extra_1.writeFileSync)(fileName, JSON.stringify(json, null, 2).replace(/\n/g, os_1.default.EOL) + os_1.default.EOL);
12
+ };
13
+ exports.writeJson = writeJson;
14
+ const TEXT_FORMAT_EXTENSIONS = new Set([".ts", ".js", ".cs", ".json", ".csproj"]);
15
+ function copyFileSyncWithFormatter(sourceFile, targetFile, formatter) {
16
+ console.log(`copyFileSyncWithFormatter from ${sourceFile} to ${targetFile}`);
17
+ if ((0, fs_extra_1.existsSync)(targetFile)) {
18
+ throw new Error(`Target file already exists: ${targetFile}`);
19
+ }
20
+ const ext = path_1.default.extname(sourceFile);
21
+ if (typeof formatter === "function" && TEXT_FORMAT_EXTENSIONS.has(ext.toLowerCase())) {
22
+ console.log(`modifying ${sourceFile}`);
23
+ const data = (0, fs_extra_1.readFileSync)(sourceFile, { encoding: "utf8" });
24
+ (0, fs_extra_1.writeFileSync)(targetFile, formatter(data), { encoding: "utf8" });
25
+ }
26
+ else {
27
+ const data = (0, fs_extra_1.readFileSync)(sourceFile);
28
+ (0, fs_extra_1.writeFileSync)(targetFile, data);
29
+ }
30
+ }
31
+ const copyFolderRecursiveSync = (sourceFolder, targetFolder, formatter) => {
32
+ console.log(`copyFolderRecursiveSync from ${sourceFolder} to ${targetFolder}`);
33
+ if (!(0, fs_extra_1.existsSync)(targetFolder)) {
34
+ console.log(`mkdir ${targetFolder}`);
35
+ (0, fs_extra_1.mkdirSync)(targetFolder);
36
+ }
37
+ else if (!(0, fs_extra_1.lstatSync)(targetFolder).isDirectory()) {
38
+ throw new Error("Target exists and is not a directory.");
39
+ }
40
+ // Copy
41
+ if ((0, fs_extra_1.lstatSync)(sourceFolder).isDirectory()) {
42
+ (0, fs_extra_1.readdirSync)(sourceFolder).forEach((child) => {
43
+ const curSource = path_1.default.join(sourceFolder, child);
44
+ const curTarget = path_1.default.join(targetFolder, child);
45
+ if ((0, fs_extra_1.lstatSync)(curSource).isDirectory()) {
46
+ (0, exports.copyFolderRecursiveSync)(curSource, curTarget, formatter);
47
+ }
48
+ else {
49
+ copyFileSyncWithFormatter(curSource, curTarget, formatter);
50
+ }
51
+ });
52
+ }
53
+ };
54
+ exports.copyFolderRecursiveSync = copyFolderRecursiveSync;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./fileManager"), exports);
18
+ __exportStar(require("./fileUtils"), exports);
@@ -31,12 +31,6 @@ const interactiveMode = () => {
31
31
  name: "husky",
32
32
  default: true
33
33
  },
34
- {
35
- type: "confirm",
36
- message: "Skip NPM Install:",
37
- name: "skipInstall",
38
- default: false
39
- },
40
34
  {
41
35
  type: "confirm",
42
36
  message: "Verbose:",
package/dist/main.js CHANGED
@@ -10,17 +10,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.main = void 0;
13
+ const checkNodeVersion_1 = require("./checkNodeVersion");
13
14
  const launcherCompiler_1 = require("./launcherCompiler");
14
15
  const createWindowlessApp_1 = require("./createWindowlessApp");
15
16
  const main = () => __awaiter(void 0, void 0, void 0, function* () {
16
- const currentNodeVersion = process.versions.node;
17
- const semver = currentNodeVersion.split(".");
18
- const major = Number(semver[0]);
19
- const minor = Number(semver[1]);
20
- if (Number.isNaN(major) || Number.isNaN(minor) || major < 12 || (major === 12 && minor < 20)) {
21
- console.error(`You are running NodeJS ${currentNodeVersion}.\nCreate Windowless App requires NodeJS 12.20 or higher.\nPlease update your version of Node.`);
22
- process.exit(1);
23
- }
17
+ // check minimum node version
18
+ (0, checkNodeVersion_1.checkNodeRuntimeVersion)();
24
19
  // Check for msbuild.exe in %PATH%
25
20
  yield (0, launcherCompiler_1.checkMsbuildInPath)(true);
26
21
  yield (0, createWindowlessApp_1.createWindowlessApp)(process.argv);
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./packageJsonBuilder"), exports);
18
+ __exportStar(require("./packageJsonConsts"), exports);
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _PackageJsonBuilder_appName, _PackageJsonBuilder_typescript, _PackageJsonBuilder_husky;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.PackageJsonBuilder = void 0;
16
+ const packageJsonConsts_1 = require("./packageJsonConsts");
17
+ class PackageJsonBuilder {
18
+ constructor(appName) {
19
+ _PackageJsonBuilder_appName.set(this, void 0);
20
+ _PackageJsonBuilder_typescript.set(this, true);
21
+ _PackageJsonBuilder_husky.set(this, false);
22
+ __classPrivateFieldSet(this, _PackageJsonBuilder_appName, appName, "f");
23
+ }
24
+ withJavaScript() {
25
+ __classPrivateFieldSet(this, _PackageJsonBuilder_typescript, false, "f");
26
+ return this;
27
+ }
28
+ withHusky() {
29
+ __classPrivateFieldSet(this, _PackageJsonBuilder_husky, true, "f");
30
+ return this;
31
+ }
32
+ build() {
33
+ let packageJson = (0, packageJsonConsts_1.getPackageJsonBase)(__classPrivateFieldGet(this, _PackageJsonBuilder_appName, "f"));
34
+ if (__classPrivateFieldGet(this, _PackageJsonBuilder_typescript, "f")) {
35
+ packageJson = Object.assign(Object.assign({}, packageJson), { scripts: Object.assign(Object.assign({}, packageJson.scripts), (0, packageJsonConsts_1.getTsScripts)(__classPrivateFieldGet(this, _PackageJsonBuilder_appName, "f"))) });
36
+ }
37
+ else {
38
+ packageJson = Object.assign(Object.assign({}, packageJson), { scripts: Object.assign(Object.assign({}, packageJson.scripts), (0, packageJsonConsts_1.getJsScripts)(__classPrivateFieldGet(this, _PackageJsonBuilder_appName, "f"))) });
39
+ }
40
+ if (__classPrivateFieldGet(this, _PackageJsonBuilder_husky, "f")) {
41
+ packageJson = Object.assign(Object.assign({}, packageJson), { scripts: Object.assign(Object.assign({}, packageJson.scripts), (0, packageJsonConsts_1.getHuskyScripts)(__classPrivateFieldGet(this, _PackageJsonBuilder_appName, "f"))) });
42
+ }
43
+ return packageJson;
44
+ }
45
+ }
46
+ exports.PackageJsonBuilder = PackageJsonBuilder;
47
+ _PackageJsonBuilder_appName = new WeakMap(), _PackageJsonBuilder_typescript = new WeakMap(), _PackageJsonBuilder_husky = new WeakMap();
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getHuskyScripts = exports.getJsScripts = exports.getTsScripts = exports.getPackageJsonBase = void 0;
4
+ const getPackageJsonBase = (appName) => ({
5
+ name: appName,
6
+ version: "0.1.0",
7
+ private: true,
8
+ main: "_build/index.js",
9
+ scripts: {}
10
+ });
11
+ exports.getPackageJsonBase = getPackageJsonBase;
12
+ const getSingleExecutableApplicationsScripts = (appName) => ({
13
+ "prenode-sea:build-blob": "rimraf _blob && mkdir _blob",
14
+ "node-sea:build-blob": "node --experimental-sea-config sea-config.json",
15
+ "node-sea:copy-node": `node -e "require('fs').copyFileSync(process.execPath, 'dist/${appName}.exe')"`,
16
+ "node-sea:unsign": `signtool remove /s dist/${appName}.exe || echo Warning: signtool not found in "Path"`,
17
+ "node-sea:inject-blob": `postject dist/${appName}.exe NODE_SEA_BLOB _blob\\sea-prep.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2`,
18
+ "node-sea:sign": `signtool sign /fd SHA256 dist/${appName}.exe`,
19
+ "node-sea": "npm run node-sea:build-blob && npm run node-sea:copy-node && npm run node-sea:unsign && npm run node-sea:inject-blob"
20
+ });
21
+ const getTsScripts = (appName) => (Object.assign({ "start": "ts-node src/index.ts", "type-check": "tsc --build tsconfig.json", "prewebpack": "rimraf build && rimraf dist", "webpack": "webpack", "prebuild": "npm run check-node-version", "build": "npm run type-check && npm run webpack && npm run node-sea", "check-node-version": "ts-node -e \"require(\"\"./utils/checkNodeVersion\"\").checkNodeRuntimeVersion()\"", "check-msbuild": "ts-node -e \"require(\"\"./launcher/launcherCompiler\"\").checkMsbuildInPath(true)\"", "rebuild-launcher": "msbuild launcher/launcher.csproj" }, getSingleExecutableApplicationsScripts(appName)));
22
+ exports.getTsScripts = getTsScripts;
23
+ const getJsScripts = (appName) => (Object.assign({ "start": "node src/index.js", "prewebpack": "rimraf build && rimraf dist", "webpack": "webpack", "prebuild": "npm run check-node-version", "build": "npm run webpack && npm run node-sea", "check-node-version": "node -e \"require(\"\"./utils/checkNodeVersion\"\").checkNodeRuntimeVersion()\"", "check-msbuild": "node -e \"require(\"\"./launcher/launcherCompiler\"\").checkMsbuildInPath(true)\"", "rebuild-launcher": "msbuild launcher/launcher.csproj" }, getSingleExecutableApplicationsScripts(appName)));
24
+ exports.getJsScripts = getJsScripts;
25
+ const getHuskyScripts = (appName) => ({
26
+ "prepare": "git config --get core.hookspath || husky install",
27
+ "pre-commit": `git diff HEAD --exit-code --stat launcher/* || npm run check-msbuild && npm run rebuild-launcher && git add resources/bin/${appName}-launcher.exe`
28
+ });
29
+ exports.getHuskyScripts = getHuskyScripts;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-windowless-app",
3
- "version": "11.0.0-beta.0",
3
+ "version": "11.0.0",
4
4
  "description": "Create a windowless NodeJS app",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -56,48 +56,52 @@
56
56
  },
57
57
  "homepage": "https://github.com/yoavain/create-windowless-app#readme",
58
58
  "devDependencies": {
59
- "@tsconfig/node20": "1.0.2",
60
- "@types/cross-spawn": "6.0.2",
59
+ "@tsconfig/node20": "20.1.1",
60
+ "@types/cross-spawn": "6.0.3",
61
61
  "@types/fs-extra": "11.0.1",
62
62
  "@types/inquirer": "8.2.6",
63
- "@types/jest": "29.5.3",
63
+ "@types/jest": "29.5.4",
64
64
  "@types/mock-fs": "4.13.1",
65
- "@types/node": "18.16.19",
65
+ "@types/node": "20.5.1",
66
66
  "@types/node-notifier": "8.0.2",
67
67
  "@types/validate-npm-package-name": "4.0.0",
68
68
  "@types/winston": "2.4.4",
69
- "@typescript-eslint/eslint-plugin": "5.61.0",
70
- "@typescript-eslint/parser": "5.61.0",
69
+ "@typescript-eslint/eslint-plugin": "5.62.0",
70
+ "@typescript-eslint/parser": "5.62.0",
71
71
  "add-shebang": "0.1.0",
72
72
  "copy-webpack-plugin": "11.0.0",
73
73
  "cross-env": "7.0.3",
74
74
  "del": "6.1.1",
75
- "eslint": "8.44.0",
76
- "eslint-plugin-import": "2.27.5",
77
- "eslint-plugin-jest": "27.2.2",
75
+ "eslint": "8.49.0",
76
+ "eslint-plugin-import": "2.28.1",
77
+ "eslint-plugin-jest": "27.2.3",
78
78
  "eslint-plugin-node": "11.1.0",
79
79
  "eslint-plugin-security": "1.7.1",
80
80
  "global-npm": "0.5.0",
81
81
  "husky": "8.0.3",
82
- "jest": "29.6.1",
83
- "lint-staged": "13.2.3",
82
+ "jest": "29.7.0",
83
+ "lint-staged": "13.3.0",
84
84
  "mock-fs": "5.2.0",
85
85
  "mocked-env": "1.3.5",
86
86
  "node-notifier": "10.0.1",
87
- "prettier": "3.0.0",
87
+ "nyc": "15.1.0",
88
+ "postject": "1.0.0-alpha.6",
89
+ "prettier": "3.0.3",
88
90
  "rimraf": "5.0.1",
89
91
  "tmp-promise": "3.0.3",
90
92
  "ts-jest": "29.1.1",
93
+ "ts-loader": "9.4.4",
91
94
  "ts-node": "10.9.1",
92
- "typescript": "5.1.6",
93
- "webpack": "5.88.1",
94
- "winston": "3.9.0"
95
+ "typescript": "5.2.2",
96
+ "webpack": "5.88.2",
97
+ "webpack-cli": "5.1.4",
98
+ "winston": "3.10.0"
95
99
  },
96
100
  "dependencies": {
97
101
  "chalk": "4.1.2",
98
102
  "cross-spawn": "7.0.3",
99
103
  "fs-extra": "11.1.1",
100
- "inquirer": "8.2.5",
104
+ "inquirer": "8.2.6",
101
105
  "validate-npm-package-name": "5.0.0",
102
106
  "yargs": "17.7.2"
103
107
  },
@@ -0,0 +1,14 @@
1
+ const MIN_MAJOR_VERSION = 20;
2
+ const MIN_MINOR_VERSION = 0;
3
+
4
+ export const checkNodeRuntimeVersion = () => {
5
+ const currentNodeVersion = process.versions.node;
6
+ const semver = currentNodeVersion.split(".");
7
+ const major = Number(semver[0]);
8
+ const minor = Number(semver[1]);
9
+
10
+ if (Number.isNaN(major) || Number.isNaN(minor) || major < MIN_MAJOR_VERSION || (major === MIN_MAJOR_VERSION && minor < MIN_MINOR_VERSION)) {
11
+ console.error(`You are running Node.js ${currentNodeVersion}.\nYou need at ${MIN_MAJOR_VERSION}.${MIN_MINOR_VERSION} or higher.\nPlease update your version of Node.`);
12
+ process.exit(1);
13
+ }
14
+ };
@@ -8,5 +8,5 @@
8
8
  "noEmit": true,
9
9
  "verbatimModuleSyntax": false
10
10
  },
11
- "include": ["./src/**/*", "./webpack.config.ts"]
11
+ "include": ["./src/**/*.ts", "./launcher/**/*.ts", "./utils/**/*.ts", "./webpack.config.ts"]
12
12
  }
@@ -0,0 +1,14 @@
1
+ const MIN_MAJOR_VERSION = 20;
2
+ const MIN_MINOR_VERSION = 0;
3
+
4
+ export const checkNodeRuntimeVersion = () => {
5
+ const currentNodeVersion: string = process.versions.node;
6
+ const semver: string[] = currentNodeVersion.split(".");
7
+ const major: number = Number(semver[0]);
8
+ const minor: number = Number(semver[1]);
9
+
10
+ if (Number.isNaN(major) || Number.isNaN(minor) || major < MIN_MAJOR_VERSION || (major === MIN_MAJOR_VERSION && minor < MIN_MINOR_VERSION)) {
11
+ console.error(`You are running Node.js ${currentNodeVersion}.\nYou need at ${MIN_MAJOR_VERSION}.${MIN_MINOR_VERSION} or higher.\nPlease update your version of Node.`);
12
+ process.exit(1);
13
+ }
14
+ };
package/dist/fileUtils.js DELETED
@@ -1,37 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.copyFile = exports.writeFile = exports.writeJson = exports.readJsonResource = exports.readResource = exports.readJsonFile = exports.readFile = void 0;
7
- const fs_extra_1 = require("fs-extra");
8
- const path_1 = __importDefault(require("path"));
9
- const os_1 = __importDefault(require("os"));
10
- const readFile = (fileName) => {
11
- return (0, fs_extra_1.readFileSync)(fileName, "utf8");
12
- };
13
- exports.readFile = readFile;
14
- const readJsonFile = (jsonFileName) => {
15
- return JSON.parse((0, exports.readFile)(jsonFileName));
16
- };
17
- exports.readJsonFile = readJsonFile;
18
- const readResource = (resourceRelativePath) => {
19
- return (0, exports.readFile)(path_1.default.resolve(__dirname, resourceRelativePath));
20
- };
21
- exports.readResource = readResource;
22
- const readJsonResource = (resourceRelativePath) => {
23
- return JSON.parse((0, exports.readResource)(resourceRelativePath));
24
- };
25
- exports.readJsonResource = readJsonResource;
26
- const writeJson = (fileName, object) => {
27
- (0, fs_extra_1.writeFileSync)(fileName, JSON.stringify(object, null, 2).replace(/\n/g, os_1.default.EOL) + os_1.default.EOL);
28
- };
29
- exports.writeJson = writeJson;
30
- const writeFile = (fileName, data) => {
31
- (0, fs_extra_1.writeFileSync)(fileName, data.replace(/\r/g, "").replace(/\n/g, os_1.default.EOL));
32
- };
33
- exports.writeFile = writeFile;
34
- const copyFile = (source, destination) => {
35
- (0, fs_extra_1.copyFileSync)(source, destination);
36
- };
37
- exports.copyFile = copyFile;
File without changes
File without changes
File without changes