New limit of min 16 characters for plugin IDs

I've recently set a limit of minimum 16 characters on plugin IDs. This is because the plugin ID is globally unique and ideally should include some kind of namespace so that, for example, someone can create a "com.example.TOC" plugin and someone else a different "org.other.TOC" plugin. While if we allow reserving the name "TOC", it means there can be only one.

I just saw some errors on the plugin repo, which is why I'm making this post:

If these plugins belong to you, please update the ID. That limitation should be checked at publish time too in a following release (and I need to fix the repo script because it continues generating commits for these errors).

So you're saying Highlander rules do not apply to Joplin plugins? :stuck_out_tongue_winking_eye:

Sorry, couldn't resist.

2 Likes

I presume you mean the part of id after joplin-plugin-? Because joplin-plugin-inline-tags is certainly more than 16 symbols.

No, it's the id part in the manifest.json e.g.:

"id": "com.whatever.quick-links",

This is literally what I've just put in there. And for my other plugin too.

I know, I took it from your code to explain what was meant. IMO your namespace com.whatever. is not really meaningful, but it's your prerogative and doubtful anybody else would use it.

e.g. if I were to create a plugin, I'd use cx.evermeet.tessus. as my namespace.

I could not come up with a meaningful namespace ¯\_ (ツ)_/¯
Sure. I, too, have a domain name but how's that more meaningful I don't know.

A domain name is tied to you. You could also use your name, or anything that nobody else would use.

Who knows, maybe in a year somebody can't come up with a namespae either and also picks com.whatever.. You never know.
Or maybe you are lucky any they'll pick org.whatever. or com.cantpickaname. :wink:

As I said it's not really important and your choice. But keep in mind that changing the id along the road will mess up things for users, because they will have to delete the "old" plugin manually, otherwise people would have 2 versions of the same plugin. That's why picking a meaningful namespace should be done from the start and used for all your plugins.

These are the ones that are used so far:

"id": "io.github.jackgruber.copytags",
"id": "joplin.plugin.ambrt.backlinksToNote",
"id": "io.github.jackgruber.combine-notes",
"id": "joplin.plugin.ambrt.goToItem",
"id": "org.joplinapp.plugins.ToggleSidebars",
"id": "joplin.plugin.note.tabs",
"id": "io.github.jackgruber.backup",
"id": "io.github.jackgruber.note-overview",
"id": "joplin.plugin.benji.favorites",
"id": "outline",
"id": "plugin.calebjohn.MathMode",
"id": "osw.joplin.markdowncalc",
"id": "joplin.plugin.ambrt.convertToNewNote",

Right, that's so hard to come up with an ID so let's put rubbish in there...

(Warning - overly long post ahead... I got carried away, sorry...)
So I was curious as to how this kind of thing is handled on other projects to see if there was much in the way of a general consensus on the topic of publishing plugins.
This might be coming from a place of pure naivety but I found the following which seems to offer the two extremes of how to manage it:

Atom

  • Simply has a "name" field that must be unique to your package
    • i.e. from the documentation: Before you publish a package it is a good idea to check ahead of time if a package with the same name has already been published to the atom.io package registry. You can do that by visiting https://atom.io/packages/your-package-name to see if the package already exists. If it does, update your package's name to something that is available before proceeding.
    • Using the CLI installer it is a simple as apm install packageName
  • Otherwise the requirements are pretty basic
    • Name, description, repository, version, software/engine version
    • Author is a link to your actual GH account which must exist to publish (which creates the 'hard' link to the user to prevent extra packages turning up from typos and mistakes)

VSCode

  • Distinguishing between extensions seems to be name + user rather than having to pick a unique name
    This means
  • Allows for both the "proper" name as well as a "display" name
    • Using the cli installer you end up with ext install publisher.extension but the front end can show a longer display name
  • Requires an Azure Devops account and token to publish

Joplin

So Joplin seems to be halfway between the two in some ways and entirely different in others

  • ID is required to be unique - this new rule is basically just a voluntary unique name string from what I can work out - like in Atom
  • Name is just the front end display name - like in VSCode
  • No means of authentication for authors or repos or even a strict requirement
    • e.g. ambrt's plugins simply show "a" as the author and links to the discourse forum as the repo link rather than the actual repo (I don't mean to pick on ambrt as a user as such, the plugins themselves are fantastic but they are an obvious outlier when looking at them from the plugin repo)

What would make the most sense to me (confidently/idiotically said by somebody with no open source or even programming experience) is the following:

  • ID would use the VSCode system of author.name
    • This means that you get to keep the ability to have packages with the same name but unique per author - possibly sort them by downloads within Joplin (once/if that gets implemented)
    • As NPM is the hard requirement for publishing to the plugin repo - make a requirement that the 'author' field matches the NPM user to make sure this cannot be accidentally changed and pushed to the repo under a different user - therefore creating a 'new' plugin rather than a update
  • This last one I'm not so keen on for the sake of freedom of platform but have a requirement for a 'proper' repo in the homepage_url (github, gitlab etc. rather than fake or inappropriate links), possibly with a hard requirement to have a readme.md file at the root that could be used for additional linking to plugin info within Joplin.
1 Like

The way it works now is that when you publish a plugin, you reserve an ID, and that can't be used by anyone afterwards. It allows making sure that in particular a malicious actor can't publish a plugin with an existing ID and overwrite someone else plugin in the repo.

This idea of the voluntary unique ID comes from Yahoo Widgets as I've developed quite a few widgets back then, and I like how they had setup their packages.

Getting the ID from somewhere else I feels gets complicated because it's unique, so if you change your name or the plugin name, the ID would change too. It's better something less visible but permanent.

Another alternative is to assign a random ID when the plugin is added to the repo. But doing this means plugins installed manually won't have an ID, and it's not possible to safely derive one from the manifest, because any of the field can change.

As for authentication, it will always be anonymous anyway in the sense that we won't have a real names policy so developers are free to put whatever they want. Note that all the repo plugins go though npm, so we get for free everything that npm might require to create an account such as a valid email, and whatever requirements they have for publishing, such as immutable package versions which is important for security.

1 Like

Isn't the idea of using NPM to make sure this isn't a problem anyway? i.e. to update a package it has to continue with the same name so a rename wouldn't be an issue? The NPM names themselves are also unique and permanent (as I understand it) so even if a user changes their username somehow then that also wouldn't change much for the plugin I assume.

You mean the plugin ID should be the package name? I thought about this but there would be two issues:

  1. It means a plugin would have to be published for it to work, so it no longer would be possible to install a plugin from a file.

  2. Since we couldn't have an ID without a package, that would create a dependency to npmjs and I'd rather avoid that (we use npmjs for convenience but it's not required). Now the way it works means there's no dependency to anything, not even GitHub. One could create their own repo on a local network share, disconnected of everything, points the app to it, and it works.

Asking to provide a unique ID solves all this, and I think it's not really hard. If eventually it turns out it's a problem, we could even set it to some UUID when the plugin is created. But for now the plugin framework asks for it because I prefer a more readable ID.

I don't necessarily mean that the plugin name has to be the same as the NPM package, I just mean that because the manifest.json in the plugin repo already has the "_npm_package_name" - the package can be made immutable from there - i.e. cannot have two plugins with different IDs that have the same _npm_package_name.
You are right in that I haven't really been considering the non-repo plugins or just those who would prefer or need to install the plugin manually unless Joplin itself can somehow distinguish between a repo installed version and a manually installed one and have different rules for each case.
Just trying to think of ideas as this requirement seems to have already caused some confusion.