Skip to content

Commit b0b6029

Browse files
authored
Merge branch 'master' into mstoyanova/adding-skill
2 parents 868c7dc + ed4d1dd commit b0b6029

644 files changed

Lines changed: 3803 additions & 3933 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import javascript
2+
import semmle.javascript.security.dataflow.CommandInjectionCustomizations
3+
4+
5+
// General flow via config https://codeql.github.com/docs/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript/#sanitizers
6+
// Instead this follows https://github.com/github/codeql/blob/a3e9aed00ae5c1e70da8fbc4fc4a7cc803f177ca/javascript/documentation/library-customization.rst?plain=1#L244-L245
7+
// to modify the pre-defined javascript CommandInjection flow's Sanitizer
8+
9+
/**
10+
* Treat Util.sanitizeShellArg(x) as a sanitizer for shell‑command injection.
11+
*/
12+
class ShellArgSanitizer extends CommandInjection::Sanitizer {
13+
ShellArgSanitizer() {
14+
this.(DataFlow::MethodCallNode).getReceiver().toString() = "Util" and
15+
this.(DataFlow::MethodCallNode).getMethodName() = "sanitizeShellArg"
16+
}
17+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name: igniteui-cli-custom-javascript-queries
2+
version: 0.0.0
3+
dependencies:
4+
codeql/javascript-queries: "*"

.github/workflows/codeql-analysis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ jobs:
4949
# By default, queries listed here will override any specified in a config file.
5050
# Prefix the list here with "+" to use these queries and those in the config file.
5151
# queries: ./path/to/local/query, your-org/your-repo/queries@main
52+
queries: ./.github/codeql/custom-queries-javascript
5253

5354
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
5455
# If this step fails, then you should remove it and run the build manually (see below)

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
## [14.9.2](https://github.com/IgniteUI/igniteui-cli/compare/14.9.1...14.9.2) (2026-03-11)
2+
3+
### What's Changed
4+
* fix(igx-ts): update igniteui-angular versions and remove overrides by @Hristo313 in https://github.com/IgniteUI/igniteui-cli/pull/1508
5+
* fix(igx-ts): fix eslint configurations by @Hristo313 in https://github.com/IgniteUI/igniteui-cli/pull/1509
6+
* fix(upgrade-packages): correctly glob files on windows by @damyanpetev in https://github.com/IgniteUI/igniteui-cli/pull/1511
7+
* fix(igx-ts-legacy): fix grid type import and add missing override by @Hristo313 in https://github.com/IgniteUI/igniteui-cli/pull/1519
8+
* Fix start and other npm exec commands by @damyanpetev in https://github.com/IgniteUI/igniteui-cli/pull/1520
9+
* fix(schematics): fs writeFile create check by @damyanpetev in https://github.com/IgniteUI/igniteui-cli/pull/1526
10+
* fix(packages): disable non-functional registry login attempt on upgrade by @damyanpetev in https://github.com/IgniteUI/igniteui-cli/pull/1528
11+
12+
**Full Changelog**: https://github.com/IgniteUI/igniteui-cli/compare/14.9.1...14.9.2
13+
114
## [14.9.1](https://github.com/IgniteUI/igniteui-cli/compare/14.9.0...14.9.1) (2026-02-25)
215

316
### What's Changed
@@ -6,7 +19,6 @@
619

720
**Full Changelog**: https://github.com/IgniteUI/igniteui-cli/compare/14.9.0...14.9.1
821

9-
1022
# [14.9.0](https://github.com/IgniteUI/igniteui-cli/compare/v14.8.5...14.9.0) (2026-02-25)
1123

1224
🎉 This update includes:

packages/cli/lib/commands/start.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +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'];
1110
if (port) {
1211
// Validate port is a number to prevent command injection
1312
if (!Number.isInteger(port) || port < 0 || port > 65535) {
1413
Util.error(`Invalid port number: ${port}`, "red");
1514
return;
1615
}
17-
args.push('--', `--port=${port}`);
16+
Util.execSync(`npm start -- --port=${port}`, options);
17+
return;
1818
}
19-
Util.spawnSync('npm', args, options);
19+
Util.execSync(`npm start`, options);
2020
};
2121

