@reventlessdev/reventless-spec 3.0.0-alpha.136 → 3.0.0-alpha.137

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/CHANGELOG.md CHANGED
@@ -3,6 +3,16 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # 3.0.0-alpha.137 (2026-09-20)
7
+
8
+ ### Bug Fixes
9
+
10
+ * **spec:** resolve the drift guard's paths from the module, not the cwd ([7f4d8de](https://github.com/ReventlessDev/reventless-core/commit/7f4d8de896f37ce4a855ecc6a980788f01d0e1c7))
11
+ ### Features
12
+
13
+ * **spec:** enumerate the transparent-string semantics, and check the list against the sources ([995c31c](https://github.com/ReventlessDev/reventless-core/commit/995c31c5eb1a9bdb2ad88d39b2b9a8a5348be0da))
14
+
15
+
6
16
  # 3.0.0-alpha.136 (2026-09-16)
7
17
 
8
18
  ### Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/reventless-spec",
3
- "version": "3.0.0-alpha.136",
3
+ "version": "3.0.0-alpha.137",
4
4
  "description": "Specifications for Reventless",
5
5
  "license": "Apache-2.0",
6
6
  "bin": {
@@ -113,6 +113,50 @@ module Id = {
113
113
  let geolocation = "geolocation"
114
114
  }
115
115
 
116
+ /** One transparent-string semantic: a `semantic/` module whose `type t` is a
117
+ bare `string`. */
118
+ type brandedString = {
119
+ moduleName: string,
120
+ /** The `Id` values of this module carry. Not derivable from the module name —
121
+ `CalendarDate` carries `date`. */
122
+ id: string,
123
+ /** Whether the module exposes the `let schema` that sury-ppx resolves `X.t`
124
+ to by convention. The `false`s build theirs from a function taking
125
+ arguments (`forStore` / `forField` / `forCollection`), so such a field
126
+ always carries an explicit `@s.matches` and there is no name a pass could
127
+ derive. Offering one as a plain type pick emits code that does not
128
+ compile. */
129
+ hasDerivableSchema: bool,
130
+ }
131
+
132
+ /** Every transparent-string semantic, so a consumer can ask what they are
133
+ instead of transcribing the set.
134
+
135
+ A check written against the literal `string` keyword sees only the brand and
136
+ refuses the field, which would make declaring a semantic cost the field
137
+ whatever that check gates — so a pass that must leave these alone needs the
138
+ set, not a guess. It cannot be guessed from the names: `Money.t` is a record,
139
+ `Duration.t` an int, `Percent.t` and `Bytes.t` floats, and all four are
140
+ deliberately absent.
141
+
142
+ Both facts here are computable from the sources, and `SemanticBrandedStringsTest`
143
+ recomputes them rather than trusting this list — so adding a module without
144
+ adding it here fails, and so does the ppx's copy drifting from either. */
145
+ let brandedStrings: array<brandedString> = [
146
+ {moduleName: "DateTime", id: Id.dateTime, hasDerivableSchema: true},
147
+ {moduleName: "CalendarDate", id: Id.date, hasDerivableSchema: true},
148
+ {moduleName: "Email", id: Id.email, hasDerivableSchema: true},
149
+ {moduleName: "Phone", id: Id.phone, hasDerivableSchema: true},
150
+ {moduleName: "Url", id: Id.url, hasDerivableSchema: true},
151
+ {moduleName: "Color", id: Id.color, hasDerivableSchema: true},
152
+ {moduleName: "FileRef", id: Id.fileRef, hasDerivableSchema: true},
153
+ {moduleName: "ImageRef", id: Id.imageRef, hasDerivableSchema: true},
154
+ {moduleName: "MemberRef", id: Id.memberRef, hasDerivableSchema: false},
155
+ {moduleName: "StorageRef", id: Id.storageRef, hasDerivableSchema: false},
156
+ {moduleName: "UploadableFile", id: Id.uploadableFile, hasDerivableSchema: false},
157
+ {moduleName: "UploadableImage", id: Id.uploadableImage, hasDerivableSchema: false},
158
+ ]
159
+
116
160
  let semanticId: S.Metadata.Id.t<t> = S.Metadata.Id.make(~namespace="reventless", ~name="semantic")
117
161
 
118
162
  /** Mark a schema as carrying a semantic. */
@@ -4,25 +4,49 @@ import * as S from "sury/src/S.res.mjs";
4
4
  import * as Sury from "sury";
5
5
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
6
6
 
7
+ let dateTime = "dateTime";
8
+
9
+ let date = "date";
10
+
11
+ let storageRef = "storageRef";
12
+
13
+ let uploadableImage = "uploadableImage";
14
+
15
+ let uploadableFile = "uploadableFile";
16
+
17
+ let imageRef = "imageRef";
18
+
19
+ let fileRef = "fileRef";
20
+
21
+ let memberRef = "memberRef";
22
+
23
+ let email = "email";
24
+
25
+ let phone = "phone";
26
+
27
+ let url = "url";
28
+
29
+ let color = "color";
30
+
7
31
  let Id = {
8
- dateTime: "dateTime",
9
- date: "date",
32
+ dateTime: dateTime,
33
+ date: date,
10
34
  reference: "reference",
11
- storageRef: "storageRef",
35
+ storageRef: storageRef,
12
36
  offload: "offload",
13
- uploadableImage: "uploadableImage",
14
- uploadableFile: "uploadableFile",
15
- imageRef: "imageRef",
16
- fileRef: "fileRef",
37
+ uploadableImage: uploadableImage,
38
+ uploadableFile: uploadableFile,
39
+ imageRef: imageRef,
40
+ fileRef: fileRef,
17
41
  captionedImage: "captionedImage",
18
- memberRef: "memberRef",
19
- email: "email",
20
- phone: "phone",
21
- url: "url",
42
+ memberRef: memberRef,
43
+ email: email,
44
+ phone: phone,
45
+ url: url,
22
46
  percent: "percent",
23
47
  bytes: "bytes",
24
48
  duration: "duration",
25
- color: "color",
49
+ color: color,
26
50
  money: "money",
27
51
  dateRange: "dateRange",
28
52
  geoPoint: "geoPoint",
@@ -30,6 +54,69 @@ let Id = {
30
54
  geolocation: "geolocation"
31
55
  };
32
56
 
57
+ let brandedStrings = [
58
+ {
59
+ moduleName: "DateTime",
60
+ id: dateTime,
61
+ hasDerivableSchema: true
62
+ },
63
+ {
64
+ moduleName: "CalendarDate",
65
+ id: date,
66
+ hasDerivableSchema: true
67
+ },
68
+ {
69
+ moduleName: "Email",
70
+ id: email,
71
+ hasDerivableSchema: true
72
+ },
73
+ {
74
+ moduleName: "Phone",
75
+ id: phone,
76
+ hasDerivableSchema: true
77
+ },
78
+ {
79
+ moduleName: "Url",
80
+ id: url,
81
+ hasDerivableSchema: true
82
+ },
83
+ {
84
+ moduleName: "Color",
85
+ id: color,
86
+ hasDerivableSchema: true
87
+ },
88
+ {
89
+ moduleName: "FileRef",
90
+ id: fileRef,
91
+ hasDerivableSchema: true
92
+ },
93
+ {
94
+ moduleName: "ImageRef",
95
+ id: imageRef,
96
+ hasDerivableSchema: true
97
+ },
98
+ {
99
+ moduleName: "MemberRef",
100
+ id: memberRef,
101
+ hasDerivableSchema: false
102
+ },
103
+ {
104
+ moduleName: "StorageRef",
105
+ id: storageRef,
106
+ hasDerivableSchema: false
107
+ },
108
+ {
109
+ moduleName: "UploadableFile",
110
+ id: uploadableFile,
111
+ hasDerivableSchema: false
112
+ },
113
+ {
114
+ moduleName: "UploadableImage",
115
+ id: uploadableImage,
116
+ hasDerivableSchema: false
117
+ }
118
+ ];
119
+
33
120
  let semanticId = Sury.$Metadata_Id_make("reventless", "semantic");
34
121
 
35
122
  function mark(schema, id, payloadOpt) {
@@ -129,6 +216,7 @@ function has(fieldSchema, id) {
129
216
 
130
217
  export {
131
218
  Id,
219
+ brandedStrings,
132
220
  semanticId,
133
221
  mark,
134
222
  refined,