Skip to content

Commit b84168a

Browse files
authored
Merge branch 'master' into 14.6.x
2 parents 65ba099 + adb4ba2 commit b84168a

File tree

53 files changed

+1700
-1832
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1700
-1832
lines changed

.github/workflows/codeql-analysis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ on:
2323
jobs:
2424
analyze:
2525
name: Analyze
26+
permissions:
27+
contents: read
28+
security-events: write
2629
runs-on: ubuntu-latest
2730

2831
strategy:

.github/workflows/nodejs.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
name: Node.js CI
2+
permissions:
3+
contents: read
4+
checks: write
25

36
on:
47
push:
@@ -35,6 +38,7 @@ jobs:
3538
run: yarn coverage
3639
- name: Publish to coveralls.io
3740
if: matrix.node-version == '20.x'
38-
uses: coverallsapp/[email protected]
41+
# coverallsapp/github-action@cfd0633edbd2411b532b808ba7a8b5e04f76d2c8 corresponds to v2.3.4
42+
uses: coverallsapp/github-action@cfd0633edbd2411b532b808ba7a8b5e04f76d2c8
3943
with:
4044
github-token: ${{ github.token }}

.github/workflows/npm-publish.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ on:
33
release:
44
types: [created]
55

6+
permissions:
7+
contents: read
8+
69
jobs:
710
build:
811
runs-on: ubuntu-latest

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"handlebars": "4.7.8"
6060
},
6161
"devDependencies": {
62-
"@inquirer/prompts": "^5.4.0",
62+
"@inquirer/prompts": "^7.9.0",
6363
"@types/jasmine": "^5.1.4",
6464
"@types/minimatch": "^5.1.2",
6565
"@types/node": "^22.5.5",

packages/cli/lib/commands/start.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,16 @@ import { PositionalArgs, StartCommandType } from "./types";
77
import { ArgumentsCamelCase } from "yargs";
88

99
const execSyncNpmStart = (port: number, options: ExecSyncOptions): void => {
10+
const args = ['start'];
1011
if (port) {
11-
Util.execSync(`npm start -- --port=${port}`, options);
12-
return;
12+
// Validate port is a number to prevent command injection
13+
if (!Number.isInteger(port) || port < 0 || port > 65535) {
14+
Util.error(`Invalid port number: ${port}`, "red");
15+
return;
16+
}
17+
args.push('--', `--port=${port}`);
1318
}
14-
Util.execSync(`npm start`, options);
19+
Util.spawnSync('npm', args, options);
1520
};
1621

1722
const command: StartCommandType = {

packages/cli/lib/templates/ReactTemplate.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,9 @@ export class ReactTemplate implements Template {
109109
const components = require("@igniteui/cli-core/packages/components");
110110
const igResPath = path.join(projectPath, this.igniteResources);
111111

112-
if (fs.existsSync(igResPath)) {
113-
let igniteuiResFile = fs.readFileSync(igResPath, "utf8");
112+
try {
113+
const fd = fs.openSync(igResPath, fs.constants.O_RDWR | fs.constants.O_CREAT);
114+
let igniteuiResFile = fs.readFileSync(fd, "utf8");
114115
const freeVersionPath = "ignite-ui/";
115116
const fullVersionPath = "@infragistics/ignite-ui-full/en/";
116117
const dvPath = "@infragistics/ignite-ui-full/en/js/infragistics.dv.js";
@@ -123,16 +124,19 @@ export class ReactTemplate implements Template {
123124
igniteuiResFile = igniteuiResFile.replace(freeVersionPath, fullVersionPath);
124125
igniteuiResFile = igniteuiResFile.replace("-lite", "");
125126
}
126-
fs.writeFileSync(igResPath, igniteuiResFile);
127+
fs.ftruncateSync(fd, 0);
128+
fs.writeSync(fd, igniteuiResFile, 0);
127129
}
128130

129131
if (dvDep && !igniteuiResFile.includes(dvPath)) {
130-
fs.appendFileSync(igResPath, `${'\r\n// Ignite UI Charts Required JavaScript File\r\nimport "'
131-
+ dvPath + '";\r\n'}`);
132+
const endPos = fs.fstatSync(fd).size;
133+
fs.writeSync(fd, `\r\n// Ignite UI Charts Required JavaScript File\r\nimport "${dvPath}";\r\n`, endPos);
132134
}
133135

134-
} else {
135-
Util.log(`igniteuiResources.js file NOT found!`);
136+
fs.closeSync(fd);
137+
} catch (err) {
138+
Util.error(`Error while updating igniteuiResources.js: ${err.message}`);
139+
throw err;
136140
}
137141
}
138142

packages/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878
"dependencies": {
7979
"@igniteui/angular-templates": "~20.1.1466",
8080
"@igniteui/cli-core": "~14.6.6",
81-
"@inquirer/prompts": "^5.4.0",
81+
"@inquirer/prompts": "^7.9.0",
8282
"@types/yargs": "^17.0.33",
8383
"chalk": "^5.3.0",
8484
"glob": "^11.0.0",

packages/core/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212
"author": "Infragistics",
1313
"license": "MIT",
1414
"dependencies": {
15-
"@inquirer/prompts": "~5.4.0",
15+
"@inquirer/prompts": "^7.9.0",
1616
"chalk": "^2.3.2",
1717
"glob": "^11.0.0",
1818
"through2": "^2.0.3",
1919
"typescript": "~5.5.4"
2020
},
2121
"devDependencies": {
2222
"@angular-devkit/schematics": "^19.0.0",
23-
"@inquirer/type": "^1.5.3"
23+
"@inquirer/type": "^3.0.0"
2424
}
2525
}

packages/core/packages/PackageManager.ts

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { exec } from "child_process";
1+
import { spawn } from "child_process";
22
import * as path from "path";
33
import { TemplateManager } from "../../cli/lib/TemplateManager";
44
import { Config, FS_TOKEN, IFileSystem, ProjectTemplate } from "../types";
@@ -149,10 +149,10 @@ export class PackageManager {
149149

150150
public static addPackage(packageName: string, verbose: boolean = false): boolean {
151151
const managerCommand = this.getManager();
152-
const command = this.getInstallCommand(managerCommand, packageName);
152+
const args = this.getInstallArgs(packageName);
153153
try {
154154
// tslint:disable-next-line:object-literal-sort-keys
155-
Util.execSync(command, { stdio: "pipe", encoding: "utf8" });
155+
Util.spawnSync(managerCommand, args, { stdio: "pipe", encoding: "utf8" });
156156
} catch (error) {
157157
Util.log(`Error installing package ${packageName} with ${managerCommand}`);
158158
if (verbose) {
@@ -165,7 +165,7 @@ export class PackageManager {
165165
}
166166

167167
public static async queuePackage(packageName: string, verbose = false) {
168-
const command = this.getInstallCommand(this.getManager(), packageName).replace("--save", "--no-save");
168+
const args = this.getInstallArgs(packageName).map(arg => arg === '--save' ? '--no-save' : arg);
169169
const [packName, version] = packageName.split(/@(?=[^\/]+$)/);
170170
const packageJSON = this.getPackageJSON();
171171
if (!packageJSON.dependencies) {
@@ -190,13 +190,24 @@ export class PackageManager {
190190
// D.P. Concurrent install runs should be supported
191191
// https://github.com/npm/npm/issues/5948
192192
// https://github.com/npm/npm/issues/2500
193+
const managerCommand = this.getManager();
193194
const task = new Promise<{ packageName, error, stdout, stderr }>((resolve, reject) => {
194-
const child = exec(
195-
command, {},
196-
(error, stdout, stderr) => {
197-
resolve({ packageName, error, stdout, stderr });
198-
}
199-
);
195+
const child = spawn(managerCommand, args);
196+
let stdout = '';
197+
let stderr = '';
198+
child.stdout?.on('data', (data) => {
199+
stdout += data.toString();
200+
});
201+
child.stderr?.on('data', (data) => {
202+
stderr += data.toString();
203+
});
204+
child.on('close', (code) => {
205+
const error = code !== 0 ? new Error(`Process exited with code ${code}`) : null;
206+
resolve({ packageName, error, stdout, stderr });
207+
});
208+
child.on('error', (err) => {
209+
resolve({ packageName, error: err, stdout, stderr });
210+
});
200211
});
201212
task["packageName"] = packName;
202213
this.installQueue.push(task);
@@ -281,6 +292,10 @@ export class PackageManager {
281292
}
282293
}
283294

295+
private static getInstallArgs(packageName: string): string[] {
296+
return ['install', packageName, '--quiet', '--save'];
297+
}
298+
284299
private static getManager(/*config:Config*/): string {
285300
//stub to potentially swap out managers
286301
return "npm";

packages/core/util/GoogleAnalytics.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,16 @@ class GoogleAnalytics {
6969
protected static getUUID(): string {
7070
const absolutePath = path.join(this.userDataFolder, this.appFolder, this.userSettings);
7171
let UUID = "";
72-
if (fs.existsSync(absolutePath)) {
73-
UUID = require(absolutePath).UUID;
74-
} else {
75-
const dirName = path.dirname(absolutePath);
76-
if (!fs.existsSync(dirName)) {
77-
fs.mkdirSync(dirName);
78-
}
72+
const dirName = path.dirname(absolutePath);
73+
fs.mkdirSync(dirName, { recursive: true });
7974

75+
try {
76+
const fd = fs.openSync(absolutePath, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_RDWR, 0o600);
8077
UUID = this.getUserID();
81-
fs.writeFileSync(absolutePath, JSON.stringify({ UUID }));
78+
fs.writeFileSync(fd, JSON.stringify({ UUID }));
79+
fs.closeSync(fd);
80+
} catch {
81+
UUID = JSON.parse(fs.readFileSync(absolutePath, "utf8")).UUID;
8282
}
8383

8484
return UUID;

0 commit comments

Comments
 (0)