2222
const command: StartCommandType = {

packages/cli/lib/templates/AngularTemplate.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export class AngularTemplate implements Template {
4545
}
4646

4747
public registerInProject(projectPath: string, name: string, options?: AddTemplateArgs) {
48-
let modulePath = "app.module.ts";
48+
let modulePath = "app-module.ts";
4949
if (options && options.modulePath) {
5050
modulePath = options.modulePath;
5151
}
@@ -63,7 +63,7 @@ export class AngularTemplate implements Template {
6363
//1) import the component class name,
6464
//2) and populate the Routes array with the path and component
6565
//for example: { path: "combo", component: ComboComponent }
66-
const routingModulePath = path.join(projectPath, "src/app/app-routing.module.ts");
66+
const routingModulePath = path.join(projectPath, "src/app/app-routing-module.ts");
6767
const routingModule = new TsUpdate(routingModulePath, false, { singleQuotes: false });
6868

6969
routingModule.addRoute({
@@ -84,7 +84,7 @@ export class AngularTemplate implements Template {
8484
mainModule.addNgModuleMeta({
8585
declare: [className],
8686
from: relativePath,
87-
export: modulePath !== "app.module.ts" ? [className] : []
87+
export: modulePath !== "app-module.ts" ? [className] : []
8888
});
8989
mainModule.finalize();
9090

packages/cli/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "igniteui-cli",
3-
"version": "14.9.1",
3+
"version": "14.9.2",
44
"description": "CLI tool for creating Ignite UI projects",
55
"keywords": [
66
"CLI",
@@ -76,8 +76,8 @@
7676
"all": true
7777
},
7878
"dependencies": {
79-
"@igniteui/angular-templates": "~21.1.1491",
80-
"@igniteui/cli-core": "~14.9.1",
79+
"@igniteui/angular-templates": "~21.1.1492",
80+
"@igniteui/cli-core": "~14.9.2",
8181
"@inquirer/prompts": "^7.9.0",
8282
"@types/yargs": "^17.0.33",
8383
"chalk": "^5.3.0",

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@igniteui/cli-core",
3-
"version": "14.9.1",
3+
"version": "14.9.2",
44
"description": "Base types and functionality for Ignite UI CLI",
55
"repository": {
66
"type": "git",

packages/core/packages/PackageManager.ts

Lines changed: 45 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
import { spawn } from "child_process";
1+
import { exec } 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";
55
import { App, ProjectConfig, Util } from "../util";
66

77
import componentsConfig = require("./components");
88

9+
/** @internal */
10+
export const REGISTRY_ATTEMPT_LOGIN = false;
11+
912
export class PackageManager {
1013
private static ossPackage: string = "ignite-ui";
1114
private static fullPackage: string = "@infragistics/ignite-ui-full";
@@ -45,6 +48,10 @@ export class PackageManager {
4548
const version = ossVersion ? `@"${ossVersion}"` : "";
4649
const errorMsg = "Something went wrong, " +
4750
"please follow the steps in this guide: https://www.igniteui.com/help/using-ignite-ui-npm-packages";
51+
Util.log(
52+
"The project you've created requires the full version of Ignite UI from Infragistics private feed.",
53+
"gray"
54+
);
4855
// fallback to @latest, in case when igniteui-full does not have a matching version to ossVersion
4956
// ex: "ignite-ui": "^21.1.13" BUT --> ignite-ui-full": "^21.1.11" (no 21.1.13 released).
5057
// TODO: update temp fix - only working in 21.1.11 without errors
@@ -88,9 +95,8 @@ export class PackageManager {
8895
const config = ProjectConfig.localConfig();
8996
if (!config.packagesInstalled) {
9097
let command: string;
91-
let managerCommand: string;
98+
const managerCommand = this.getManager();
9299

93-
managerCommand = this.getManager();
94100
switch (managerCommand) {
95101
case "npm":
96102
/* passes through */
@@ -123,49 +129,52 @@ export class PackageManager {
123129
}
124130

125131
public static removePackage(packageName: string, verbose: boolean = false): boolean {
132+
let command: string;
126133
const managerCommand = this.getManager();
127-
let args: string[];
134+
const sanitizePackage = Util.sanitizeShellArg(packageName);
128135
switch (managerCommand) {
129136
case "npm":
130137
/* passes through */
131138
default:
132-
args = ['uninstall', packageName, '--quiet', '--save'];
139+
command = `${managerCommand} uninstall ${sanitizePackage} --quiet --save`;
133140
break;
134141
}
135142
try {
136143
// tslint:disable-next-line:object-literal-sort-keys
137-
Util.spawnSync(managerCommand, args, { stdio: "pipe", encoding: "utf8" });
144+
Util.execSync(command, { stdio: "pipe", encoding: "utf8" });
138145
} catch (error) {
139-
Util.log(`Error uninstalling package ${packageName} with ${managerCommand}`);
146+
Util.log(`Error uninstalling package ${sanitizePackage} with ${managerCommand}`);
140147
if (verbose) {
141148
Util.log(error.message);
142149
}
143150
return false;
144151
}
145152

146-
Util.log(`Package ${packageName} uninstalled successfully`);
153+
Util.log(`Package ${sanitizePackage} uninstalled successfully`);
147154
return true;
148155
}
149156

150157
public static addPackage(packageName: string, verbose: boolean = false): boolean {
151158
const managerCommand = this.getManager();
152-
const args = this.getInstallArgs(packageName);
159+
const sanitizePackage = Util.sanitizeShellArg(packageName);
160+
const command = this.getInstallCommand(managerCommand, sanitizePackage);
153161
try {
154162
// tslint:disable-next-line:object-literal-sort-keys
155-
Util.spawnSync(managerCommand, args, { stdio: "pipe", encoding: "utf8" });
163+
Util.execSync(command, { stdio: "pipe", encoding: "utf8" });
156164
} catch (error) {
157-
Util.log(`Error installing package ${packageName} with ${managerCommand}`);
165+
Util.log(`Error installing package ${sanitizePackage} with ${managerCommand}`);
158166
if (verbose) {
159167
Util.log(error.message);
160168
}
161169
return false;
162170
}
163-
Util.log(`Package ${packageName} installed successfully`);
171+
Util.log(`Package ${sanitizePackage} installed successfully`);
164172
return true;
165173
}
166174

167175
public static async queuePackage(packageName: string, verbose = false) {
168-
const args = this.getInstallArgs(packageName).map(arg => arg === '--save' ? '--no-save' : arg);
176+
const command = this.getInstallCommand(this.getManager(), Util.sanitizeShellArg(packageName))
177+
.replace("--save", "--no-save");
169178
const [packName, version] = packageName.split(/@(?=[^\/]+$)/);
170179
const packageJSON = this.getPackageJSON();
171180
if (!packageJSON.dependencies) {
@@ -190,24 +199,13 @@ export class PackageManager {
190199
// D.P. Concurrent install runs should be supported
191200
// https://github.com/npm/npm/issues/5948
192201
// https://github.com/npm/npm/issues/2500
193-
const managerCommand = this.getManager();
194202
const task = new Promise<{ packageName, error, stdout, stderr }>((resolve, reject) => {
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-
});
203+
const child = exec(
204+
command, {},
205+
(error, stdout, stderr) => {
206+
resolve({ packageName, error, stdout, stderr });
207+
}
208+
);
211209
});
212210
task["packageName"] = packName;
213211
this.installQueue.push(task);
@@ -233,16 +231,17 @@ export class PackageManager {
233231
}
234232

235233
public static ensureRegistryUser(config: Config, message: string): boolean {
236-
const fullPackageRegistry = config.igPackageRegistry;
234+
const fullPackageRegistry = Util.sanitizeShellArg(config.igPackageRegistry);
237235
try {
238236
// tslint:disable-next-line:object-literal-sort-keys
239-
Util.spawnSync('npm', ['whoami', `--registry=${fullPackageRegistry}`], { stdio: 'pipe', encoding: 'utf8' });
237+
Util.execSync(`npm whoami --registry=${fullPackageRegistry}`, { stdio: "pipe", encoding: "utf8" });
240238
} catch (error) {
239+
if (!REGISTRY_ATTEMPT_LOGIN) {
240+
Util.log(message, "gray");
241+
return true;
242+
}
243+
241244
// try registering the user:
242-
Util.log(
243-
"The project you've created requires the full version of Ignite UI from Infragistics private feed.",
244-
"gray"
245-
);
246245
Util.log(
247246
"We are initiating the login process for you. This will be required only once per environment.",
248247
"gray"
@@ -257,20 +256,16 @@ export class PackageManager {
257256
if (process.stdin.isTTY) {
258257
process.stdin.setRawMode(true);
259258
}
260-
const cmd = /^win/.test(process.platform) ? "npm.cmd" : "npm"; //https://github.com/nodejs/node/issues/3675
261-
const login = Util.spawnSync(cmd,
262-
["adduser", `--registry=${fullPackageRegistry}`, `--scope=@infragistics`, `--auth-type=legacy`],
263-
{ stdio: "inherit" }
264-
);
265-
if (login?.status === 0) {
259+
260+
try {
261+
Util.execSync(
262+
`npm login --registry=${fullPackageRegistry} --scope=@infragistics --auth-type=legacy`,
263+
{ stdio: "inherit" }
264+
);
266265
//make sure scope is configured:
267-
try {
268-
Util.spawnSync('npm', ['config', 'set', `@infragistics:registry`, fullPackageRegistry]);
269-
return true;
270-
} catch (error) {
271-
return false;
272-
}
273-
} else {
266+
Util.execSync(`npm config set @infragistics:registry ${fullPackageRegistry}`);
267+
return true;
268+
} catch (error) {
274269
Util.log(message, "red");
275270
return false;
276271
}
@@ -292,11 +287,7 @@ export class PackageManager {
292287
}
293288
}
294289

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

packages/core/update/Update.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export async function updateWorkspace(rootPath: string): Promise<boolean> {
5555
}
5656
const pkgJSON = JSON.parse(fileString);
5757

58-
const errorMsg = "Something went wrong, please follow the steps in this guide: " + guideLink;
58+
const errorMsg = "Can't detect/setup Infragistics feed login required for licensed packages.\nSee: " + guideLink;
5959
if (!PackageManager.ensureRegistryUser(config, errorMsg)) {
6060
return false;
6161
}

0 commit comments

Comments
 (0)