Are any of the clojure validation/spec libraries available for use with #squint? I saw on one thread that its possible to compile a cljs library with squint to make it consumable as a library. Has that been tried for - e.g. clojure spec // plumatic schema // malli ?
@zach.charlop.powers did you progressed on this? Just having the same requirement here, I really missing a validation input for some of my functions that I would benefit a lot from something like schema/malli
No. The data I was interested in had a JSON schema so I used that.
I did put an example of using ajv in the squint repo
I really miss the function annotation, where you can define input / output schemas and validate in tests. I'm going to check the ajv example, how is your workflow? Define the scheme and validate inside the funcion?
currently no. perhaps there is one in the JS library ecosystem?
Thank you @borkdude! Yes. In my case I am weighing the build simplicity of squint (+ js validator) vs a true clojurescipt + spec/et.al. The data domain I am working with is relatively deeply nested would benefit from the composability of e.g. spec.
don't know how well it works with nested data
I'll take a look. thank you
JSON schema may also work for you
I am wondering how hard it would be to to write a Malli->joi ....
probably hard :)
lol. true. I think the JSON schema is most practical although its a bit less clj intruitive about keys etc. But I think I will try that route. Thank you.
https://ajv.js.org/guide/getting-started.html#basic-data-validation is also good
i guess you can build stuff around it to make it nicer for clojure
I am hitting the following import issue in squint. I am aiming to us use Ajv to validate an OpenAPISpec and use that from my project. addFormats is supposedly used to extend to AJV to consume different spec dialects. Is there a way to alter/influence squint's imports?
(ns mvsj
(:require ["fs" :as fs]
["url" :refer [fileURLToPath]]
["ajv" :refer [Ajv]]
["ajv-formats" :refer [addFormats]]))
file:///Users/zcpowers/Downloads/squint-mol/mvsj.mjs:5
import { addFormats } from 'ajv-formats';
^^^^^^^^^^
SyntaxError: Named export 'addFormats' not found. The requested module 'ajv-formats' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from 'ajv-formats';
const { addFormats } = pkg;I think you probably need to do it like this:
["ajv-formats$default" :refer [addFormats]]
since it's a cjs module rather than ESM
the error message kind of hints at that
thank you.
Now I know what this means: CommonJS modules can always be imported via the default export,
yeah sorry, it might not be clear to you what $default means. it's the standard ClojureScript notation to import a default export
Probably we need to add this to the README of squint. PR welcome :)
Once I get this sorted I'll be happy to submit a PR
👍
Apologies but one more continuation related to importing.
import default$1 from 'ajv-formats';
const { addFormats } = default$1;
file:///Users/zcpowers/Downloads/squint-mol/mvsj.mjs:248
const _5 = addFormats(ajv1, ({ }));
^
TypeError: addFormats is not a functionit's best to just console.log the ajv-formats thing and inspect it so you know what exists at runtime
e.g.:
["ajv-formats" :as ajv]
(js/console.log ajv)ah.
if it prints something like Module with default, then add $default and try the same thing
and then you should see addFormats in there somewhere hopefully
oh wait you mean this?
import addFormats from "ajv-formats"this should look like this in squint:
(:require ["ajv-formats$default" :as addFormats])so you import the default and give it the name addFormats
Thank you.
The last one worked. Now onto troubleshooting the openAPI call. Will post repro example as PR once worked out. TY
Awesome thank you!
Is there a gensym alternative for #squint? Any drop in alternatives?
[squint] Running test_macro.cljs
file:///Users/zcpowers/Downloads/squint-mol/test_macro.mjs:3
const name_sym1 = gensym("name");squint doesn't have symbol, so it also doesn't have gensym
I guess you could do something like this: https://squint-cljs.github.io/squint/?src=KGRlZiBnZW4KICAobGV0IFtjb3VudGVyIChhdG9tIDApXQogICAgKGZuIFtwcmVmaXhdCiAgICAgIChzd2FwISBjb3VudGVyIGluYykKICAgICAgKHN0ciBwcmVmaXggQGNvdW50ZXIpKSkpCgpbKGdlbiAiZm9vIikgKGdlbiAiZHVkZSIpXQ%3D%3D
If you want to share code, you can hit the share button and paste the link here, even better than a screenshot :)
ah! this is what I'm working on. little macro to condense JSON creation. (def gen
(let [counter (atom 0)]
(fn [prefix]
(swap! counter inc)
(str prefix @counter))))
(defmacro nodize
"Transforms a hiccup-like vector [:name props children] into a node map."
[form]
(let [name-sym (gen "name")
props-sym (gen "props")
children-sym (gen "children")]
`(let [[name-sym props-sym children-sym] form]
(cond-> {"kind" (name ~name-sym)}
(not (empty? props-sym)) (assoc "params" props-sym)
(seq children-sym) (assoc "children" (mapv nodize children-sym))))))
(nodize
[:thing1 {:prop1 "container"} [[:thing2 {} []] [:thing3 {:prop2 "awesome"} []]]])
That's cool, but macros don't work in the playground unfortunately (yet).
Macros have to live in a separate file and have to be loaded with :require-macros
You can use gensym in macros since they are executed in SCI, not in the target runtime
(ns nextjournal.clojure-mode-tests
(:require #?@(:squint []
:cljs [[cljs.test :refer [are testing deftest is]]])
[nextjournal.clojure-mode :as cm-clojure]
[nextjournal.clojure-mode.util :as util]
[nextjournal.clojure-mode.test-utils :as test-utils]
[nextjournal.clojure-mode.extensions.close-brackets :as close-brackets]
[nextjournal.clojure-mode.commands :as commands]
[nextjournal.clojure-mode.extensions.formatting :as format]
[nextjournal.clojure-mode.extensions.eval-region :as eval-region]
[nextjournal.scratch]
#?@(:squint []
:cljs [[nextjournal.livedoc :as livedoc]])
#?(:squint ["assert" :as assert]))
#?(:squint (:require-macros [nextjournal.clojure-mode-tests.macros :refer [deftest are testing is]])))^ I was running into require-macro problems and looking up how youv'e done it elsewhere. Looks like a :squint key is required.
no that is only in .cljc files where you use a reader conditional
https://github.com/squint-cljs/squint?tab=readme-ov-file#macros
here is a test project in the squint repo: https://github.com/squint-cljs/squint/blob/44cc9ef7fca2dac90e56a1c08de0c83a94383ee8/test-project/src/main.cljs#L2
Thanks I'll work off of that I kept running into errors like this but didn't have a minimal working example to work from.
[squint] Compiling CLJS file: /Users/zcpowers/Downloads/squint-mol/src/mvsj/core.cljs
node:fs:441
path = getValidatedPath(path);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string or an instance of Buffer or URL. Received nulldo you have a squint.edn already?
the macro needs to be somewhere in a directory that is mentioned in :source-paths
yes.
{:paths ["resources", "src/mvsj"]
:output-dir "dist"}what does your require-macros look like?
tree src/
src/
└── mvsj
├── core.cljs
├── macros.cljc
└── mvsj.cljs
(ns mvsj.core
(:require
[mvsj.mvsj :as mvsj]
["fs" :as fs]
["ajv$default" :as Ajv]
["ajv-formats$default" :as addFormats])
;; (:require-macros [resources.macros :refer [nodize]])
(:require-macros [msvj.macros :refer [nodize]]))you need to change :paths to ["resources" "src"]
you have one mvsj nested too many when you say "src/mvjs"
if you say (:require-macros [msvj.macros]) squint tries to look in all the paths mentioned in squint.edn + /msvj/macros.cljc added to that.
makes sense?
Note:
; works: different tree
(:require-macros [mvsj.resource :refer [nodize]])
; triggers and issue....
(:require-macros [mvsj.macros :refer [nodize]])
; [squint] Compiling CLJS file: /Users/zcpowers/Downloads/squint-:
; mol/src/mvsj/core.cljs
; node:fs:441
; path = getValidatedPath(path);
;
; TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type ;
; string or an instance of Buffer or URL. Received null
; at Module.readFileSync (node:fs:441:14)Yes. The path is much clearer now. I also see how the compiled MJS files look in the output. I put the issue about but as the first one works I am def unblocked!
I think the error just means that it can't find the macro file on the path (is my guess)
I see two times the same :require-macros in your previous post, but maybe I'm misreading
Updated the words. The first one uses resources/ the second users src/mvsj/macros
oh resource vs macros
The first is how you structures you macros in the squint repo; the second in the test-project
order of operations?
sorry I don't follow and I don't see any difference between how it's described in the README and in the test-project. If you want to make sure I get, post your project on github so I can clone it
I'll be back later
Yes. I will troubleshoot. Thank you for your time.
Macros import correctly and they compile . Now I need to try using them
git clone
cd squint-mol
npm i
npx squint compile