Skip to content

Commit

Permalink
Update the .loc.json schema to allow for string names taht include th…
Browse files Browse the repository at this point in the history
…e '$' character. (#4879)
  • Loading branch information
iclanton authored Aug 12, 2024
1 parent 253cb78 commit 3bcf141
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@rushstack/localization-utilities",
"comment": "Update the schema for `.loc.json` files to allow string names that include the `$` character.",
"type": "minor"
}
],
"packageName": "@rushstack/localization-utilities"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@rushstack/node-core-library",
"comment": "Add a `ignoreSchemaField` option to the `JsonSchema.validateObject` options to ignore `$schema` properties and add an options object argument to `JsonSchema.validateObjectWithCallback` with the same `ignoreSchemaField` option.",
"type": "minor"
}
],
"packageName": "@rushstack/node-core-library"
}
9 changes: 7 additions & 2 deletions common/reviews/api/node-core-library.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,12 @@ export interface IJsonSchemaLoadOptions {
}

// @public
export interface IJsonSchemaValidateOptions {
export interface IJsonSchemaValidateObjectWithOptions {
ignoreSchemaField?: boolean;
}

// @public
export interface IJsonSchemaValidateOptions extends IJsonSchemaValidateObjectWithOptions {
customErrorHeader?: string;
}

Expand Down Expand Up @@ -675,7 +680,7 @@ export class JsonSchema {
static fromLoadedObject(schemaObject: JsonObject, options?: IJsonSchemaFromObjectOptions): JsonSchema;
get shortName(): string;
validateObject(jsonObject: JsonObject, filenameForErrors: string, options?: IJsonSchemaValidateOptions): void;
validateObjectWithCallback(jsonObject: JsonObject, errorCallback: (errorInfo: IJsonSchemaErrorInfo) => void): void;
validateObjectWithCallback(jsonObject: JsonObject, errorCallback: (errorInfo: IJsonSchemaErrorInfo) => void, options?: IJsonSchemaValidateObjectWithOptions): void;
}

// @public
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const LOC_JSON_SCHEMA: JsonSchema = JsonSchema.fromLoadedObject(locJsonSchema);
export function parseLocJson({ content, filePath, ignoreString }: IParseFileOptions): ILocalizationFile {
const parsedFile: ILocalizationFile = JsonFile.parseString(content);
try {
LOC_JSON_SCHEMA.validateObject(parsedFile, filePath);
LOC_JSON_SCHEMA.validateObject(parsedFile, filePath, { ignoreSchemaField: true });
} catch (e) {
throw new Error(`The loc file is invalid. Error: ${e}`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,8 @@
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Localizable JSON file",

"properties": {
"$schema": {
"description": "Part of the JSON Schema standard, this optional keyword declares the URL of the schema that the file conforms to. Editors may download the schema and use it to perform syntax highlighting.",
"type": "string"
}
},
"patternProperties": {
"^[A-Za-z_][0-9A-Za-z_]*$": {
"^[A-Za-z_$][0-9A-Za-z_$]*$": {
"type": "object",
"properties": {
"value": {
Expand Down
51 changes: 38 additions & 13 deletions libraries/node-core-library/src/JsonSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ interface ISchemaWithId {
export type JsonSchemaVersion = 'draft-04' | 'draft-07';

/**
* Callback function arguments for JsonSchema.validateObjectWithCallback();
* Callback function arguments for {@link JsonSchema.validateObjectWithCallback}
* @public
*/
export interface IJsonSchemaErrorInfo {
Expand All @@ -37,10 +37,22 @@ export interface IJsonSchemaErrorInfo {
}

/**
* Options for JsonSchema.validateObject()
* Options for {@link JsonSchema.validateObjectWithCallback}
* @public
*/
export interface IJsonSchemaValidateOptions {
export interface IJsonSchemaValidateObjectWithOptions {
/**
* If true, the root-level `$schema` property in a JSON object being validated will be ignored during validation.
* If this is set to `true` and the schema requires a `$schema` property, validation will fail.
*/
ignoreSchemaField?: boolean;
}

/**
* Options for {@link JsonSchema.validateObject}
* @public
*/
export interface IJsonSchemaValidateOptions extends IJsonSchemaValidateObjectWithOptions {
/**
* A custom header that will be used to report schema errors.
* @remarks
Expand All @@ -53,7 +65,7 @@ export interface IJsonSchemaValidateOptions {
}

/**
* Options for JsonSchema.fromFile() and JsonSchema.fromLoadedObject()
* Options for {@link JsonSchema.fromFile} and {@link JsonSchema.fromLoadedObject}
* @public
*/
export interface IJsonSchemaLoadOptions {
Expand Down Expand Up @@ -85,13 +97,13 @@ export interface IJsonSchemaLoadOptions {
}

/**
* Options for JsonSchema.fromFile()
* Options for {@link JsonSchema.fromFile}
* @public
*/
export type IJsonSchemaFromFileOptions = IJsonSchemaLoadOptions;

/**
* Options for JsonSchema.fromLoadedObject()
* Options for {@link JsonSchema.fromLoadedObject}
* @public
*/
export type IJsonSchemaFromObjectOptions = IJsonSchemaLoadOptions;
Expand Down Expand Up @@ -334,12 +346,15 @@ export class JsonSchema {
filenameForErrors: string,
options?: IJsonSchemaValidateOptions
): void {
this.validateObjectWithCallback(jsonObject, (errorInfo: IJsonSchemaErrorInfo) => {
const prefix: string =
options && options.customErrorHeader ? options.customErrorHeader : 'JSON validation failed:';

throw new Error(prefix + os.EOL + filenameForErrors + os.EOL + errorInfo.details);
});
this.validateObjectWithCallback(
jsonObject,
(errorInfo: IJsonSchemaErrorInfo) => {
const prefix: string = options?.customErrorHeader ?? 'JSON validation failed:';

throw new Error(prefix + os.EOL + filenameForErrors + os.EOL + errorInfo.details);
},
options
);
}

/**
Expand All @@ -348,10 +363,20 @@ export class JsonSchema {
*/
public validateObjectWithCallback(
jsonObject: JsonObject,
errorCallback: (errorInfo: IJsonSchemaErrorInfo) => void
errorCallback: (errorInfo: IJsonSchemaErrorInfo) => void,
options?: IJsonSchemaValidateObjectWithOptions
): void {
this.ensureCompiled();

if (options?.ignoreSchemaField) {
const {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
$schema,
...remainder
} = jsonObject;
jsonObject = remainder;
}

if (this._validator && !this._validator(jsonObject)) {
const errorDetails: string = JsonSchema._formatErrorDetails(this._validator.errors!);

Expand Down
1 change: 1 addition & 0 deletions libraries/node-core-library/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export {
type IJsonSchemaFromObjectOptions,
type IJsonSchemaLoadOptions,
type IJsonSchemaValidateOptions,
type IJsonSchemaValidateObjectWithOptions,
JsonSchema,
type JsonSchemaVersion
} from './JsonSchema';
Expand Down

0 comments on commit 3bcf141

Please sign in to comment.