@planning-inspectorate/data-model 2.24.0 → 2.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/pins_data_model/models/model_appeal_document.py +1 -1
- package/pins_data_model/models/model_appeal_event.py +1 -1
- package/pins_data_model/models/model_appeal_event_estimate.py +1 -1
- package/pins_data_model/models/model_appeal_has.py +1 -1
- package/pins_data_model/models/model_appeal_representation.py +1 -1
- package/pins_data_model/models/model_appeal_s78.py +1 -1
- package/pins_data_model/models/model_dart_response.py +1 -1
- package/pins_data_model/models/model_entraid.py +1 -1
- package/pins_data_model/models/model_folder.py +1 -1
- package/pins_data_model/models/model_gettimesheets_response.py +1 -1
- package/pins_data_model/models/model_listed_building.py +1 -1
- package/pins_data_model/models/model_listed_buildings.py +1 -1
- package/pins_data_model/models/model_nsip_document.py +1 -1
- package/pins_data_model/models/model_nsip_exam_timetable.py +1 -1
- package/pins_data_model/models/model_nsip_invoice.py +1 -1
- package/pins_data_model/models/model_nsip_meeting.py +1 -1
- package/pins_data_model/models/model_nsip_project.py +1 -1
- package/pins_data_model/models/model_nsip_project_update.py +1 -1
- package/pins_data_model/models/model_nsip_representation.py +1 -1
- package/pins_data_model/models/model_nsip_subscription.py +1 -1
- package/pins_data_model/models/model_pins_inspector.py +1 -1
- package/pins_data_model/models/model_pins_lpa.py +1 -1
- package/pins_data_model/models/model_s51_advice.py +1 -1
- package/pins_data_model/models/model_service_user.py +1 -1
- package/schemas/commands/appeals-components/lpa-questionnaire-enforcement-common.schema.json +48 -0
- package/schemas/commands/appeals-components/lpa-questionnaire-enforcement.schema.json +14 -46
- package/schemas/commands/lpa-questionnaire.schema.json +18 -2
- package/src/enums.cjs +41 -0
- package/src/enums.d.ts +37 -0
- package/src/enums.js +37 -0
- package/src/index.cjs +41 -0
- package/src/lib/gen-enum-impl.js +196 -0
- package/src/lib/gen-enum-impl.test.js +183 -0
- package/src/lib/gen-enums.js +11 -87
- package/src/schemas.d.ts +24 -7
- package/tests/appeals/commands/enforcement-listed-questionnaire.test.js +4 -8
- package/tests/appeals/commands/enforcement-questionnaire.test.js +2 -2
package/package.json
CHANGED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "commands/appeals-components/lpa-questionnaire-enforcement-common.schema.json",
|
|
4
|
+
"title": "LPAQ Enforcement common submission properties",
|
|
5
|
+
"description": "Schema defining any common enforcement specific properties for LPAQ submissions",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": true,
|
|
8
|
+
"required": [
|
|
9
|
+
"noticeRelatesToBuildingEngineeringMiningOther",
|
|
10
|
+
"siteAreaSquareMetres",
|
|
11
|
+
"relatesToErectionOfBuildingOrBuildings",
|
|
12
|
+
"relatesToBuildingWithAgriculturalPurpose",
|
|
13
|
+
"relatesToBuildingSingleDwellingHouse"
|
|
14
|
+
],
|
|
15
|
+
"allOf": [
|
|
16
|
+
{
|
|
17
|
+
"properties": {
|
|
18
|
+
"noticeRelatesToBuildingEngineeringMiningOther": {
|
|
19
|
+
"type": ["boolean", "null"]
|
|
20
|
+
},
|
|
21
|
+
"siteAreaSquareMetres": {
|
|
22
|
+
"type": ["number", "null"],
|
|
23
|
+
"examples": [45.7],
|
|
24
|
+
"description": "The site area, in square meters"
|
|
25
|
+
},
|
|
26
|
+
"areaOfAllegedBreachInSquareMetres": {
|
|
27
|
+
"type": ["number", "null"],
|
|
28
|
+
"examples": [45.7],
|
|
29
|
+
"description": "Area of the alleged breach, in square meters"
|
|
30
|
+
},
|
|
31
|
+
"floorSpaceCreatedByBreachInSquareMetres": {
|
|
32
|
+
"type": ["number", "null"],
|
|
33
|
+
"examples": [45.7],
|
|
34
|
+
"description": "Floor space created by the breach, in square meters"
|
|
35
|
+
},
|
|
36
|
+
"relatesToErectionOfBuildingOrBuildings": {
|
|
37
|
+
"type": ["boolean", "null"]
|
|
38
|
+
},
|
|
39
|
+
"relatesToBuildingWithAgriculturalPurpose": {
|
|
40
|
+
"type": ["boolean", "null"]
|
|
41
|
+
},
|
|
42
|
+
"relatesToBuildingSingleDwellingHouse": {
|
|
43
|
+
"type": ["boolean", "null"]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
@@ -2,61 +2,20 @@
|
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"$id": "commands/appeals-components/lpa-questionnaire-enforcement.schema.json",
|
|
4
4
|
"title": "LPAQ Enforcement submission properties",
|
|
5
|
-
"description": "Schema defining any
|
|
5
|
+
"description": "Schema defining any enforcement specific properties for LPAQ submissions",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": true,
|
|
8
8
|
"required": [
|
|
9
|
-
"noticeRelatesToBuildingEngineeringMiningOther",
|
|
10
|
-
"siteAreaSquareMetres",
|
|
11
|
-
"changeOfUseRefuseOrWaste",
|
|
12
|
-
"changeOfUseMineralExtraction",
|
|
13
|
-
"changeOfUseMineralStorage",
|
|
14
|
-
"relatesToErectionOfBuildingOrBuildings",
|
|
15
|
-
"relatesToBuildingWithAgriculturalPurpose",
|
|
16
|
-
"relatesToBuildingSingleDwellingHouse",
|
|
17
9
|
"affectedTrunkRoadName",
|
|
18
10
|
"isSiteOnCrownLand",
|
|
19
|
-
"article4AffectedDevelopmentRights"
|
|
11
|
+
"article4AffectedDevelopmentRights",
|
|
12
|
+
"changeOfUseRefuseOrWaste",
|
|
13
|
+
"changeOfUseMineralExtraction",
|
|
14
|
+
"changeOfUseMineralStorage"
|
|
20
15
|
],
|
|
21
16
|
"allOf": [
|
|
22
17
|
{
|
|
23
18
|
"properties": {
|
|
24
|
-
"noticeRelatesToBuildingEngineeringMiningOther": {
|
|
25
|
-
"type": ["boolean", "null"]
|
|
26
|
-
},
|
|
27
|
-
"siteAreaSquareMetres": {
|
|
28
|
-
"type": ["number", "null"],
|
|
29
|
-
"examples": [45.7],
|
|
30
|
-
"description": "The site area, in square meters"
|
|
31
|
-
},
|
|
32
|
-
"areaOfAllegedBreachInSquareMetres": {
|
|
33
|
-
"type": ["number", "null"],
|
|
34
|
-
"examples": [45.7],
|
|
35
|
-
"description": "Area of the alleged breach, in square meters"
|
|
36
|
-
},
|
|
37
|
-
"floorSpaceCreatedByBreachInSquareMetres": {
|
|
38
|
-
"type": ["number", "null"],
|
|
39
|
-
"examples": [45.7],
|
|
40
|
-
"description": "Floor space created by the breach, in square meters"
|
|
41
|
-
},
|
|
42
|
-
"changeOfUseRefuseOrWaste": {
|
|
43
|
-
"type": ["boolean", "null"]
|
|
44
|
-
},
|
|
45
|
-
"changeOfUseMineralExtraction": {
|
|
46
|
-
"type": ["boolean", "null"]
|
|
47
|
-
},
|
|
48
|
-
"changeOfUseMineralStorage": {
|
|
49
|
-
"type": ["boolean", "null"]
|
|
50
|
-
},
|
|
51
|
-
"relatesToErectionOfBuildingOrBuildings": {
|
|
52
|
-
"type": ["boolean", "null"]
|
|
53
|
-
},
|
|
54
|
-
"relatesToBuildingWithAgriculturalPurpose": {
|
|
55
|
-
"type": ["boolean", "null"]
|
|
56
|
-
},
|
|
57
|
-
"relatesToBuildingSingleDwellingHouse": {
|
|
58
|
-
"type": ["boolean", "null"]
|
|
59
|
-
},
|
|
60
19
|
"affectedTrunkRoadName": {
|
|
61
20
|
"type": ["string", "null"],
|
|
62
21
|
"examples": ["Buckingham palace road"],
|
|
@@ -68,6 +27,15 @@
|
|
|
68
27
|
"article4AffectedDevelopmentRights": {
|
|
69
28
|
"type": ["string", "null"],
|
|
70
29
|
"description": "What permitted develpoment rights are affected by the Article 4 Direction"
|
|
30
|
+
},
|
|
31
|
+
"changeOfUseRefuseOrWaste": {
|
|
32
|
+
"type": ["boolean", "null"]
|
|
33
|
+
},
|
|
34
|
+
"changeOfUseMineralExtraction": {
|
|
35
|
+
"type": ["boolean", "null"]
|
|
36
|
+
},
|
|
37
|
+
"changeOfUseMineralStorage": {
|
|
38
|
+
"type": ["boolean", "null"]
|
|
71
39
|
}
|
|
72
40
|
}
|
|
73
41
|
}
|
|
@@ -71,9 +71,9 @@
|
|
|
71
71
|
]
|
|
72
72
|
},
|
|
73
73
|
{
|
|
74
|
-
"$comment": "Enforcement
|
|
74
|
+
"$comment": "Enforcement",
|
|
75
75
|
"allOf": [
|
|
76
|
-
{ "properties": { "caseType": { "enum": ["C"
|
|
76
|
+
{ "properties": { "caseType": { "enum": ["C"] } } },
|
|
77
77
|
{ "$ref": "appeals-components/lpa-questionnaire-common.schema.json" },
|
|
78
78
|
{ "$ref": "appeals-components/lpa-questionnaire-has.schema.json" },
|
|
79
79
|
{ "$ref": "appeals-components/lpa-procedure-preference.schema.json" },
|
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
{ "$ref": "appeals-components/infrastructure-levy.schema.json" },
|
|
82
82
|
{ "$ref": "appeals-components/environmental-impact-assessment.schema.json" },
|
|
83
83
|
{ "$ref": "appeals-components/site-designations-protection.schema.json" },
|
|
84
|
+
{ "$ref": "appeals-components/lpa-questionnaire-enforcement-common.schema.json" },
|
|
84
85
|
{ "$ref": "appeals-components/lpa-questionnaire-enforcement.schema.json" }
|
|
85
86
|
]
|
|
86
87
|
},
|
|
@@ -93,6 +94,21 @@
|
|
|
93
94
|
{ "$ref": "appeals-components/infrastructure-levy.schema.json" },
|
|
94
95
|
{ "$ref": "appeals-components/lpa-questionnaire-ldc.schema.json" }
|
|
95
96
|
]
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"$comment": "Enforcement listed building",
|
|
100
|
+
"allOf": [
|
|
101
|
+
{ "properties": { "caseType": { "enum": ["F"] } } },
|
|
102
|
+
{ "$ref": "appeals-components/lpa-questionnaire-common.schema.json" },
|
|
103
|
+
{ "$ref": "appeals-components/lpa-questionnaire-has.schema.json" },
|
|
104
|
+
{ "$ref": "appeals-components/lpa-procedure-preference.schema.json" },
|
|
105
|
+
{ "$ref": "appeals-components/changed-listed-building-number.schema.json" },
|
|
106
|
+
{ "$ref": "appeals-components/infrastructure-levy.schema.json" },
|
|
107
|
+
{ "$ref": "appeals-components/environmental-impact-assessment.schema.json" },
|
|
108
|
+
{ "$ref": "appeals-components/site-designations-protection.schema.json" },
|
|
109
|
+
{ "$ref": "appeals-components/lpa-questionnaire-enforcement-common.schema.json" },
|
|
110
|
+
{ "$ref": "appeals-components/lpa-questionnaire-listed-building.schema.json" }
|
|
111
|
+
]
|
|
96
112
|
}
|
|
97
113
|
]
|
|
98
114
|
},
|
package/src/enums.cjs
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const APPEAL_HAS_CASE_DECISION_OUTCOME = Object.freeze({
|
|
4
|
+
ALLOWED: 'allowed',
|
|
5
|
+
DISMISSED: 'dismissed',
|
|
6
|
+
INVALID: 'invalid',
|
|
7
|
+
SPLIT_DECISION: 'split_decision',
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const APPEAL_HAS_CASE_PROCEDURE = Object.freeze({
|
|
11
|
+
HEARING: 'hearing',
|
|
12
|
+
INQUIRY: 'inquiry',
|
|
13
|
+
WRITTEN: 'written',
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const APPEAL_HAS_CASE_STATUS = Object.freeze({
|
|
17
|
+
ASSIGN_CASE_OFFICER: 'assign_case_officer',
|
|
18
|
+
AWAITING_EVENT: 'awaiting_event',
|
|
19
|
+
AWAITING_TRANSFER: 'awaiting_transfer',
|
|
20
|
+
CLOSED: 'closed',
|
|
21
|
+
COMPLETE: 'complete',
|
|
22
|
+
EVENT: 'event',
|
|
23
|
+
INVALID: 'invalid',
|
|
24
|
+
ISSUE_DETERMINATION: 'issue_determination',
|
|
25
|
+
LPA_QUESTIONNAIRE: 'lpa_questionnaire',
|
|
26
|
+
READY_TO_START: 'ready_to_start',
|
|
27
|
+
TRANSFERRED: 'transferred',
|
|
28
|
+
VALIDATION: 'validation',
|
|
29
|
+
WITHDRAWN: 'withdrawn',
|
|
30
|
+
});
|
|
31
|
+
|
|
3
32
|
const APPEAL_ALLOCATION_LEVEL = Object.freeze({
|
|
4
33
|
A: 'A',
|
|
5
34
|
B: 'B',
|
|
@@ -410,6 +439,11 @@ const METHOD = Object.freeze({
|
|
|
410
439
|
POST: 'post',
|
|
411
440
|
});
|
|
412
441
|
|
|
442
|
+
const NSIP_PROJECT_SOURCE_SYSTEM = Object.freeze({
|
|
443
|
+
BACK_OFFICE_APPLICATIONS: 'back-office-applications',
|
|
444
|
+
HORIZON: 'horizon',
|
|
445
|
+
});
|
|
446
|
+
|
|
413
447
|
const NSIP_CA_AND_TP_EVIDENCE = Object.freeze({
|
|
414
448
|
AWAITING_SUBMISSION: 'awaiting_submission',
|
|
415
449
|
NOT_APPLICABLE: 'not_applicable',
|
|
@@ -655,8 +689,11 @@ const NSIP_SECURITY_CLASSIFICATION = Object.freeze({
|
|
|
655
689
|
});
|
|
656
690
|
|
|
657
691
|
const NSIP_SOURCE_SYSTEM = Object.freeze({
|
|
692
|
+
BACK_OFFICE_APPEALS: 'back-office-appeals',
|
|
658
693
|
BACK_OFFICE_APPLICATIONS: 'back-office-applications',
|
|
659
694
|
HORIZON: 'horizon',
|
|
695
|
+
NI_FILE: 'ni_file',
|
|
696
|
+
SHAREPOINT: 'sharepoint',
|
|
660
697
|
});
|
|
661
698
|
|
|
662
699
|
const NSIP_STAGE = Object.freeze({
|
|
@@ -762,6 +799,9 @@ exports.APPEAL_EIA_DEVELOPMENT_DESCRIPTION = APPEAL_EIA_DEVELOPMENT_DESCRIPTION;
|
|
|
762
799
|
exports.APPEAL_EIA_ENVIRONMENTAL_IMPACT_SCHEDULE = APPEAL_EIA_ENVIRONMENTAL_IMPACT_SCHEDULE;
|
|
763
800
|
exports.APPEAL_EVENT_STATUS = APPEAL_EVENT_STATUS;
|
|
764
801
|
exports.APPEAL_EVENT_TYPE = APPEAL_EVENT_TYPE;
|
|
802
|
+
exports.APPEAL_HAS_CASE_DECISION_OUTCOME = APPEAL_HAS_CASE_DECISION_OUTCOME;
|
|
803
|
+
exports.APPEAL_HAS_CASE_PROCEDURE = APPEAL_HAS_CASE_PROCEDURE;
|
|
804
|
+
exports.APPEAL_HAS_CASE_STATUS = APPEAL_HAS_CASE_STATUS;
|
|
765
805
|
exports.APPEAL_INVALID_OR_INCOMPLETE_DETAILS = APPEAL_INVALID_OR_INCOMPLETE_DETAILS;
|
|
766
806
|
exports.APPEAL_KNOWS_ALL_OWNERS = APPEAL_KNOWS_ALL_OWNERS;
|
|
767
807
|
exports.APPEAL_KNOWS_OTHER_OWNERS = APPEAL_KNOWS_OTHER_OWNERS;
|
|
@@ -797,6 +837,7 @@ exports.NSIP_ORIGIN = NSIP_ORIGIN;
|
|
|
797
837
|
exports.NSIP_PLANNING_INSPECTORATE_ROLE = NSIP_PLANNING_INSPECTORATE_ROLE;
|
|
798
838
|
exports.NSIP_POLICY_COMPLIANCE_DOCUMENT = NSIP_POLICY_COMPLIANCE_DOCUMENT;
|
|
799
839
|
exports.NSIP_PRINCIPAL_AREA_DISAGREEMENT_SUMMARY_STMT = NSIP_PRINCIPAL_AREA_DISAGREEMENT_SUMMARY_STMT;
|
|
840
|
+
exports.NSIP_PROJECT_SOURCE_SYSTEM = NSIP_PROJECT_SOURCE_SYSTEM;
|
|
800
841
|
exports.NSIP_PROJECT_TYPE = NSIP_PROJECT_TYPE;
|
|
801
842
|
exports.NSIP_PUBLIC_SECTOR_EQUALITY_DUTY = NSIP_PUBLIC_SECTOR_EQUALITY_DUTY;
|
|
802
843
|
exports.NSIP_PUBLISHED_STATUS = NSIP_PUBLISHED_STATUS;
|
package/src/enums.d.ts
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
export const APPEAL_HAS_CASE_DECISION_OUTCOME = {
|
|
2
|
+
ALLOWED: 'allowed',
|
|
3
|
+
DISMISSED: 'dismissed',
|
|
4
|
+
INVALID: 'invalid',
|
|
5
|
+
SPLIT_DECISION: 'split_decision',
|
|
6
|
+
} as const;
|
|
7
|
+
|
|
8
|
+
export const APPEAL_HAS_CASE_PROCEDURE = {
|
|
9
|
+
HEARING: 'hearing',
|
|
10
|
+
INQUIRY: 'inquiry',
|
|
11
|
+
WRITTEN: 'written',
|
|
12
|
+
} as const;
|
|
13
|
+
|
|
14
|
+
export const APPEAL_HAS_CASE_STATUS = {
|
|
15
|
+
ASSIGN_CASE_OFFICER: 'assign_case_officer',
|
|
16
|
+
AWAITING_EVENT: 'awaiting_event',
|
|
17
|
+
AWAITING_TRANSFER: 'awaiting_transfer',
|
|
18
|
+
CLOSED: 'closed',
|
|
19
|
+
COMPLETE: 'complete',
|
|
20
|
+
EVENT: 'event',
|
|
21
|
+
INVALID: 'invalid',
|
|
22
|
+
ISSUE_DETERMINATION: 'issue_determination',
|
|
23
|
+
LPA_QUESTIONNAIRE: 'lpa_questionnaire',
|
|
24
|
+
READY_TO_START: 'ready_to_start',
|
|
25
|
+
TRANSFERRED: 'transferred',
|
|
26
|
+
VALIDATION: 'validation',
|
|
27
|
+
WITHDRAWN: 'withdrawn',
|
|
28
|
+
} as const;
|
|
29
|
+
|
|
1
30
|
export const APPEAL_ALLOCATION_LEVEL = {
|
|
2
31
|
A: 'A',
|
|
3
32
|
B: 'B',
|
|
@@ -408,6 +437,11 @@ export const METHOD = {
|
|
|
408
437
|
POST: 'post',
|
|
409
438
|
} as const;
|
|
410
439
|
|
|
440
|
+
export const NSIP_PROJECT_SOURCE_SYSTEM = {
|
|
441
|
+
BACK_OFFICE_APPLICATIONS: 'back-office-applications',
|
|
442
|
+
HORIZON: 'horizon',
|
|
443
|
+
} as const;
|
|
444
|
+
|
|
411
445
|
export const NSIP_CA_AND_TP_EVIDENCE = {
|
|
412
446
|
AWAITING_SUBMISSION: 'awaiting_submission',
|
|
413
447
|
NOT_APPLICABLE: 'not_applicable',
|
|
@@ -653,8 +687,11 @@ export const NSIP_SECURITY_CLASSIFICATION = {
|
|
|
653
687
|
} as const;
|
|
654
688
|
|
|
655
689
|
export const NSIP_SOURCE_SYSTEM = {
|
|
690
|
+
BACK_OFFICE_APPEALS: 'back-office-appeals',
|
|
656
691
|
BACK_OFFICE_APPLICATIONS: 'back-office-applications',
|
|
657
692
|
HORIZON: 'horizon',
|
|
693
|
+
NI_FILE: 'ni_file',
|
|
694
|
+
SHAREPOINT: 'sharepoint',
|
|
658
695
|
} as const;
|
|
659
696
|
|
|
660
697
|
export const NSIP_STAGE = {
|
package/src/enums.js
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
export const APPEAL_HAS_CASE_DECISION_OUTCOME = Object.freeze({
|
|
2
|
+
ALLOWED: 'allowed',
|
|
3
|
+
DISMISSED: 'dismissed',
|
|
4
|
+
INVALID: 'invalid',
|
|
5
|
+
SPLIT_DECISION: 'split_decision',
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export const APPEAL_HAS_CASE_PROCEDURE = Object.freeze({
|
|
9
|
+
HEARING: 'hearing',
|
|
10
|
+
INQUIRY: 'inquiry',
|
|
11
|
+
WRITTEN: 'written',
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const APPEAL_HAS_CASE_STATUS = Object.freeze({
|
|
15
|
+
ASSIGN_CASE_OFFICER: 'assign_case_officer',
|
|
16
|
+
AWAITING_EVENT: 'awaiting_event',
|
|
17
|
+
AWAITING_TRANSFER: 'awaiting_transfer',
|
|
18
|
+
CLOSED: 'closed',
|
|
19
|
+
COMPLETE: 'complete',
|
|
20
|
+
EVENT: 'event',
|
|
21
|
+
INVALID: 'invalid',
|
|
22
|
+
ISSUE_DETERMINATION: 'issue_determination',
|
|
23
|
+
LPA_QUESTIONNAIRE: 'lpa_questionnaire',
|
|
24
|
+
READY_TO_START: 'ready_to_start',
|
|
25
|
+
TRANSFERRED: 'transferred',
|
|
26
|
+
VALIDATION: 'validation',
|
|
27
|
+
WITHDRAWN: 'withdrawn',
|
|
28
|
+
});
|
|
29
|
+
|
|
1
30
|
export const APPEAL_ALLOCATION_LEVEL = Object.freeze({
|
|
2
31
|
A: 'A',
|
|
3
32
|
B: 'B',
|
|
@@ -408,6 +437,11 @@ export const METHOD = Object.freeze({
|
|
|
408
437
|
POST: 'post',
|
|
409
438
|
});
|
|
410
439
|
|
|
440
|
+
export const NSIP_PROJECT_SOURCE_SYSTEM = Object.freeze({
|
|
441
|
+
BACK_OFFICE_APPLICATIONS: 'back-office-applications',
|
|
442
|
+
HORIZON: 'horizon',
|
|
443
|
+
});
|
|
444
|
+
|
|
411
445
|
export const NSIP_CA_AND_TP_EVIDENCE = Object.freeze({
|
|
412
446
|
AWAITING_SUBMISSION: 'awaiting_submission',
|
|
413
447
|
NOT_APPLICABLE: 'not_applicable',
|
|
@@ -653,8 +687,11 @@ export const NSIP_SECURITY_CLASSIFICATION = Object.freeze({
|
|
|
653
687
|
});
|
|
654
688
|
|
|
655
689
|
export const NSIP_SOURCE_SYSTEM = Object.freeze({
|
|
690
|
+
BACK_OFFICE_APPEALS: 'back-office-appeals',
|
|
656
691
|
BACK_OFFICE_APPLICATIONS: 'back-office-applications',
|
|
657
692
|
HORIZON: 'horizon',
|
|
693
|
+
NI_FILE: 'ni_file',
|
|
694
|
+
SHAREPOINT: 'sharepoint',
|
|
658
695
|
});
|
|
659
696
|
|
|
660
697
|
export const NSIP_STAGE = Object.freeze({
|
package/src/index.cjs
CHANGED
|
@@ -81,6 +81,35 @@ function loadSchemaSync(filePath) {
|
|
|
81
81
|
return jsoncParser.parse(content.toString());
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
const APPEAL_HAS_CASE_DECISION_OUTCOME = Object.freeze({
|
|
85
|
+
ALLOWED: 'allowed',
|
|
86
|
+
DISMISSED: 'dismissed',
|
|
87
|
+
INVALID: 'invalid',
|
|
88
|
+
SPLIT_DECISION: 'split_decision',
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const APPEAL_HAS_CASE_PROCEDURE = Object.freeze({
|
|
92
|
+
HEARING: 'hearing',
|
|
93
|
+
INQUIRY: 'inquiry',
|
|
94
|
+
WRITTEN: 'written',
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const APPEAL_HAS_CASE_STATUS = Object.freeze({
|
|
98
|
+
ASSIGN_CASE_OFFICER: 'assign_case_officer',
|
|
99
|
+
AWAITING_EVENT: 'awaiting_event',
|
|
100
|
+
AWAITING_TRANSFER: 'awaiting_transfer',
|
|
101
|
+
CLOSED: 'closed',
|
|
102
|
+
COMPLETE: 'complete',
|
|
103
|
+
EVENT: 'event',
|
|
104
|
+
INVALID: 'invalid',
|
|
105
|
+
ISSUE_DETERMINATION: 'issue_determination',
|
|
106
|
+
LPA_QUESTIONNAIRE: 'lpa_questionnaire',
|
|
107
|
+
READY_TO_START: 'ready_to_start',
|
|
108
|
+
TRANSFERRED: 'transferred',
|
|
109
|
+
VALIDATION: 'validation',
|
|
110
|
+
WITHDRAWN: 'withdrawn',
|
|
111
|
+
});
|
|
112
|
+
|
|
84
113
|
const APPEAL_ALLOCATION_LEVEL = Object.freeze({
|
|
85
114
|
A: 'A',
|
|
86
115
|
B: 'B',
|
|
@@ -491,6 +520,11 @@ const METHOD = Object.freeze({
|
|
|
491
520
|
POST: 'post',
|
|
492
521
|
});
|
|
493
522
|
|
|
523
|
+
const NSIP_PROJECT_SOURCE_SYSTEM = Object.freeze({
|
|
524
|
+
BACK_OFFICE_APPLICATIONS: 'back-office-applications',
|
|
525
|
+
HORIZON: 'horizon',
|
|
526
|
+
});
|
|
527
|
+
|
|
494
528
|
const NSIP_CA_AND_TP_EVIDENCE = Object.freeze({
|
|
495
529
|
AWAITING_SUBMISSION: 'awaiting_submission',
|
|
496
530
|
NOT_APPLICABLE: 'not_applicable',
|
|
@@ -736,8 +770,11 @@ const NSIP_SECURITY_CLASSIFICATION = Object.freeze({
|
|
|
736
770
|
});
|
|
737
771
|
|
|
738
772
|
const NSIP_SOURCE_SYSTEM = Object.freeze({
|
|
773
|
+
BACK_OFFICE_APPEALS: 'back-office-appeals',
|
|
739
774
|
BACK_OFFICE_APPLICATIONS: 'back-office-applications',
|
|
740
775
|
HORIZON: 'horizon',
|
|
776
|
+
NI_FILE: 'ni_file',
|
|
777
|
+
SHAREPOINT: 'sharepoint',
|
|
741
778
|
});
|
|
742
779
|
|
|
743
780
|
const NSIP_STAGE = Object.freeze({
|
|
@@ -875,6 +912,9 @@ exports.APPEAL_EIA_DEVELOPMENT_DESCRIPTION = APPEAL_EIA_DEVELOPMENT_DESCRIPTION;
|
|
|
875
912
|
exports.APPEAL_EIA_ENVIRONMENTAL_IMPACT_SCHEDULE = APPEAL_EIA_ENVIRONMENTAL_IMPACT_SCHEDULE;
|
|
876
913
|
exports.APPEAL_EVENT_STATUS = APPEAL_EVENT_STATUS;
|
|
877
914
|
exports.APPEAL_EVENT_TYPE = APPEAL_EVENT_TYPE;
|
|
915
|
+
exports.APPEAL_HAS_CASE_DECISION_OUTCOME = APPEAL_HAS_CASE_DECISION_OUTCOME;
|
|
916
|
+
exports.APPEAL_HAS_CASE_PROCEDURE = APPEAL_HAS_CASE_PROCEDURE;
|
|
917
|
+
exports.APPEAL_HAS_CASE_STATUS = APPEAL_HAS_CASE_STATUS;
|
|
878
918
|
exports.APPEAL_INVALID_OR_INCOMPLETE_DETAILS = APPEAL_INVALID_OR_INCOMPLETE_DETAILS;
|
|
879
919
|
exports.APPEAL_KNOWS_ALL_OWNERS = APPEAL_KNOWS_ALL_OWNERS;
|
|
880
920
|
exports.APPEAL_KNOWS_OTHER_OWNERS = APPEAL_KNOWS_OTHER_OWNERS;
|
|
@@ -910,6 +950,7 @@ exports.NSIP_ORIGIN = NSIP_ORIGIN;
|
|
|
910
950
|
exports.NSIP_PLANNING_INSPECTORATE_ROLE = NSIP_PLANNING_INSPECTORATE_ROLE;
|
|
911
951
|
exports.NSIP_POLICY_COMPLIANCE_DOCUMENT = NSIP_POLICY_COMPLIANCE_DOCUMENT;
|
|
912
952
|
exports.NSIP_PRINCIPAL_AREA_DISAGREEMENT_SUMMARY_STMT = NSIP_PRINCIPAL_AREA_DISAGREEMENT_SUMMARY_STMT;
|
|
953
|
+
exports.NSIP_PROJECT_SOURCE_SYSTEM = NSIP_PROJECT_SOURCE_SYSTEM;
|
|
913
954
|
exports.NSIP_PROJECT_TYPE = NSIP_PROJECT_TYPE;
|
|
914
955
|
exports.NSIP_PUBLIC_SECTOR_EQUALITY_DUTY = NSIP_PUBLIC_SECTOR_EQUALITY_DUTY;
|
|
915
956
|
exports.NSIP_PUBLISHED_STATUS = NSIP_PUBLISHED_STATUS;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import snakeCase from 'lodash.snakecase';
|
|
2
|
+
|
|
3
|
+
const SPACING = ' ';
|
|
4
|
+
const NEW_LINE = '\n';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Generate JS code to define exported constants for the given enum values
|
|
8
|
+
*
|
|
9
|
+
* @param {string} name
|
|
10
|
+
* @param {string[]} values
|
|
11
|
+
* @param {Object} opts
|
|
12
|
+
* @param {boolean} [opts.ts] - whether to generate the TS type or JS code
|
|
13
|
+
* @returns {string}
|
|
14
|
+
*/
|
|
15
|
+
export function generateConstants(name, values, { ts = false } = {}) {
|
|
16
|
+
const freezeStart = ts ? '' : 'Object.freeze(';
|
|
17
|
+
const freezeEnd = ts ? ' as const' : ')';
|
|
18
|
+
const exportPrefix = 'export ';
|
|
19
|
+
const lines = [`${exportPrefix}const ${formatName(name)} = ${freezeStart}{`];
|
|
20
|
+
/**
|
|
21
|
+
* @param {string} line
|
|
22
|
+
* @param {number} spacing
|
|
23
|
+
*/
|
|
24
|
+
const addWithSpace = (line, spacing = 0) => lines.push(SPACING.repeat(spacing) + line);
|
|
25
|
+
|
|
26
|
+
for (const value of values.sort()) {
|
|
27
|
+
addWithSpace(`${formatName(value)}: '${value}',`, 1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
lines.push(`}${freezeEnd};`);
|
|
31
|
+
|
|
32
|
+
return lines.join(NEW_LINE);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Format a name for use as a constant value: UPPER_SNAKE_CASE
|
|
37
|
+
*
|
|
38
|
+
* @param {string} name
|
|
39
|
+
* @returns {string}
|
|
40
|
+
*/
|
|
41
|
+
function formatName(name) {
|
|
42
|
+
return snakeCase(name).toUpperCase();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {{schemaName: string, key: string, values: string[]}[]} enums
|
|
47
|
+
* @returns {Record<string, string[]>} map of enum name to values
|
|
48
|
+
*/
|
|
49
|
+
export function generateEnumMap(enums) {
|
|
50
|
+
/** @type {Object<string, string[]>} */
|
|
51
|
+
const enumProps = {};
|
|
52
|
+
|
|
53
|
+
// only allow one duplicate - else the superset logic gets complex
|
|
54
|
+
const duplicateKeys = new Set();
|
|
55
|
+
const warnings = [];
|
|
56
|
+
const infos = [];
|
|
57
|
+
|
|
58
|
+
for (const e of enums) {
|
|
59
|
+
const prefix = schemaPrefix(e.schemaName);
|
|
60
|
+
const key = prefix ? prefix + '_' + e.key : e.key;
|
|
61
|
+
|
|
62
|
+
const existingEnum = enumProps[key];
|
|
63
|
+
const thisEnum = e.values;
|
|
64
|
+
if (!existingEnum) {
|
|
65
|
+
enumProps[key] = e.values;
|
|
66
|
+
} else if (!enumsMatch(existingEnum, thisEnum)) {
|
|
67
|
+
const existingEnumProps = enums.find((e) => e.values === existingEnum);
|
|
68
|
+
const setIndex = indexOfSuperset(existingEnum, thisEnum);
|
|
69
|
+
// handle duplicate enums - but one must be a superset of the other
|
|
70
|
+
if (setIndex === -1) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
`Enums ${existingEnumProps.key} from ${existingEnumProps.schemaName} and ${e.key} from ${e.schemaName} have the same name but one is not a superset of the other`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
// and only allow one duplicate
|
|
76
|
+
if (duplicateKeys.has(key)) {
|
|
77
|
+
throw new Error(
|
|
78
|
+
`enum ${e.key} is used by multiple schemas, including ${existingEnumProps.schemaName} and ${e.schemaName}`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
duplicateKeys.add(key);
|
|
82
|
+
warnings.push([
|
|
83
|
+
'⚠️ enum key',
|
|
84
|
+
key,
|
|
85
|
+
'is used with different values in',
|
|
86
|
+
existingEnumProps.schemaName,
|
|
87
|
+
'and',
|
|
88
|
+
e.schemaName
|
|
89
|
+
]);
|
|
90
|
+
|
|
91
|
+
if (setIndex === 1) {
|
|
92
|
+
// existing enum is the superset
|
|
93
|
+
// so this enum goes with a specific name
|
|
94
|
+
enumProps[e.schemaName.replace('.schema.json', '') + '_' + e.key] = e.values;
|
|
95
|
+
} else if (setIndex === 2) {
|
|
96
|
+
// this enum is the superset
|
|
97
|
+
// so 'swap in' this enum
|
|
98
|
+
enumProps[key] = e.values;
|
|
99
|
+
enumProps[existingEnumProps.schemaName.replace('.schema.json', '') + '_' + existingEnumProps.key] =
|
|
100
|
+
existingEnumProps.values;
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
// if the enums do match, nothing to change
|
|
104
|
+
infos.push(['ℹ️ enum key', key, 'is used multiple times but uses the same values']);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
for (const info of infos) {
|
|
108
|
+
console.log(...info);
|
|
109
|
+
}
|
|
110
|
+
for (const warning of warnings) {
|
|
111
|
+
console.log(...warning);
|
|
112
|
+
}
|
|
113
|
+
return enumProps;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Do list1 and list2 match?
|
|
118
|
+
*
|
|
119
|
+
* @param {string[]} list1
|
|
120
|
+
* @param {string[]} list2
|
|
121
|
+
*/
|
|
122
|
+
export function enumsMatch(list1, list2) {
|
|
123
|
+
const set1 = new Set(list1);
|
|
124
|
+
const set2 = new Set(list2);
|
|
125
|
+
// get all elements that are in set1 or set2 but not in both
|
|
126
|
+
// if there are none, they match
|
|
127
|
+
return set1.symmetricDifference(set2).size === 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Is list1 a superset of list2, or vice versa?
|
|
132
|
+
*
|
|
133
|
+
* @param {string[]} list1
|
|
134
|
+
* @param {string[]} list2
|
|
135
|
+
* @returns {1 | 2 | -1} -1 if neither list is a superset of the other
|
|
136
|
+
*/
|
|
137
|
+
export function indexOfSuperset(list1, list2) {
|
|
138
|
+
const set1 = new Set(list1);
|
|
139
|
+
const set2 = new Set(list2);
|
|
140
|
+
if (set1.isSupersetOf(set2)) {
|
|
141
|
+
return 1;
|
|
142
|
+
}
|
|
143
|
+
if (set2.isSupersetOf(set1)) {
|
|
144
|
+
return 2;
|
|
145
|
+
}
|
|
146
|
+
return -1;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
*
|
|
151
|
+
* @param {{schemaName: string, key: string, values: string[]}[]} enums
|
|
152
|
+
* @param {Object<string, {type?: string|string[], enum?: string[]}>} properties
|
|
153
|
+
* @param {string} schemaName
|
|
154
|
+
*/
|
|
155
|
+
export function collectEnumProps(enums, properties = {}, schemaName) {
|
|
156
|
+
for (const [key, prop] of Object.entries(properties)) {
|
|
157
|
+
const hasStringEnum = (p) =>
|
|
158
|
+
p && p.enum && Array.isArray(p.enum) && p.type && (p.type === 'string' || p.type.includes('string'));
|
|
159
|
+
const getEnumValues = (p) => p.filter((e) => e !== null);
|
|
160
|
+
const collectEnumFromProp = (p) => {
|
|
161
|
+
if (hasStringEnum(p)) {
|
|
162
|
+
const values = getEnumValues(p.enum);
|
|
163
|
+
const asSet = new Set(values);
|
|
164
|
+
if (values.length > asSet.size) {
|
|
165
|
+
throw new Error(`enum ${key} from ${schemaName} has duplicate elements`);
|
|
166
|
+
}
|
|
167
|
+
enums.push({
|
|
168
|
+
schemaName,
|
|
169
|
+
key,
|
|
170
|
+
values: values
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
collectEnumFromProp(prop);
|
|
176
|
+
collectEnumFromProp(prop.items);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Generate a prefix based on the schema name
|
|
182
|
+
*
|
|
183
|
+
* @param {string} schemaName
|
|
184
|
+
* @returns {string|undefined}
|
|
185
|
+
*/
|
|
186
|
+
export function schemaPrefix(schemaName) {
|
|
187
|
+
if (schemaName === 'message') {
|
|
188
|
+
return 'message';
|
|
189
|
+
}
|
|
190
|
+
if (schemaName.toLowerCase().includes('appeal')) {
|
|
191
|
+
return 'appeal';
|
|
192
|
+
}
|
|
193
|
+
if (schemaName.toLowerCase().includes('nsip')) {
|
|
194
|
+
return 'nsip';
|
|
195
|
+
}
|
|
196
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import { collectEnumProps, generateConstants, generateEnumMap } from './gen-enum-impl.js';
|
|
3
|
+
import assert from 'node:assert';
|
|
4
|
+
|
|
5
|
+
describe('gen-enum-impl', () => {
|
|
6
|
+
describe('generateConstants', () => {
|
|
7
|
+
it('should generate constant definitions', () => {
|
|
8
|
+
const output = generateConstants('some_EnumValue', ['value-1', 'other-value', 'a-third-value']);
|
|
9
|
+
assert.strictEqual(
|
|
10
|
+
output,
|
|
11
|
+
`export const SOME_ENUM_VALUE = Object.freeze({\n A_THIRD_VALUE: 'a-third-value',\n OTHER_VALUE: 'other-value',\n VALUE_1: 'value-1',\n});`
|
|
12
|
+
);
|
|
13
|
+
});
|
|
14
|
+
it('should generate constant definitions as typescript', () => {
|
|
15
|
+
const output = generateConstants('some_EnumValue', ['value-1', 'other-value', 'a-third-value'], { ts: true });
|
|
16
|
+
assert.strictEqual(
|
|
17
|
+
output,
|
|
18
|
+
`export const SOME_ENUM_VALUE = {\n A_THIRD_VALUE: 'a-third-value',\n OTHER_VALUE: 'other-value',\n VALUE_1: 'value-1',\n} as const;`
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('generateEnumMap', () => {
|
|
24
|
+
it('should add all enums to a map by key with prefix', () => {
|
|
25
|
+
const enums = [
|
|
26
|
+
{
|
|
27
|
+
schemaName: 'schema-1',
|
|
28
|
+
key: 'key3',
|
|
29
|
+
values: ['enum-1', 'enum-2']
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
schemaName: 'appeal-1.schema.json',
|
|
33
|
+
key: 'key5',
|
|
34
|
+
values: ['enum-4', 'enum-5']
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
schemaName: 'nsip-1.schema.json',
|
|
38
|
+
key: 'key5',
|
|
39
|
+
values: ['enum-6', 'enum-7']
|
|
40
|
+
}
|
|
41
|
+
];
|
|
42
|
+
const map = generateEnumMap(enums);
|
|
43
|
+
assert.deepStrictEqual(map, {
|
|
44
|
+
appeal_key5: ['enum-4', 'enum-5'],
|
|
45
|
+
nsip_key5: ['enum-6', 'enum-7'],
|
|
46
|
+
key3: ['enum-1', 'enum-2']
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
it('should ignore duplicates if the enums match', () => {
|
|
50
|
+
const enums = [
|
|
51
|
+
{
|
|
52
|
+
schemaName: 'schema-1',
|
|
53
|
+
key: 'key3',
|
|
54
|
+
values: ['enum-1', 'enum-2']
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
schemaName: 'appeal-1.schema.json',
|
|
58
|
+
key: 'key5',
|
|
59
|
+
values: ['enum-4', 'enum-5']
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
schemaName: 'appeal-2.schema.json',
|
|
63
|
+
key: 'key5',
|
|
64
|
+
values: ['enum-4', 'enum-5']
|
|
65
|
+
}
|
|
66
|
+
];
|
|
67
|
+
const map = generateEnumMap(enums);
|
|
68
|
+
assert.deepStrictEqual(map, {
|
|
69
|
+
appeal_key5: ['enum-4', 'enum-5'],
|
|
70
|
+
key3: ['enum-1', 'enum-2']
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
it('should add a more specific prefix if there is a duplicate key', () => {
|
|
74
|
+
const enums = [
|
|
75
|
+
{
|
|
76
|
+
schemaName: 'schema-1',
|
|
77
|
+
key: 'key3',
|
|
78
|
+
values: ['enum-1', 'enum-2']
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
schemaName: 'appeal-1.schema.json',
|
|
82
|
+
key: 'key5',
|
|
83
|
+
values: ['enum-4', 'enum-5']
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
schemaName: 'appeal-2.schema.json',
|
|
87
|
+
key: 'key5',
|
|
88
|
+
values: ['enum-4', 'enum-5', 'enum-6']
|
|
89
|
+
}
|
|
90
|
+
];
|
|
91
|
+
const map = generateEnumMap(enums);
|
|
92
|
+
assert.deepStrictEqual(map, {
|
|
93
|
+
appeal_key5: ['enum-4', 'enum-5', 'enum-6'],
|
|
94
|
+
'appeal-1_key5': ['enum-4', 'enum-5'],
|
|
95
|
+
key3: ['enum-1', 'enum-2']
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
it('should error if duplicate key enums are not a superset', () => {
|
|
99
|
+
const enums = [
|
|
100
|
+
{
|
|
101
|
+
schemaName: 'schema-1',
|
|
102
|
+
key: 'key3',
|
|
103
|
+
values: ['enum-1', 'enum-2']
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
schemaName: 'appeal-1.schema.json',
|
|
107
|
+
key: 'key5',
|
|
108
|
+
values: ['enum-4', 'enum-5']
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
schemaName: 'appeal-2.schema.json',
|
|
112
|
+
key: 'key5',
|
|
113
|
+
values: ['enum-4', 'enum-6']
|
|
114
|
+
}
|
|
115
|
+
];
|
|
116
|
+
assert.throws(() => generateEnumMap(enums), { message: /not a superset of the other/ });
|
|
117
|
+
});
|
|
118
|
+
it('should error if duplicate keys are present more than twice', () => {
|
|
119
|
+
const enums = [
|
|
120
|
+
{
|
|
121
|
+
schemaName: 'schema-1',
|
|
122
|
+
key: 'key3',
|
|
123
|
+
values: ['enum-1', 'enum-2']
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
schemaName: 'appeal-1.schema.json',
|
|
127
|
+
key: 'key5',
|
|
128
|
+
values: ['enum-4', 'enum-5']
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
schemaName: 'appeal-2.schema.json',
|
|
132
|
+
key: 'key5',
|
|
133
|
+
values: ['enum-4', 'enum-5', 'enum-6']
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
schemaName: 'appeal-2.schema.json',
|
|
137
|
+
key: 'key5',
|
|
138
|
+
values: ['enum-4', 'enum-5', 'enum-6', 'enum-7']
|
|
139
|
+
}
|
|
140
|
+
];
|
|
141
|
+
assert.throws(() => generateEnumMap(enums), { message: /used by multiple schemas/ });
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
describe('collectEnumProps', () => {
|
|
146
|
+
it('should collect all enums', () => {
|
|
147
|
+
const enums = [];
|
|
148
|
+
collectEnumProps(
|
|
149
|
+
enums,
|
|
150
|
+
{
|
|
151
|
+
key1: 'value-1',
|
|
152
|
+
key2: 'other-value',
|
|
153
|
+
key3: {
|
|
154
|
+
type: 'string',
|
|
155
|
+
enum: ['enum-1', 'enum-2']
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
'schema-1'
|
|
159
|
+
);
|
|
160
|
+
collectEnumProps(
|
|
161
|
+
enums,
|
|
162
|
+
{
|
|
163
|
+
key5: {
|
|
164
|
+
type: 'string',
|
|
165
|
+
enum: ['enum-4', 'enum-5']
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
'appeal-1.schema.json'
|
|
169
|
+
);
|
|
170
|
+
assert.strictEqual(enums.length, 2);
|
|
171
|
+
assert.deepStrictEqual(enums[0], {
|
|
172
|
+
schemaName: 'schema-1',
|
|
173
|
+
key: 'key3',
|
|
174
|
+
values: ['enum-1', 'enum-2']
|
|
175
|
+
});
|
|
176
|
+
assert.deepStrictEqual(enums[1], {
|
|
177
|
+
schemaName: 'appeal-1.schema.json',
|
|
178
|
+
key: 'key5',
|
|
179
|
+
values: ['enum-4', 'enum-5']
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
});
|
package/src/lib/gen-enums.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import url from 'url';
|
|
4
3
|
import { loadAllSchemas } from '../index.js';
|
|
5
|
-
import snakeCase from 'lodash.snakecase';
|
|
6
4
|
import { loadSchema } from './load.js';
|
|
5
|
+
import { collectEnumProps, generateConstants, generateEnumMap } from './gen-enum-impl.js';
|
|
7
6
|
|
|
8
|
-
const __dirname =
|
|
7
|
+
const __dirname = import.meta.dirname;
|
|
9
8
|
|
|
10
9
|
export const constPath = path.join(__dirname, '..', 'enums.js');
|
|
11
10
|
export const constTsPath = path.join(__dirname, '..', 'enums.d.ts');
|
|
12
11
|
|
|
13
|
-
const SPACING = ' ';
|
|
14
12
|
const NEW_LINE = '\n';
|
|
15
13
|
|
|
16
14
|
/**
|
|
@@ -19,16 +17,17 @@ const NEW_LINE = '\n';
|
|
|
19
17
|
async function run() {
|
|
20
18
|
const s = await loadAllSchemas();
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
const enumProps = {};
|
|
20
|
+
const allEnums = [];
|
|
24
21
|
|
|
25
22
|
for (const schemaName of Object.keys(s.schemas).sort()) {
|
|
26
23
|
const schema = s.schemas[schemaName];
|
|
27
|
-
collectEnumProps(
|
|
24
|
+
collectEnumProps(allEnums, schema.properties, schemaName);
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
const staticEnums = await loadSchema(path.join(__dirname, 'enums-static.schema.json'));
|
|
31
|
-
collectEnumProps(
|
|
28
|
+
collectEnumProps(allEnums, staticEnums.properties, 'message');
|
|
29
|
+
|
|
30
|
+
const enumProps = generateEnumMap(allEnums);
|
|
32
31
|
|
|
33
32
|
let output = '';
|
|
34
33
|
let tsOutput = '';
|
|
@@ -42,82 +41,7 @@ async function run() {
|
|
|
42
41
|
await fs.writeFile(constTsPath, tsOutput);
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
* @param {string[]} values
|
|
50
|
-
* @param {Object} opts
|
|
51
|
-
* @param {boolean} [opts.ts] - whether to generate the TS type or JS code
|
|
52
|
-
* @returns {string}
|
|
53
|
-
*/
|
|
54
|
-
function generateConstants(name, values, { ts = false } = {}) {
|
|
55
|
-
const freezeStart = ts ? '' : 'Object.freeze(';
|
|
56
|
-
const freezeEnd = ts ? ' as const' : ')';
|
|
57
|
-
const exportPrefix = 'export ';
|
|
58
|
-
const lines = [`${exportPrefix}const ${formatName(name)} = ${freezeStart}{`];
|
|
59
|
-
/**
|
|
60
|
-
* @param {string} line
|
|
61
|
-
* @param {number} spacing
|
|
62
|
-
*/
|
|
63
|
-
const addWithSpace = (line, spacing = 0) => lines.push(SPACING.repeat(spacing) + line);
|
|
64
|
-
|
|
65
|
-
for (const value of values.sort()) {
|
|
66
|
-
addWithSpace(`${formatName(value)}: '${value}',`, 1);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
lines.push(`}${freezeEnd};`);
|
|
70
|
-
|
|
71
|
-
return lines.join(NEW_LINE);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Format a name for use as a constant value: UPPER_SNAKE_CASE
|
|
76
|
-
*
|
|
77
|
-
* @param {string} name
|
|
78
|
-
* @returns {string}
|
|
79
|
-
*/
|
|
80
|
-
function formatName(name) {
|
|
81
|
-
return snakeCase(name).toUpperCase();
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
*
|
|
86
|
-
* @param {Object<string, string[]>} map
|
|
87
|
-
* @param {Object<string, {type?: string|string[], enum?: string[]}>} properties
|
|
88
|
-
* @param {string} [prefix]
|
|
89
|
-
*/
|
|
90
|
-
function collectEnumProps(map, properties = {}, prefix) {
|
|
91
|
-
for (const [key, prop] of Object.entries(properties)) {
|
|
92
|
-
const name = prefix ? prefix + '_' + key : key;
|
|
93
|
-
|
|
94
|
-
const hasStringEnum = (p) =>
|
|
95
|
-
p && p.enum && Array.isArray(p.enum) && p.type && (p.type === 'string' || p.type.includes('string'));
|
|
96
|
-
const getEnumValues = (p) => p.filter((e) => e !== null);
|
|
97
|
-
const collectEnumFromProp = (p) => {
|
|
98
|
-
if (hasStringEnum(p)) {
|
|
99
|
-
map[name] = getEnumValues(p.enum);
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
collectEnumFromProp(prop);
|
|
104
|
-
collectEnumFromProp(prop.items);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Generate a prefix based on the schema name
|
|
110
|
-
*
|
|
111
|
-
* @param {string} schemaName
|
|
112
|
-
* @returns {string|undefined}
|
|
113
|
-
*/
|
|
114
|
-
function schemaPrefix(schemaName) {
|
|
115
|
-
if (schemaName.toLowerCase().includes('appeal')) {
|
|
116
|
-
return 'appeal';
|
|
117
|
-
}
|
|
118
|
-
if (schemaName.toLowerCase().includes('nsip')) {
|
|
119
|
-
return 'nsip';
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
run().catch(console.error);
|
|
44
|
+
run().catch((err) => {
|
|
45
|
+
console.error(err);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
});
|
package/src/schemas.d.ts
CHANGED
|
@@ -4613,9 +4613,9 @@ export type LPAQCasAdvertSubmissionProperties = {
|
|
|
4613
4613
|
didAppellantSubmitCompletePhotosAndPlans?: boolean | null;
|
|
4614
4614
|
};
|
|
4615
4615
|
/**
|
|
4616
|
-
* Schema defining any
|
|
4616
|
+
* Schema defining any common enforcement specific properties for LPAQ submissions
|
|
4617
4617
|
*/
|
|
4618
|
-
export type
|
|
4618
|
+
export type LPAQEnforcementCommonSubmissionProperties = {
|
|
4619
4619
|
noticeRelatesToBuildingEngineeringMiningOther?: boolean | null;
|
|
4620
4620
|
/**
|
|
4621
4621
|
* The site area, in square meters
|
|
@@ -4629,12 +4629,14 @@ export type LPAQEnforcementSubmissionProperties = {
|
|
|
4629
4629
|
* Floor space created by the breach, in square meters
|
|
4630
4630
|
*/
|
|
4631
4631
|
floorSpaceCreatedByBreachInSquareMetres?: number | null;
|
|
4632
|
-
changeOfUseRefuseOrWaste?: boolean | null;
|
|
4633
|
-
changeOfUseMineralExtraction?: boolean | null;
|
|
4634
|
-
changeOfUseMineralStorage?: boolean | null;
|
|
4635
4632
|
relatesToErectionOfBuildingOrBuildings?: boolean | null;
|
|
4636
4633
|
relatesToBuildingWithAgriculturalPurpose?: boolean | null;
|
|
4637
4634
|
relatesToBuildingSingleDwellingHouse?: boolean | null;
|
|
4635
|
+
};
|
|
4636
|
+
/**
|
|
4637
|
+
* Schema defining any enforcement specific properties for LPAQ submissions
|
|
4638
|
+
*/
|
|
4639
|
+
export type LPAQEnforcementSubmissionProperties = {
|
|
4638
4640
|
/**
|
|
4639
4641
|
* Name of trunk road within 67M of site
|
|
4640
4642
|
*/
|
|
@@ -4644,6 +4646,9 @@ export type LPAQEnforcementSubmissionProperties = {
|
|
|
4644
4646
|
* What permitted develpoment rights are affected by the Article 4 Direction
|
|
4645
4647
|
*/
|
|
4646
4648
|
article4AffectedDevelopmentRights?: string | null;
|
|
4649
|
+
changeOfUseRefuseOrWaste?: boolean | null;
|
|
4650
|
+
changeOfUseMineralExtraction?: boolean | null;
|
|
4651
|
+
changeOfUseMineralStorage?: boolean | null;
|
|
4647
4652
|
};
|
|
4648
4653
|
/**
|
|
4649
4654
|
* Schema defining any LDC specific properties for LPAQ submissions
|
|
@@ -4705,7 +4710,7 @@ export interface LPAQuestionnaireCommand {
|
|
|
4705
4710
|
LPAProcedurePreferenceProperties &
|
|
4706
4711
|
ChangedListedBuildingNumbersProperties)
|
|
4707
4712
|
| ({
|
|
4708
|
-
caseType?: 'C'
|
|
4713
|
+
caseType?: 'C';
|
|
4709
4714
|
} & LPAQCommonSubmissionProperties &
|
|
4710
4715
|
LPAQHASSubmissionProperties &
|
|
4711
4716
|
LPAProcedurePreferenceProperties &
|
|
@@ -4713,13 +4718,25 @@ export interface LPAQuestionnaireCommand {
|
|
|
4713
4718
|
InfrastructureLevyProperties &
|
|
4714
4719
|
EnvironmentalImpactAssessmentProperties &
|
|
4715
4720
|
SiteDesignationsAndProtectionSpecificProperties &
|
|
4721
|
+
LPAQEnforcementCommonSubmissionProperties &
|
|
4716
4722
|
LPAQEnforcementSubmissionProperties)
|
|
4717
4723
|
| ({
|
|
4718
4724
|
caseType?: 'X';
|
|
4719
4725
|
} & LPAQCommonSubmissionProperties &
|
|
4720
4726
|
LPAProcedurePreferenceProperties &
|
|
4721
4727
|
InfrastructureLevyProperties &
|
|
4722
|
-
LPAQLDCSubmissionProperties)
|
|
4728
|
+
LPAQLDCSubmissionProperties)
|
|
4729
|
+
| ({
|
|
4730
|
+
caseType?: 'F';
|
|
4731
|
+
} & LPAQCommonSubmissionProperties &
|
|
4732
|
+
LPAQHASSubmissionProperties &
|
|
4733
|
+
LPAProcedurePreferenceProperties &
|
|
4734
|
+
ChangedListedBuildingNumbersProperties &
|
|
4735
|
+
InfrastructureLevyProperties &
|
|
4736
|
+
EnvironmentalImpactAssessmentProperties &
|
|
4737
|
+
SiteDesignationsAndProtectionSpecificProperties &
|
|
4738
|
+
LPAQEnforcementCommonSubmissionProperties &
|
|
4739
|
+
LPAQListedBuildingSubmissionProperties);
|
|
4723
4740
|
documents: {
|
|
4724
4741
|
/**
|
|
4725
4742
|
* The unique identifier for the document
|
|
@@ -63,17 +63,13 @@ const exampleEnforcementListedQuestionnaireSchema = {
|
|
|
63
63
|
lpaProcedurePreferenceDuration: -34480053.16630782,
|
|
64
64
|
noticeRelatesToBuildingEngineeringMiningOther: null,
|
|
65
65
|
siteAreaSquareMetres: null,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
changeOfUseRefuseOrWaste: null,
|
|
69
|
-
changeOfUseMineralExtraction: null,
|
|
70
|
-
changeOfUseMineralStorage: null,
|
|
66
|
+
areaOfAllegedBreachInSquareMetres: null,
|
|
67
|
+
floorSpaceCreatedByBreachInSquareMetres: null,
|
|
71
68
|
relatesToErectionOfBuildingOrBuildings: null,
|
|
72
69
|
relatesToBuildingWithAgriculturalPurpose: null,
|
|
73
70
|
relatesToBuildingSingleDwellingHouse: null,
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
article4AffectedDevelopmentRights: null
|
|
71
|
+
preserveGrantLoan: null,
|
|
72
|
+
consultHistoricEngland: null
|
|
77
73
|
},
|
|
78
74
|
documents: [document]
|
|
79
75
|
};
|
|
@@ -63,8 +63,8 @@ const exampleEnforcementQuestionnaireSchema = {
|
|
|
63
63
|
lpaProcedurePreferenceDuration: -34480053.16630782,
|
|
64
64
|
noticeRelatesToBuildingEngineeringMiningOther: null,
|
|
65
65
|
siteAreaSquareMetres: null,
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
areaOfAllegedBreachInSquareMetres: null,
|
|
67
|
+
floorSpaceCreatedByBreachInSquareMetres: null,
|
|
68
68
|
changeOfUseRefuseOrWaste: null,
|
|
69
69
|
changeOfUseMineralExtraction: null,
|
|
70
70
|
changeOfUseMineralStorage: null,
|