Skip to content

Commit 7b90e15

Browse files
committed
Add resource config validation (without resource defs) + added better name validation
1 parent 2cf1991 commit 7b90e15

4 files changed

Lines changed: 64 additions & 8 deletions

File tree

codify-core/src/config-compiler/parser/entities/project.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,21 @@ describe('Parser: project entity tests', () => {
6060
name: 'test-project',
6161
type: 'project',
6262
})).to.not.throw;
63+
64+
expect(() => new ProjectConfig({
65+
name: '1',
66+
type: 'project',
67+
})).to.throw;
68+
69+
expect(() => new ProjectConfig({
70+
name: '##ab',
71+
type: 'project',
72+
})).to.throw;
73+
74+
expect(() => new ProjectConfig({
75+
name: 'abc12',
76+
type: 'project',
77+
})).to.not.throw;
6378
})
6479

6580
it('plugin versions must be semvers', () => {

codify-core/src/config-compiler/parser/entities/project.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { RemoveMethods } from '../../../utils/types';
22
import {
33
validateAllowedObjectKeys,
4+
validateNameString,
45
validateSemver,
56
validateStringEq,
67
validateTypeRecordStringString,
@@ -53,8 +54,8 @@ export class ProjectConfig implements ConfigBlock {
5354
throw new Error('Config is not of type project');
5455
}
5556

56-
if (config.name && !validateTypeString(config.name)) {
57-
throw new Error('Name is not of type string');
57+
if (config.name && !validateNameString(config.name)) {
58+
throw new Error('Name must be of type string, start with a letter, and only contain [a-z][0-9]_-');
5859
}
5960

6061
if (config.plugins && !validateTypeRecordStringString) {
Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,55 @@
11
import { RemoveMethods } from '../../../utils/types';
2+
import { validateNameString, validateStringEq, validateTypeRecordStringUnknown, } from '../../../utils/validator';
23
import { ConfigBlock, ConfigBlockType } from './index';
34

5+
/** Resource JSON supported format
6+
* {
7+
* "type": "plugin_name_resource_1",
8+
* "name?": "optional-name"
9+
* "parameter1": {
10+
* "plguin1": "^10.6.2", // From registry
11+
* "https://www.github.com/project": "^10.3.2", // url
12+
* }
13+
* "parameter2": "string",
14+
* "parameter3": 1,
15+
* }
16+
*
17+
* We won't be able to validate the parameters until we get the resource definitions from the plugins
18+
*/
19+
420
export class ResourceConfig implements ConfigBlock {
521
readonly configType = ConfigBlockType.RESOURCE;
622

7-
type!: string;
23+
type: string;
824
name?: string;
9-
parameters!: Record<string, unknown>;
25+
parameters: Record<string, unknown>;
1026
dependencies?: Node[] = [];
1127

12-
constructor(props: Omit<RemoveMethods<ResourceConfig>, 'configType'>) {
13-
Object.assign(this, props);
28+
constructor(config: unknown) {
29+
if (this.validate(config)) {
30+
const { name, type, ...params } = config;
31+
this.type = type;
32+
this.name = name;
33+
this.parameters = params ?? {};
34+
}
35+
36+
throw new Error('Unable to parse resource config');
1437
}
1538

16-
validate(config: unknown): void {
17-
console.log(config);
39+
validate(config: unknown): config is RemoveMethods<ResourceConfig> {
40+
if (!validateTypeRecordStringUnknown(config)) {
41+
throw new Error('Config is not an object');
42+
}
43+
44+
if (!validateStringEq(config.type, 'project')) {
45+
throw new Error('Config is not of type project');
46+
}
47+
48+
if (config.name && !validateNameString(config.name)) {
49+
throw new Error('Name must be of type string, start with a letter, and only contain a-z0-9_-');
50+
}
51+
52+
return true;
1853
}
1954

2055
}

codify-core/src/utils/validator.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { valid as semverValid } from 'semver';
55
//******************
66

77
const urlRegex = /[\w#%+.:=@~-]{1,256}\.[\d()a-z]{1,6}\b([\w#%&()+./:=?@~-]*)/gi;
8+
const nameRegex = /^[$_a-z][\w$]*$/gi;
89

910
//*****************
1011
// Validators
@@ -36,6 +37,10 @@ export function validateStringEq(actual: unknown, expected: string): actual is s
3637
return actual === expected;
3738
}
3839

40+
export function validateNameString(actual: unknown): actual is string {
41+
return validateTypeString(actual) && actual.match(nameRegex) !== null;
42+
}
43+
3944
export function validateUrl(actual: unknown): actual is string {
4045
return validateTypeString(actual) && actual.match(urlRegex) !== null;
4146
}

0 commit comments

Comments
 (0)