@tracepass/dpp-schemas 0.1.0 → 0.2.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/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](./LICENSE)
12
12
  [![npm](https://img.shields.io/npm/v/@tracepass/dpp-schemas.svg)](https://www.npmjs.com/package/@tracepass/dpp-schemas)
13
- [![Fields](https://img.shields.io/badge/fields-913-informational)](#whats-in-here)
13
+ [![Fields](https://img.shields.io/badge/fields-935-informational)](#whats-in-here)
14
14
  [![Categories](https://img.shields.io/badge/categories-12-informational)](#whats-in-here)
15
15
  [![Dependencies](https://img.shields.io/badge/dependencies-none-success)](#no-build-step)
16
16
  [![Schema](https://img.shields.io/badge/JSON%20Schema-2020--12-orange)](./schema.json)
@@ -39,12 +39,12 @@ this repository contains.
39
39
 
40
40
  ## What's in here
41
41
 
42
- Twelve JSON files, one per product category. **913 fields in total. 343 are required by an instrument in force;
43
- 187 are anticipated under a rule that has not yet been adopted.**
42
+ Twelve JSON files, one per product category. **935 fields in total. 307 are required by an instrument in force;
43
+ 198 are anticipated under a rule that has not yet been adopted.**
44
44
 
45
45
  | Category | Fields | Required | Instrument |
46
46
  |---|---:|---:|---|
47
- | `battery` | 95 | 95 | Regulation (EU) 2023/1542 |
47
+ | `battery` | 117 | 59 | Regulation (EU) 2023/1542 |
48
48
  | `chemicals` | 96 | 28 | ESPR (EU) 2024/1781 |
49
49
  | `construction` | 49 | 43 | CPR (EU) 2024/3110 |
50
50
  | `electronics` | 167 | 20 | ESPR (EU) 2024/1781 |
@@ -66,6 +66,16 @@ flows through a delegated act adopted under its Article 4. No product-group dele
66
66
  has been adopted. Fields expected under a future act carry `validation.anticipated`
67
67
  rather than `required`, with the CELEX of the instrument expected to impose them.
68
68
 
69
+ **An obligation does not always apply uniformly across a category.** Where the governing
70
+ instrument distinguishes sub-categories, the field carries `validation.requiredBy` — a map
71
+ from sub-category to `required`, `conditional`, or `notApplicable`. Battery uses the
72
+ Regulation (EU) 2023/1542 split (`EV`, `LMT`, `industrial_gt_2kwh`): everything applies to
73
+ EV batteries, LMT is exempt from the capacity-threshold-for-exhaustion field, and industrial
74
+ batteries are largely conditional on gates such as having a battery management system or
75
+ containing Annex X materials. `conditional` means the instrument compels the field only when
76
+ its stated gate is met — so a passport legitimately leaves it empty otherwise. Fields with no
77
+ `requiredBy` apply to the whole category.
78
+
69
79
  ## What a field looks like
70
80
 
71
81
  ```jsonc
package/index.json CHANGED
@@ -7,22 +7,23 @@
7
7
  },
8
8
  "totals": {
9
9
  "categories": 12,
10
- "fields": 913,
11
- "requiredFields": 343,
12
- "anticipatedFields": 187
10
+ "fields": 935,
11
+ "requiredFields": 307,
12
+ "anticipatedFields": 198
13
13
  },
14
14
  "categories": [
15
15
  {
16
16
  "category": "battery",
17
17
  "label": "Battery",
18
18
  "file": "templates/battery.json",
19
- "version": 2,
20
- "fieldCount": 95,
21
- "requiredFieldCount": 95,
22
- "anticipatedFieldCount": 0,
19
+ "version": 3,
20
+ "fieldCount": 117,
21
+ "requiredFieldCount": 59,
22
+ "anticipatedFieldCount": 11,
23
23
  "regulation": {
24
24
  "name": "EU Battery Regulation",
25
25
  "number": "(EU) 2023/1542",
26
+ "effectiveDate": "2027-02-18",
26
27
  "mandatoryDate": "2027-02-18"
27
28
  }
28
29
  },
@@ -37,6 +38,7 @@
37
38
  "regulation": {
38
39
  "name": "EU ESPR - Chemicals",
39
40
  "number": "(EU) 2024/1781",
41
+ "effectiveDate": "2029-09-01",
40
42
  "mandatoryDate": "2029-09-01"
41
43
  }
42
44
  },
@@ -51,6 +53,7 @@
51
53
  "regulation": {
52
54
  "name": "Construction Products Regulation",
53
55
  "number": "(EU) 2024/3110",
56
+ "effectiveDate": "2029-01-01",
54
57
  "mandatoryDate": "2029-01-01"
55
58
  }
56
59
  },
@@ -65,6 +68,7 @@
65
68
  "regulation": {
66
69
  "name": "EU ESPR - Electronics",
67
70
  "number": "(EU) 2024/1781",
71
+ "effectiveDate": "2028-01-01",
68
72
  "mandatoryDate": "2029-01-01"
69
73
  }
70
74
  },
@@ -79,6 +83,7 @@
79
83
  "regulation": {
80
84
  "name": "EU ESPR - FMCG",
81
85
  "number": "(EU) 2024/1781",
86
+ "effectiveDate": "2028-01-01",
82
87
  "mandatoryDate": "2030-01-01"
83
88
  }
84
89
  },
@@ -93,6 +98,7 @@
93
98
  "regulation": {
94
99
  "name": "EU ESPR - Furniture",
95
100
  "number": "(EU) 2024/1781",
101
+ "effectiveDate": "2029-01-01",
96
102
  "mandatoryDate": "2030-01-01"
97
103
  }
98
104
  },
@@ -107,6 +113,7 @@
107
113
  "regulation": {
108
114
  "name": "EU ESPR - Jewelry",
109
115
  "number": "(EU) 2024/1781",
116
+ "effectiveDate": "2030-01-01",
110
117
  "mandatoryDate": "2030-01-01"
111
118
  }
112
119
  },
@@ -121,6 +128,7 @@
121
128
  "regulation": {
122
129
  "name": "Packaging and Packaging Waste Regulation",
123
130
  "number": "(EU) 2025/40",
131
+ "effectiveDate": "2027-01-01",
124
132
  "mandatoryDate": "2030-01-01"
125
133
  }
126
134
  },
@@ -135,6 +143,7 @@
135
143
  "regulation": {
136
144
  "name": "EU ESPR - Iron, Steel & Aluminium",
137
145
  "number": "(EU) 2024/1781",
146
+ "effectiveDate": "2027-01-01",
138
147
  "mandatoryDate": "2028-01-01"
139
148
  }
140
149
  },
@@ -149,6 +158,7 @@
149
158
  "regulation": {
150
159
  "name": "EU ESPR - Textiles",
151
160
  "number": "(EU) 2024/1781",
161
+ "effectiveDate": "2028-01-01",
152
162
  "mandatoryDate": "2029-01-01"
153
163
  }
154
164
  },
@@ -163,6 +173,7 @@
163
173
  "regulation": {
164
174
  "name": "EU ESPR - Toys",
165
175
  "number": "(EU) 2024/1781",
176
+ "effectiveDate": "2030-01-01",
166
177
  "mandatoryDate": "2030-01-01"
167
178
  }
168
179
  },
@@ -177,6 +188,7 @@
177
188
  "regulation": {
178
189
  "name": "EU ESPR - Tyres",
179
190
  "number": "(EU) 2024/1781",
191
+ "effectiveDate": "2028-01-01",
180
192
  "mandatoryDate": "2029-01-01"
181
193
  }
182
194
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tracepass/dpp-schemas",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Machine-readable field specifications for EU Digital Product Passports (ESPR) — 12 product categories, 913 fields, each traced to the article of EU law that mandates it. Pure JSON, no dependencies.",
5
5
  "keywords": [
6
6
  "digital-product-passport",
@@ -38,9 +38,13 @@
38
38
  ],
39
39
  "sideEffects": false,
40
40
  "publishConfig": {
41
- "access": "public"
41
+ "access": "public",
42
+ "provenance": true
42
43
  },
43
44
  "scripts": {
44
- "validate": "python3 -c \"import json,glob;from jsonschema import Draft202012Validator as V;v=V(json.load(open('schema.json')));[print(('ok ' if not list(v.iter_errors(json.load(open(p)))) else 'FAIL'),p) for p in sorted(glob.glob('templates/*.json'))]\""
45
+ "validate": "python3 -c \"import json,glob,sys;from jsonschema import Draft202012Validator as V;v=V(json.load(open('schema.json')));bad=0\nfor p in sorted(glob.glob('templates/*.json')):\n e=list(v.iter_errors(json.load(open(p))));bad+=bool(e);print(('FAIL' if e else 'ok '),p)\n [print(' ',str(x.absolute_path),x.message[:120]) for x in e[:3]]\nsys.exit(1 if bad else 0)\"",
46
+ "build:index": "node scripts/build-index.mjs",
47
+ "check:index": "node scripts/build-index.mjs --check",
48
+ "check": "npm run validate && npm run check:index"
45
49
  }
46
50
  }
package/schema.json CHANGED
@@ -395,6 +395,19 @@
395
395
  "anticipatedNote": {
396
396
  "type": "string",
397
397
  "description": "Why it is expected — e.g. \"ESPR Annex I(p), pending a delegated act under Art. 4\"."
398
+ },
399
+ "requiredBy": {
400
+ "type": "object",
401
+ "description": "Per-sub-category applicability, where one obligation does not apply uniformly across a category. Present only on fields whose governing instrument distinguishes sub-categories; absent means `required`/`anticipated` applies to the whole category. Battery uses the Regulation (EU) 2023/1542 split: EV batteries, light means of transport (LMT), and industrial batteries over 2 kWh.",
402
+ "additionalProperties": {
403
+ "type": "string",
404
+ "enum": [
405
+ "required",
406
+ "conditional",
407
+ "notApplicable"
408
+ ],
409
+ "description": "`required` — the instrument compels it for this sub-category. `conditional` — compelled only when a stated gate is met (e.g. the battery has a BMS, is rechargeable, or contains Annex X materials). `notApplicable` — the provision does not reach this sub-category."
410
+ }
398
411
  }
399
412
  }
400
413
  },