@carrot-foundation/schemas 0.1.21 → 0.1.23

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/dist/index.js CHANGED
@@ -33,6 +33,11 @@ var IsoDateSchema = z.iso.date("Must be a valid ISO 8601 date (YYYY-MM-DD)").met
33
33
  description: "ISO 8601 formatted date in YYYY-MM-DD format",
34
34
  examples: ["2024-12-05", "2025-02-22", "2024-02-10"]
35
35
  });
36
+ var UnixTimestampSchema = z.number().int().positive().meta({
37
+ title: "Unix Timestamp",
38
+ description: "Unix timestamp in milliseconds since epoch (January 1, 1970 00:00:00 UTC)",
39
+ examples: [17040672e5, 17356896e5, 1762371245149]
40
+ });
36
41
  var IsoCountryCodeSchema = z.string().regex(/^[A-Z]{2}$/, "Must be a valid ISO 3166-1 alpha-2 country code").meta({
37
42
  title: "ISO Country Code",
38
43
  description: "Two-letter country code following ISO 3166-1 alpha-2 standard",
@@ -46,14 +51,14 @@ var IsoAdministrativeDivisionCodeSchema = z.string().regex(
46
51
  description: "Administrative division code following ISO 3166-2 standard",
47
52
  examples: ["BR-AP", "BR-ES", "US-CA"]
48
53
  });
49
- var LatitudeSchema = z.number().min(-90).max(90).meta({
54
+ var LatitudeSchema = z.number().min(-90).max(90).multipleOf(1e-3).meta({
50
55
  title: "Latitude",
51
- description: "Geographic latitude coordinate in decimal degrees",
52
- examples: [-0.02, -20.38, 40.7128]
56
+ description: "Geographic latitude coordinate in decimal degrees with maximum 3 decimal places precision (~100m-1km accuracy for city-level, non-PII compliance)",
57
+ examples: [-0.02, -20.38, 40.713]
53
58
  });
54
- var LongitudeSchema = z.number().min(-180).max(180).meta({
59
+ var LongitudeSchema = z.number().min(-180).max(180).multipleOf(1e-3).meta({
55
60
  title: "Longitude",
56
- description: "Geographic longitude coordinate in decimal degrees",
61
+ description: "Geographic longitude coordinate in decimal degrees with maximum 3 decimal places precision (~100m-1km accuracy for city-level, non-PII compliance)",
57
62
  examples: [-51.06, -40.34, -74.006]
58
63
  });
59
64
  var WeightKgSchema = z.number().min(0).meta({
@@ -95,19 +100,18 @@ var ParticipantNameSchema = NonEmptyStringSchema.max(100).meta({
95
100
  examples: ["Enlatados Produ\xE7\xE3o", "Eco Reciclagem", "Green Tech Corp"]
96
101
  });
97
102
  var FacilityTypeSchema = z.enum([
98
- "Waste Generation",
99
103
  "Collection Point",
100
- "Transfer Station",
101
- "Sorting Facility",
102
- "Composting Facility",
103
104
  "Recycling Facility",
104
- "Processing Facility",
105
- "Disposal Facility",
106
- "Administrative Office"
105
+ "Administrative Office",
106
+ "Other"
107
107
  ]).meta({
108
108
  title: "Facility Type",
109
- description: "Type of facility in the waste management infrastructure",
110
- examples: ["Waste Generation", "Recycling Facility", "Collection Point"]
109
+ description: "Type of facility in the waste management chain",
110
+ examples: [
111
+ "Collection Point",
112
+ "Recycling Facility",
113
+ "Administrative Office"
114
+ ]
111
115
  });
112
116
  var BlockchainChainIdSchema = z.number().int().min(1).meta({
113
117
  title: "Chain ID",
@@ -265,9 +269,9 @@ var CoordinatesSchema = z.strictObject({
265
269
  description: "GPS coordinates of the location"
266
270
  });
267
271
  var LocationSchema = z.strictObject({
268
- id: UuidSchema.meta({
269
- title: "Location ID",
270
- description: "Unique identifier for the location"
272
+ id_hash: Sha256HashSchema.meta({
273
+ title: "Location ID Hash",
274
+ description: "Anonymized identifier for the location"
271
275
  }),
272
276
  municipality: NonEmptyStringSchema.max(50).meta({
273
277
  title: "Municipality",
@@ -292,9 +296,9 @@ var LocationSchema = z.strictObject({
292
296
  title: "Country Code",
293
297
  description: "ISO 3166-1 alpha-2 country code"
294
298
  }),
295
- responsible_participant_id: UuidSchema.meta({
296
- title: "Responsible Participant ID",
297
- description: "ID of the participant responsible for this location"
299
+ responsible_participant_id_hash: Sha256HashSchema.meta({
300
+ title: "Responsible Participant ID Hash",
301
+ description: "Anonymized ID of the participant responsible for this location"
298
302
  }),
299
303
  coordinates: CoordinatesSchema,
300
304
  facility_type: FacilityTypeSchema.optional().meta({
@@ -324,9 +328,9 @@ function uniqueBy(schema, selector, errorMessage = "Items must be unique") {
324
328
 
325
329
  // src/shared/entities/participant.schema.ts
326
330
  var ParticipantSchema = z.strictObject({
327
- id: UuidSchema.meta({
328
- title: "Participant ID",
329
- description: "Unique identifier for the participant"
331
+ id_hash: Sha256HashSchema.meta({
332
+ title: "Participant ID Hash",
333
+ description: "Anonymized identifier for the participant"
330
334
  }),
331
335
  name: ParticipantNameSchema.meta({
332
336
  title: "Participant Name",
@@ -361,15 +365,10 @@ var MassIDLocalClassificationSchema = z.strictObject({
361
365
  "Municipal solid waste - organic fraction"
362
366
  ]
363
367
  }),
364
- system: NonEmptyStringSchema.max(50).meta({
368
+ system: z.enum(["IBAMA"]).meta({
365
369
  title: "Classification System",
366
- description: 'Classification system name (e.g., "Ibama Waste Code", "European Waste Catalogue", "US EPA Codes")',
367
- examples: [
368
- "European Waste Catalogue",
369
- "US EPA Codes",
370
- "Ibama Waste Code",
371
- "Brazilian ABNT Classification"
372
- ]
370
+ description: "Classification system name - currently supports IBAMA (Instituto Brasileiro do Meio Ambiente e dos Recursos Naturais Renov\xE1veis)",
371
+ examples: ["IBAMA"]
373
372
  })
374
373
  }).meta({
375
374
  title: "Local Classification",
@@ -385,10 +384,10 @@ var ContaminationLevelSchema = z.enum(["None", "Low", "Medium", "High"]).meta({
385
384
  description: "Level of contamination in the waste batch",
386
385
  examples: ["Low", "Medium", "None"]
387
386
  });
388
- var MassIDWasteClassificationSchema = z.strictObject({
389
- primary_type: WasteTypeSchema.meta({
390
- title: "Primary Waste Type",
391
- description: "Primary waste material category"
387
+ var MassIDWastePropertiesSchema = z.strictObject({
388
+ type: WasteTypeSchema.meta({
389
+ title: "Waste Type",
390
+ description: "Waste material category"
392
391
  }),
393
392
  subtype: WasteSubtypeSchema.meta({
394
393
  title: "Waste Subtype",
@@ -402,8 +401,8 @@ var MassIDWasteClassificationSchema = z.strictObject({
402
401
  }),
403
402
  contamination_level: ContaminationLevelSchema.optional()
404
403
  }).meta({
405
- title: "Waste Classification",
406
- description: "Standardized waste material classification and regulatory information"
404
+ title: "Waste Properties",
405
+ description: "Standardized waste material properties and regulatory information"
407
406
  });
408
407
  var EventAttributeFormatSchema = z.enum(["KILOGRAM", "DATE", "CURRENCY", "PERCENTAGE", "COORDINATE"]).meta({
409
408
  title: "Event Attribute Format",
@@ -425,7 +424,7 @@ var EventAttributeSchema = z.strictObject({
425
424
  "processing_cost"
426
425
  ]
427
426
  }),
428
- value: z.union([z.string(), z.number(), z.boolean()]).meta({
427
+ value: z.union([z.string(), z.number(), z.boolean()]).optional().meta({
429
428
  title: "Attribute Value",
430
429
  description: "Event attribute value",
431
430
  examples: [
@@ -439,6 +438,10 @@ var EventAttributeSchema = z.strictObject({
439
438
  "OP-456"
440
439
  ]
441
440
  }),
441
+ preserved_sensitivity: z.boolean().optional().meta({
442
+ title: "Preserved Sensitivity",
443
+ description: "Indicates if the attribute contains sensitive information that was preserved"
444
+ }),
442
445
  format: EventAttributeFormatSchema.optional()
443
446
  }).meta({
444
447
  title: "Event Attribute",
@@ -527,12 +530,12 @@ var MassIDChainOfCustodyEventSchema = z.strictObject({
527
530
  title: "Event Timestamp",
528
531
  description: "ISO 8601 timestamp when the event occurred"
529
532
  }),
530
- participant_id: UuidSchema.meta({
531
- title: "Participant ID",
533
+ participant_id_hash: Sha256HashSchema.meta({
534
+ title: "Participant ID Hash",
532
535
  description: "Reference to participant in the participants array"
533
536
  }),
534
- location_id: UuidSchema.meta({
535
- title: "Location ID",
537
+ location_id_hash: Sha256HashSchema.meta({
538
+ title: "Location ID Hash",
536
539
  description: "Reference to location in the locations array"
537
540
  }),
538
541
  weight: NonNegativeFloatSchema.optional().meta({
@@ -573,12 +576,12 @@ var MassIDChainOfCustodySchema = z.strictObject({
573
576
  description: "Complete chain of custody tracking from waste generation to final processing"
574
577
  });
575
578
  var MassIDTransportRouteSchema = z.strictObject({
576
- from_location_id: UuidSchema.meta({
577
- title: "From Location ID",
579
+ from_location_id_hash: Sha256HashSchema.meta({
580
+ title: "From Location ID Hash",
578
581
  description: "Reference to the origin location in the locations array"
579
582
  }),
580
- to_location_id: UuidSchema.meta({
581
- title: "To Location ID",
583
+ to_location_id_hash: Sha256HashSchema.meta({
584
+ title: "To Location ID Hash",
582
585
  description: "Reference to the destination location in the locations array"
583
586
  }),
584
587
  distance_km: NonNegativeFloatSchema.meta({
@@ -608,16 +611,16 @@ var MassIDTransportRouteSchema = z.strictObject({
608
611
  description: "Transport route segment information"
609
612
  });
610
613
  var MassIDGeographicDataSchema = z.strictObject({
611
- origin_location_id: UuidSchema.meta({
612
- title: "Origin Location ID",
614
+ origin_location_id_hash: Sha256HashSchema.meta({
615
+ title: "Origin Location ID Hash",
613
616
  description: "Reference to origin location in the locations array"
614
617
  }),
615
- processing_location_ids: z.array(UuidSchema).optional().meta({
616
- title: "Processing Location IDs",
618
+ processing_location_id_hashes: z.array(Sha256HashSchema).optional().meta({
619
+ title: "Processing Location ID Hashes",
617
620
  description: "Locations where the waste was processed or handled"
618
621
  }),
619
- final_destination_id: UuidSchema.meta({
620
- title: "Final Destination ID",
622
+ final_destination_id_hash: Sha256HashSchema.meta({
623
+ title: "Final Destination ID Hash",
621
624
  description: "Reference to final destination in the locations array"
622
625
  }),
623
626
  transport_routes: z.array(MassIDTransportRouteSchema).meta({
@@ -629,19 +632,19 @@ var MassIDGeographicDataSchema = z.strictObject({
629
632
  description: "Geographic information about waste origin and processing locations"
630
633
  });
631
634
  var MassIDDataSchema = z.strictObject({
632
- waste_classification: MassIDWasteClassificationSchema,
635
+ waste_properties: MassIDWastePropertiesSchema,
633
636
  locations: uniqueBy(
634
637
  LocationSchema,
635
- (loc) => loc.id,
636
- "Location IDs must be unique"
638
+ (loc) => loc.id_hash,
639
+ "Location ID hashes must be unique"
637
640
  ).min(1).meta({
638
641
  title: "Locations",
639
642
  description: "All locations referenced in this MassID, indexed by ID"
640
643
  }),
641
644
  participants: uniqueBy(
642
645
  ParticipantSchema,
643
- (p) => p.id,
644
- "Participant IDs must be unique"
646
+ (p) => p.id_hash,
647
+ "Participant ID hashes must be unique"
645
648
  ).min(1).meta({
646
649
  title: "Participants",
647
650
  description: "All participants referenced in this MassID, indexed by ID"
@@ -650,27 +653,27 @@ var MassIDDataSchema = z.strictObject({
650
653
  geographic_data: MassIDGeographicDataSchema
651
654
  }).refine((data) => {
652
655
  const participantIdSet = new Set(
653
- data.participants.map((participant) => participant.id)
656
+ data.participants.map((participant) => participant.id_hash)
654
657
  );
655
658
  const eventParticipantIds = data.chain_of_custody.events.map(
656
- (event) => event.participant_id
659
+ (event) => event.participant_id_hash
657
660
  );
658
661
  const allEventParticipantsExist = eventParticipantIds.every(
659
662
  (participantId) => participantIdSet.has(participantId)
660
663
  );
661
664
  return allEventParticipantsExist;
662
- }, "All participant IDs in chain of custody events must exist in participants array").refine((data) => {
665
+ }, "All participant ID hashes in chain of custody events must exist in participants array").refine((data) => {
663
666
  const locationIdSet = new Set(
664
- data.locations.map((location) => location.id)
667
+ data.locations.map((location) => location.id_hash)
665
668
  );
666
669
  const eventLocationIds = data.chain_of_custody.events.map(
667
- (event) => event.location_id
670
+ (event) => event.location_id_hash
668
671
  );
669
672
  const allEventLocationsExist = eventLocationIds.every(
670
673
  (locationId) => locationIdSet.has(locationId)
671
674
  );
672
675
  return allEventLocationsExist;
673
- }, "All location IDs in chain of custody events must exist in locations array").meta({
676
+ }, "All location ID hashes in chain of custody events must exist in locations array").meta({
674
677
  title: "MassID Data",
675
678
  description: "MassID data containing waste tracking and chain of custody information"
676
679
  });
@@ -694,7 +697,7 @@ var RecordCreatorSchema = z.strictObject({
694
697
  name: z.string().meta({
695
698
  title: "Creator Name",
696
699
  description: "Company or individual name that created this record",
697
- examples: ["Carrot Foundation", "Alice", "Bob"]
700
+ examples: ["Carrot Foundation"]
698
701
  }),
699
702
  id: UuidSchema.meta({
700
703
  title: "Creator ID",
@@ -962,6 +965,18 @@ var NftIpfsSchema = BaseIpfsSchema.safeExtend({
962
965
  description: "NFT-specific fields for Carrot IPFS records"
963
966
  });
964
967
 
968
+ // src/shared/schema-version.ts
969
+ function getSchemaBaseUrl() {
970
+ return `https://raw.githubusercontent.com/carrot-foundation/schemas/refs/tags/${getSchemaVersionOrDefault()}/schemas/ipfs`;
971
+ }
972
+ function buildSchemaUrl(schemaPath) {
973
+ const cleanPath = schemaPath.startsWith("/") ? schemaPath.slice(1) : schemaPath;
974
+ return `${getSchemaBaseUrl()}/${cleanPath}`;
975
+ }
976
+ function getSchemaVersionOrDefault() {
977
+ return "0.0.0-dev";
978
+ }
979
+
965
980
  // src/mass-id/mass-id.schema.ts
966
981
  var AttributeWasteTypeSchema = z.strictObject({
967
982
  trait_type: z.literal("Waste Type"),
@@ -1037,14 +1052,14 @@ var AttributeIntegratorSchema = z.strictObject({
1037
1052
  });
1038
1053
  var AttributePickUpDateSchema = z.strictObject({
1039
1054
  trait_type: z.literal("Pick-up Date"),
1040
- value: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Must be a valid date in YYYY-MM-DD format").meta({
1055
+ value: UnixTimestampSchema.meta({
1041
1056
  title: "Pick-up Date Value",
1042
- description: "Date when the waste was picked up from the source"
1057
+ description: "Unix timestamp in milliseconds when the waste was picked up from the source"
1043
1058
  }),
1044
1059
  display_type: z.literal("date")
1045
1060
  }).meta({
1046
1061
  title: "Pick-up Date Attribute",
1047
- description: "Pick-up date attribute"
1062
+ description: "Pick-up date attribute with Unix timestamp"
1048
1063
  });
1049
1064
  var AttributeRecyclingDateSchema = z.strictObject({
1050
1065
  trait_type: z.literal("Recycling Date"),
@@ -1075,8 +1090,8 @@ var MassIDAttributesSchema = z.tuple([
1075
1090
  var MassIDIpfsSchemaMeta = {
1076
1091
  title: "MassID NFT IPFS Record",
1077
1092
  description: "Complete MassID NFT IPFS record including fixed attributes and detailed waste tracking data",
1078
- $id: "https://raw.githubusercontent.com/carrot-foundation/schemas/refs/heads/main/schemas/ipfs/mass-id/mass-id.schema.json",
1079
- version: "1.0.1"
1093
+ $id: buildSchemaUrl("mass-id/mass-id.schema.json"),
1094
+ version: getSchemaVersionOrDefault()
1080
1095
  };
1081
1096
  var MassIDIpfsSchema = NftIpfsSchema.safeExtend({
1082
1097
  schema: NftIpfsSchema.shape.schema.safeExtend({