velocious 1.0.656 → 1.0.658

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
@@ -1063,6 +1063,8 @@ Task.validates("name", {presence: true, uniqueness: true})
1063
1063
  export default Task
1064
1064
  ```
1065
1065
 
1066
+ `presence: true` rejects only `null`, `undefined`, and trimmed-empty strings; non-string values are present as-is, so a `Date`, a number (including `0`), or a boolean (including `false`) never fails presence validation. See [docs/validations.md](docs/validations.md) for the full validator contract.
1067
+
1066
1068
  Generated belongs-to setters synchronize the loaded relationship and foreign key before save, so `task.setProject(project)` updates `task.projectId()`, `task.changes()`, callbacks, and scoped features such as `actsAsList`. Custom relationship primary keys are also used after autosaving an assigned new or dirty related record. Generated backend write attributes accept belongs-to relationship names for `create` and `update` payloads. See [docs/relationships.md](docs/relationships.md#assigning-belongs-to-relationships).
1067
1069
 
1068
1070
  Translated models also get a `currentTranslation` `hasOne` relationship scoped to the first available row in the current locale fallback order. See [docs/translations.md](docs/translations.md) for preloading and frontend-model sorting behavior.
@@ -11,10 +11,12 @@ export default class VelociousDatabaseRecordValidatorsPresence extends Base {
11
11
  * @param {string} args.attributeName - Attribute name.
12
12
  */
13
13
  async validate({model, attributeName}) {
14
- const rawValue = /** @type {string | undefined} */ (model.readAttribute(attributeName))
15
- const attributeValue = rawValue?.trim()
14
+ const rawValue = /** @type {unknown} */ (model.readAttribute(attributeName))
15
+ const attributeValue = typeof rawValue === "string" ? rawValue.trim() : rawValue
16
16
 
17
- if (!attributeValue) {
17
+ // Only nullish values and blank (trimmed-empty) strings count as absent;
18
+ // falsy non-string values like 0 or false are legitimately present.
19
+ if (attributeValue === null || attributeValue === undefined || attributeValue === "") {
18
20
  if (!(attributeName in model._validationErrors)) model._validationErrors[attributeName] = []
19
21
 
20
22
  const translator = model.getModelClass()._getConfiguration().getTranslator()
@@ -1 +1 @@
1
- {"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../../../../../src/database/record/validators/presence.js"],"names":[],"mappings":"AAEA,OAAO,IAAI,MAAM,WAAW,CAAA;AAG5B,MAAM,CAAC,OAAO,OAAO,yCAA0C,SAAQ,IAAI;IACzE;;;;;OAKG;IACG,QAAQ,CAAC,EAAC,KAAK,EAAE,aAAa,EAAC,EAHlC;QAA4C,KAAK,EAAzC,OAAO,aAAa,EAAE,OAAO,CACrC;QAAqB,aAAa,EAA1B,MAAM,CAChB;KACoC,iBAWpC;CACF"}
1
+ {"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../../../../../src/database/record/validators/presence.js"],"names":[],"mappings":"AAEA,OAAO,IAAI,MAAM,WAAW,CAAA;AAG5B,MAAM,CAAC,OAAO,OAAO,yCAA0C,SAAQ,IAAI;IACzE;;;;;OAKG;IACG,QAAQ,CAAC,EAAC,KAAK,EAAE,aAAa,EAAC,EAHlC;QAA4C,KAAK,EAAzC,OAAO,aAAa,EAAE,OAAO,CACrC;QAAqB,aAAa,EAA1B,MAAM,CAChB;KACoC,iBAapC;CACF"}
@@ -9,9 +9,11 @@ export default class VelociousDatabaseRecordValidatorsPresence extends Base {
9
9
  * @param {string} args.attributeName - Attribute name.
10
10
  */
11
11
  async validate({ model, attributeName }) {
12
- const rawValue = /** @type {string | undefined} */ (model.readAttribute(attributeName));
13
- const attributeValue = rawValue?.trim();
14
- if (!attributeValue) {
12
+ const rawValue = /** @type {unknown} */ (model.readAttribute(attributeName));
13
+ const attributeValue = typeof rawValue === "string" ? rawValue.trim() : rawValue;
14
+ // Only nullish values and blank (trimmed-empty) strings count as absent;
15
+ // falsy non-string values like 0 or false are legitimately present.
16
+ if (attributeValue === null || attributeValue === undefined || attributeValue === "") {
15
17
  if (!(attributeName in model._validationErrors))
16
18
  model._validationErrors[attributeName] = [];
17
19
  const translator = model.getModelClass()._getConfiguration().getTranslator();
@@ -19,4 +21,4 @@ export default class VelociousDatabaseRecordValidatorsPresence extends Base {
19
21
  }
20
22
  }
21
23
  }
22
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJlc2VuY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvZGF0YWJhc2UvcmVjb3JkL3ZhbGlkYXRvcnMvcHJlc2VuY2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQTtBQUM1QixPQUFPLGlCQUFpQixNQUFNLDJCQUEyQixDQUFBO0FBRXpELE1BQU0sQ0FBQyxPQUFPLE9BQU8seUNBQTBDLFNBQVEsSUFBSTtJQUN6RTs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBQyxLQUFLLEVBQUUsYUFBYSxFQUFDO1FBQ25DLE1BQU0sUUFBUSxHQUFHLGlDQUFpQyxDQUFDLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFBO1FBQ3ZGLE1BQU0sY0FBYyxHQUFHLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQTtRQUV2QyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDcEIsSUFBSSxDQUFDLENBQUMsYUFBYSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQztnQkFBRSxLQUFLLENBQUMsaUJBQWlCLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxDQUFBO1lBRTVGLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFBO1lBRTVFLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsQ0FBQyxFQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUE7UUFDMUgsQ0FBQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgQmFzZSBmcm9tIFwiLi9iYXNlLmpzXCJcbmltcG9ydCB2YWxpZGF0aW9uTWVzc2FnZSBmcm9tIFwiLi4vdmFsaWRhdGlvbi1tZXNzYWdlcy5qc1wiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZlbG9jaW91c0RhdGFiYXNlUmVjb3JkVmFsaWRhdG9yc1ByZXNlbmNlIGV4dGVuZHMgQmFzZSB7XG4gIC8qKlxuICAgKiBSdW5zIHZhbGlkYXRlLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2luZGV4LmpzXCIpLmRlZmF1bHR9IGFyZ3MubW9kZWwgLSBNb2RlbCBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuYXR0cmlidXRlTmFtZSAtIEF0dHJpYnV0ZSBuYW1lLlxuICAgKi9cbiAgYXN5bmMgdmFsaWRhdGUoe21vZGVsLCBhdHRyaWJ1dGVOYW1lfSkge1xuICAgIGNvbnN0IHJhd1ZhbHVlID0gLyoqIEB0eXBlIHtzdHJpbmcgfCB1bmRlZmluZWR9ICovIChtb2RlbC5yZWFkQXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUpKVxuICAgIGNvbnN0IGF0dHJpYnV0ZVZhbHVlID0gcmF3VmFsdWU/LnRyaW0oKVxuXG4gICAgaWYgKCFhdHRyaWJ1dGVWYWx1ZSkge1xuICAgICAgaWYgKCEoYXR0cmlidXRlTmFtZSBpbiBtb2RlbC5fdmFsaWRhdGlvbkVycm9ycykpIG1vZGVsLl92YWxpZGF0aW9uRXJyb3JzW2F0dHJpYnV0ZU5hbWVdID0gW11cblxuICAgICAgY29uc3QgdHJhbnNsYXRvciA9IG1vZGVsLmdldE1vZGVsQ2xhc3MoKS5fZ2V0Q29uZmlndXJhdGlvbigpLmdldFRyYW5zbGF0b3IoKVxuXG4gICAgICBtb2RlbC5fdmFsaWRhdGlvbkVycm9yc1thdHRyaWJ1dGVOYW1lXS5wdXNoKHt0eXBlOiBcInByZXNlbmNlXCIsIG1lc3NhZ2U6IHZhbGlkYXRpb25NZXNzYWdlKHt0cmFuc2xhdG9yLCB0eXBlOiBcImJsYW5rXCJ9KX0pXG4gICAgfVxuICB9XG59XG4iXX0=
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJlc2VuY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvZGF0YWJhc2UvcmVjb3JkL3ZhbGlkYXRvcnMvcHJlc2VuY2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQTtBQUM1QixPQUFPLGlCQUFpQixNQUFNLDJCQUEyQixDQUFBO0FBRXpELE1BQU0sQ0FBQyxPQUFPLE9BQU8seUNBQTBDLFNBQVEsSUFBSTtJQUN6RTs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBQyxLQUFLLEVBQUUsYUFBYSxFQUFDO1FBQ25DLE1BQU0sUUFBUSxHQUFHLHNCQUFzQixDQUFDLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFBO1FBQzVFLE1BQU0sY0FBYyxHQUFHLE9BQU8sUUFBUSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUE7UUFFaEYseUVBQXlFO1FBQ3pFLG9FQUFvRTtRQUNwRSxJQUFJLGNBQWMsS0FBSyxJQUFJLElBQUksY0FBYyxLQUFLLFNBQVMsSUFBSSxjQUFjLEtBQUssRUFBRSxFQUFFLENBQUM7WUFDckYsSUFBSSxDQUFDLENBQUMsYUFBYSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQztnQkFBRSxLQUFLLENBQUMsaUJBQWlCLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxDQUFBO1lBRTVGLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFBO1lBRTVFLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsQ0FBQyxFQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUE7UUFDMUgsQ0FBQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgQmFzZSBmcm9tIFwiLi9iYXNlLmpzXCJcbmltcG9ydCB2YWxpZGF0aW9uTWVzc2FnZSBmcm9tIFwiLi4vdmFsaWRhdGlvbi1tZXNzYWdlcy5qc1wiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZlbG9jaW91c0RhdGFiYXNlUmVjb3JkVmFsaWRhdG9yc1ByZXNlbmNlIGV4dGVuZHMgQmFzZSB7XG4gIC8qKlxuICAgKiBSdW5zIHZhbGlkYXRlLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2luZGV4LmpzXCIpLmRlZmF1bHR9IGFyZ3MubW9kZWwgLSBNb2RlbCBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuYXR0cmlidXRlTmFtZSAtIEF0dHJpYnV0ZSBuYW1lLlxuICAgKi9cbiAgYXN5bmMgdmFsaWRhdGUoe21vZGVsLCBhdHRyaWJ1dGVOYW1lfSkge1xuICAgIGNvbnN0IHJhd1ZhbHVlID0gLyoqIEB0eXBlIHt1bmtub3dufSAqLyAobW9kZWwucmVhZEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKSlcbiAgICBjb25zdCBhdHRyaWJ1dGVWYWx1ZSA9IHR5cGVvZiByYXdWYWx1ZSA9PT0gXCJzdHJpbmdcIiA/IHJhd1ZhbHVlLnRyaW0oKSA6IHJhd1ZhbHVlXG5cbiAgICAvLyBPbmx5IG51bGxpc2ggdmFsdWVzIGFuZCBibGFuayAodHJpbW1lZC1lbXB0eSkgc3RyaW5ncyBjb3VudCBhcyBhYnNlbnQ7XG4gICAgLy8gZmFsc3kgbm9uLXN0cmluZyB2YWx1ZXMgbGlrZSAwIG9yIGZhbHNlIGFyZSBsZWdpdGltYXRlbHkgcHJlc2VudC5cbiAgICBpZiAoYXR0cmlidXRlVmFsdWUgPT09IG51bGwgfHwgYXR0cmlidXRlVmFsdWUgPT09IHVuZGVmaW5lZCB8fCBhdHRyaWJ1dGVWYWx1ZSA9PT0gXCJcIikge1xuICAgICAgaWYgKCEoYXR0cmlidXRlTmFtZSBpbiBtb2RlbC5fdmFsaWRhdGlvbkVycm9ycykpIG1vZGVsLl92YWxpZGF0aW9uRXJyb3JzW2F0dHJpYnV0ZU5hbWVdID0gW11cblxuICAgICAgY29uc3QgdHJhbnNsYXRvciA9IG1vZGVsLmdldE1vZGVsQ2xhc3MoKS5fZ2V0Q29uZmlndXJhdGlvbigpLmdldFRyYW5zbGF0b3IoKVxuXG4gICAgICBtb2RlbC5fdmFsaWRhdGlvbkVycm9yc1thdHRyaWJ1dGVOYW1lXS5wdXNoKHt0eXBlOiBcInByZXNlbmNlXCIsIG1lc3NhZ2U6IHZhbGlkYXRpb25NZXNzYWdlKHt0cmFuc2xhdG9yLCB0eXBlOiBcImJsYW5rXCJ9KX0pXG4gICAgfVxuICB9XG59XG4iXX0=
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "velocious": "build/bin/velocious.js"
4
4
  },
5
5
  "name": "velocious",
6
- "version": "1.0.656",
6
+ "version": "1.0.658",
7
7
  "main": "build/index.js",
8
8
  "types": "build/index.d.ts",
9
9
  "files": [
@@ -11,10 +11,12 @@ export default class VelociousDatabaseRecordValidatorsPresence extends Base {
11
11
  * @param {string} args.attributeName - Attribute name.
12
12
  */
13
13
  async validate({model, attributeName}) {
14
- const rawValue = /** @type {string | undefined} */ (model.readAttribute(attributeName))
15
- const attributeValue = rawValue?.trim()
14
+ const rawValue = /** @type {unknown} */ (model.readAttribute(attributeName))
15
+ const attributeValue = typeof rawValue === "string" ? rawValue.trim() : rawValue
16
16
 
17
- if (!attributeValue) {
17
+ // Only nullish values and blank (trimmed-empty) strings count as absent;
18
+ // falsy non-string values like 0 or false are legitimately present.
19
+ if (attributeValue === null || attributeValue === undefined || attributeValue === "") {
18
20
  if (!(attributeName in model._validationErrors)) model._validationErrors[attributeName] = []
19
21
 
20
22
  const translator = model.getModelClass()._getConfiguration().getTranslator()