SketchAPI
SketchAPI copied to clipboard
Custom context params problem due to running plugin via cli
Hello there!
Task: To send param from Sketch CLI when running the Sketch plugin. Issue: the derived value of the JSON dictionary is of type object(expected string).
That's code of my plugin with commented output:
import { Document } from 'sketch/dom';
export default ({ documentPath }) => {
const hardcodedUrl = '/Users/alexander.gusev/QSE/infrastructure/repositories/qordoba-sketch-editor-renderer/sketches/zip.sketch';
console.log(documentPath); // '/Users/alexander.gusev/QSE/infrastructure/repositories/qordoba-sketch-editor-renderer/sketches/zip.sketch'
console.log(documentPath == hardcodedUrl); // true
console.log(documentPath === hardcodedUrl); // false
console.log(typeof documentPath); // 'object'
console.log(typeof documentPath.toString()); // 'object'
console.log(typeof documentPath.valueOf()); // Type error
// TypeError: Type error
// at valueOf[native code] (/)
// at /Users/alexander.gusev/QSE/sketch-plugin/sketch-plugin/sketch-plugin.sketchplugin/Contents/Sketch/__fitText.js:123:43
// at __skpm_run (/Users/alexander.gusev/QSE/sketch-plugin/sketch-plugin/sketch-plugin.sketchplugin/Contents/Sketch/__fitText.js:151:19)
// at __skpm_run[native code] (/)%
console.log(Object.entries(documentPath)); // []
console.log(Object.getOwnPropertyNames(documentPath)); // []
const document = Document.open(documentPath); // Error
// Error: An Obj-C exception occurred.
// at [native code] (/)
// at value (/Applications/Sketch.app/Contents/Resources/SketchAPI_dom.js:1:82729)
// at /Users/alexander.gusev/QSE/sketch-plugin/sketch-plugin/sketch-plugin.sketchplugin/Contents/Sketch/__fitText.js:133:74
// at __skpm_run (/Users/alexander.gusev/QSE/sketch-plugin/sketch-plugin/sketch-plugin.sketchplugin/Contents/Sketch/__fitText.js:155:19)
// at __skpm_run[native code] (/)
// nativeException: -[__NSCFString isFileURL]: unrecognized selector sent to instance 0x600002f78b80%
}
That's a bash command to run the plugin:
path/to/sketchtool run path/to/sketchplugin identifier --context='{"documentPath": "/Users/alexander.gusev/QSE/infrastructure/repositories/qordoba-sketch-editor-renderer/sketches/zip.sketch"}'
The solution I found is to use a String object explicitly:
import { Document } from 'sketch/dom';
export default ({ documentPath }) => {
const parsedDocumentPath = new String(documentPath).toString();
const document = Document.open(parsedDocumentPath); // works fine
}
Question: Is it the most preferable way to cast context value to string?
PS: by the way, as I understand, you override Object.prototype props for some reason. If so, do you think that overriding default behaviour is a good idea?
Yes I agree, there are a few pitfalls when using plugin context values this way. I got tripped up myself with this a few weeks ago, but it resolved itself in my case since I was using the values in a template literal, which also works ok:
export default ({ value }) => {
Document.open(`${value}/foo.sketch`); // also works
}
It would be nice to fix this so its less surprising, and the context values are usable directly.
the values from the context are native Obj-C objects. So you have an NSString instead of a String. Casting it to a string using \${value}`` or String(value) works fine.
The error in Document.open(documentPath) is probably because the value isn't casted correctly in the API (and that should be fixed)