Skip to content

Commit

Permalink
fix: force paths to be lowercase, restrict path characters
Browse files Browse the repository at this point in the history
Closes #48

- Makes registry paths lowercase to fix suggestion issues with commands containing uppercase characters.

- Restricts paths to alphanumeric characters and underscores.

- Make `getChildPaths` case-insensitive.
  • Loading branch information
paradoxuum committed Oct 4, 2024
1 parent e4908c6 commit 56bd0f0
Showing 1 changed file with 37 additions and 20 deletions.
57 changes: 37 additions & 20 deletions packages/core/src/shared/core/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,22 +193,30 @@ export abstract class BaseRegistry<
* @param groups The groups to register
*/
registerGroup(...groups: GroupOptions[]) {
const commandGroups = groups.map(
(options) =>
const commandGroups: CommandGroup[] = [];
for (const group of groups) {
const pathParts =
group.parent !== undefined
? group.parent.map((val) => val.lower())
: [];
pathParts.push(group.name.lower());
commandGroups.push(
new CommandGroup(
this.config,
new ImmutableRegistryPath([...(options.parent ?? []), options.name]),
options,
new ImmutableRegistryPath(pathParts),
group,
),
);
);
}

// Sort groups by path size so parent groups are registered first
commandGroups.sort((a, b) => a.getPath().size() < b.getPath().size());

for (const group of commandGroups) {
const pathString = group.getPath().toString();
this.validatePath(pathString, false);
const path = group.getPath();
this.validatePath(path, false);

const pathString = path.toString();
if (group.getPath().size() > 1) {
const parentPath = group.getPath().parent();
const parentGroup = this.groups.get(parentPath.toString());
Expand Down Expand Up @@ -395,7 +403,7 @@ export abstract class BaseRegistry<
* @returns An array of {@link RegistryPath} instances.
*/
getChildPaths(path: RegistryPath) {
return this.cachedPaths.get(path.toString()) ?? [];
return this.cachedPaths.get(path.toString().lower()) ?? [];
}

protected cachePath(path: RegistryPath) {
Expand Down Expand Up @@ -436,7 +444,7 @@ export abstract class BaseRegistry<

protected addCommand(command: BaseCommand, group?: CommandGroup) {
for (const path of command.getPaths()) {
this.validatePath(path.toString(), true);
this.validatePath(path, true);
this.commands.set(path.toString(), command);
this.cachePath(path);
}
Expand All @@ -458,8 +466,8 @@ export abstract class BaseRegistry<
) {
const commandPath =
group !== undefined
? group.append(options.name)
: new ImmutableRegistryPath([options.name]);
? group.append(options.name.lower())
: new ImmutableRegistryPath([options.name.lower()]);

let commandGroup: CommandGroup | undefined;
if (group !== undefined) {
Expand Down Expand Up @@ -533,10 +541,10 @@ export abstract class BaseRegistry<
property,
) ?? [];

const groupParts = [...classGroups];
const groupParts = classGroups.map((val) => val.lower());
if (group !== undefined && !group.isEmpty()) {
for (const part of group) {
groupParts.push(part);
groupParts.push(part.lower());
}
}

Expand All @@ -561,30 +569,39 @@ export abstract class BaseRegistry<
}
}

protected validatePath(path: string, isCommand: boolean) {
const commandRegistered = this.commands.has(path);
private validatePath(path: RegistryPath, isCommand: boolean) {
const pathString = path.toString();
for (const part of path.iter()) {
if (part.match("^[a-zA-Z0-9_]+$")[0]) continue;
this.logger.error(
`Invalid path for ${isCommand ? "command" : "group"}: ${pathString}. Command/group names can only contain alphanumeric characters and underscores.`,
);
return;
}

const commandRegistered = this.commands.has(pathString);
if (commandRegistered && isCommand) {
this.logger.error(`Duplicate command: ${path}`);
this.logger.error(`Duplicate command: ${pathString}`);
return;
}

if (commandRegistered) {
this.logger.error(
`A command already exists with the same name as this group: ${path}`,
`A command already exists with the same name as this group: ${pathString}`,
);
return;
}

const groupRegistered = this.groups.has(path);
const groupRegistered = this.groups.has(pathString);
if (groupRegistered && isCommand) {
this.logger.error(
`A group already exists with the same name as this command: ${path}`,
`A group already exists with the same name as this command: ${pathString}`,
);
return;
}

if (groupRegistered) {
this.logger.error(`Duplicate group: ${path}`);
this.logger.error(`Duplicate group: ${pathString}`);
}
}
}

0 comments on commit 56bd0f0

Please sign in to comment.