obsidian-typings 1.0.0 → 1.0.1

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.
@@ -0,0 +1,18 @@
1
+ name: Publish
2
+ on:
3
+ push:
4
+ tags:
5
+ - '*'
6
+ jobs:
7
+ build:
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - uses: actions/checkout@v4
11
+ - uses: actions/setup-node@v3
12
+ with:
13
+ node-version: '20.x'
14
+ registry-url: 'https://registry.npmjs.org'
15
+ - run: npm ci
16
+ - run: npm publish
17
+ env:
18
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ ## v1.0.0 (initial npm release)
4
+ - Made package installable via npm
5
+ - Clarified README, added contribution guidelines
@@ -0,0 +1,238 @@
1
+ # Introduction
2
+
3
+ ## General Notes
4
+ Feel free to start typing any part of the Obsidian API that is not yet typed, or fixing/adding additional descriptions to existing typings.
5
+ If you are unsure about anything, don't hesitate to open an issue.
6
+
7
+ ### TSDoc
8
+ Please use [TSDoc](https://tsdoc.org/) to document the typings. This will allow the documentation to be automatically generated
9
+ within your IDE, and can help with the discoverability of the typings.
10
+
11
+
12
+ Example:
13
+ ```ts
14
+ interface someObject {
15
+ /**
16
+ * Does something specific
17
+ * @param val1 Enables some functionality
18
+ * @tutorial Useful for implementing some features for your plugin
19
+ * @remark Prefer using `someOtherMethod` instead
20
+ */
21
+ someMethod(val1: boolean): number;
22
+
23
+ /**
24
+ * Does something that you're not certain about, and should probably not be used
25
+ * @internal
26
+ */
27
+ someInternalMethod(): void;
28
+ }
29
+ ```
30
+
31
+ > [!NOTE]
32
+ > `@internal` --- Method is *very likely* not fully/correctly typed, and/or is not intended to be used by plugins.
33
+ >
34
+ > `@remark` --- Alternatives that should be used instead, or warnings about the function.
35
+ >
36
+ > `@tutorial` --- Short description on how the function could be used in your plugin.
37
+ >
38
+ > `@deprecated` --- Method is deprecated in a particular version (can't be found in `app.js` anymore).
39
+
40
+
41
+ # Tutorial
42
+
43
+ ## Adding new typings
44
+
45
+ ### Finding/Discovering new typings
46
+
47
+ The first step to add new typings, is finding the object/interface/module you want to add typings for within the Obsidian app.
48
+ One of the easiest way to do this, is to open the developer console (Ctrl+Shift+I), and start searching for the interface you wish to
49
+ type from the `app.` object.
50
+
51
+ If you want to, for example, add typings for the `InternalPlugins` object, you can type `app.internalPlugins` into the console,
52
+ which will produce the following output:
53
+
54
+ ![images/prototype-reference.png](images/prototype-reference.png)
55
+
56
+ Note how the internalPlugins object contains multiple prototypes: the `InternalPlugins` interface itself, but also
57
+ the `Events` class and then the `Object` literal (does not need to be typed). This can be determined this by looking at the other definitions in the (un)official API,
58
+ and checking whether the two objects define the same properties.
59
+
60
+ Thus, to define `InternalPlugin`, you can start by adding each of the methods and properties to a `InternalPlugins` interface:
61
+
62
+ ```ts
63
+ interface InternalPlugins extends Events {
64
+ // Variables
65
+ app: App;
66
+ config: Record<any, any>;
67
+ migration: any;
68
+ plugins: Record<any, any>;
69
+
70
+ // Methods
71
+ requestSaveConfig(): any;
72
+ enable(): any;
73
+ getEnabledPluginById(var1: any): any;
74
+ getEnabledPlugins(): any;
75
+ // ...
76
+ }
77
+ ```
78
+ To keep it simple, we first add `any` as type to every variable and method -- unless it is obvious what the type should be
79
+ (i.e. `app` will always be an instance of `App`).
80
+
81
+ Next up, is the most tedious part of adding typings: finding the correct types for each of the methods and variables.
82
+
83
+ ### Typing variables
84
+
85
+ The easiest way to start, is by tackling the variables first. For example, in the console output, you can see that `config`
86
+ is mapping a string to `true`. In this case, it would be safe to assume that the type of `config` is `Record<string, boolean>`.
87
+
88
+ ```ts
89
+ interface InternalPlugins extends Events {
90
+ // ...
91
+ config: Record<string, boolean>;
92
+ // ...
93
+ }
94
+ ```
95
+
96
+ However, you can take this one step further still by considering the fact that each string is essentialy a different plugin ID.
97
+ In this case, we might just define a new type that contains all the plugin IDs, and use this as the key for the `config` object:
98
+
99
+ ```ts
100
+ type InternalPluginName = 'audio-recorder' | 'backlink' | 'bookmarks' | 'canvas' /*| ... */;
101
+ interface InternalPlugins extends Events {
102
+ // ...
103
+ config: Record<InternalPluginName, boolean>;
104
+ // ...
105
+ }
106
+ ```
107
+
108
+ Similarly, you can define the `plugins` variable as `Record<InternalPluginName, any>`.
109
+
110
+ Further, it is safe to assume that each element in `Plugins` would be some instance of a `InternalPlugin` class, so we
111
+ will also need to add a new interface for this:
112
+
113
+ ```ts
114
+ interface InternalPlugin {
115
+ app: App;
116
+ commands: any;
117
+ // etc. (repeat the same procedure)
118
+ }
119
+
120
+ interface InternalPlugins extends Events {
121
+ // ...
122
+ plugins: Record<InternalPluginName, InternalPlugin>;
123
+ // ...
124
+ }
125
+ ```
126
+
127
+ Make sure to also add brief descriptions (using [TSDoc](https://tsdoc.org/)) to each of the variables. Mark variables that you are not entirely sure about with `@internal`.
128
+ Feel free to copy descriptions from previous typings, or from the official API.
129
+
130
+
131
+ ### Typing methods
132
+
133
+ Typing methods is a bit more difficult, as aside you will need to know what the method does, and what the expected input and output is.
134
+
135
+ You could start by typing the methods that do not take any arguments, and have a simple return type. For example, the `requestSaveConfig` method.
136
+ From the name, we can already make the assumption that this method will probably _not_ return anything, as it is just telling
137
+ the app that a config should be saved, the method will thus _likely_ be of type `void`.
138
+
139
+ However, to make sure whether this assumption is correct, you _**should**_ check the source code (see next section).
140
+ If possible, you can also run the method in the console, and see what happens (in this case, nothing happens, so it is likely just `void`).
141
+
142
+ As before, if you are not certain about the return type or the workings of the function in general,
143
+ add a `@internal` tag to the method description, and/or mark the return type as `any`.
144
+
145
+
146
+ ```ts
147
+ interface InternalPlugins extends Events {
148
+ // ...
149
+ /**
150
+ * @internal Request save of plugin configs
151
+ */
152
+ requestSaveConfig(): any;
153
+ // ...
154
+ }
155
+ ```
156
+
157
+ Next up, are methods that take arguments. For example, the `getEnabledPluginById` method takes a single argument.
158
+ It is very likely that this argument will just be of type `InternalPluginName`, but again, you could easily verify this by
159
+ running the method in the console (i.e. `app.internalPlugins.getEnabledPluginById('audio-recorder')` and `app.internalPlugins.getEnabledPluginById('wrong-id')`).
160
+
161
+ ```ts
162
+ interface InternalPlugins extends Events {
163
+ // ...
164
+ /**
165
+ * Get an internal plugin by ID
166
+ * @param id - ID of the plugin to get
167
+ * @returns Plugin instance
168
+ */
169
+ getEnabledPluginById(id: InternalPluginName): InternalPlugin;
170
+ // ...
171
+ }
172
+ ```
173
+
174
+
175
+ ## Traversing and analysing the source code
176
+
177
+ Finally, this is both the most tedious but also the most important technique: finding the definition of the method in the minified source code.
178
+
179
+ Start off by going back to the console, and going into the `Sources` tab. Here you will find the `app.js` file where
180
+ all the internal methods are defined.
181
+
182
+ 1. Go to the `Sources` tab
183
+ 2. Select the `app.js` file
184
+ 3. `Pretty format` the code (optional)
185
+ 4. Copy the code to your IDE of choice (optional, but recommended)
186
+
187
+
188
+ ![images/accessing-main.png](images/accessing-main.png)
189
+
190
+ With access to the minified code, you can now start searching through it and find the definition of the method you are trying to type.
191
+
192
+ For any method "XYZ", start by just searching for "XYZ". Generally, the method is defined as either:
193
+ - `t.XYZ = ...` (for prototype methods)
194
+ - `t.prototype.XYZ = ...` (for prototype methods)
195
+ - `function XYZ(` (for internal/minified methods)
196
+
197
+ At this stage, you might get lucky and get a single definition, or you might get multiple definitions. In the latter case,
198
+ you will need try to look at the context of the code to determine which interface/class the method belongs to.
199
+ The main tip for finding the correct definition, is to look at the other methods being defined on the prototype,
200
+ and check if these match with the other methods of your object.
201
+
202
+ With the correct line found for the definition, you can now start analysing the code to determine the input/output types
203
+ and its behaviour.
204
+
205
+ For example, the `requestSaveConfig` method (seen earlier) is defined as follows:
206
+
207
+ ```js
208
+ n.requestSaveConfig = at(n.saveConfig.bind(n), 1e3, !0),
209
+ ```
210
+
211
+ Here, we find the following three things:
212
+ - `at` is a minified function that takes three arguments, and its return value is the return value of the method
213
+ - `1e3` is shorthand notation for `1000`
214
+ - `!0` is shorthand notation for `true`
215
+
216
+ (There are many shorthands and structural changes that you will need to get used to in the minified code)
217
+
218
+ Since we don't know what `at` does, we need to start searching through the code again. Make sure to enable caps + whole word search, as `at` is a very common word.
219
+ Start by searching for `function at`, or `.prototype.at`. With any luck, this will lead you to the following definition:
220
+
221
+ ```js
222
+ function at(e, t, n) {
223
+ void 0 === t && (t = 0),
224
+ void 0 === n && (n = !1);
225
+ var i, r = null, o = null, a = null, s = 0, l = function() {
226
+ var t = o
227
+ , n = a;
228
+ /* ... */
229
+ }
230
+ }
231
+ ```
232
+
233
+ At this point, you may want to pass the code through your favourite flavour of LLM or de-minifier, to make the code more understandable.
234
+ In this case, it seems that a function is constructed and some timeouts are started/reset, and other shenanigans.
235
+ Since I personally didn't want to spend too much time on this, I forewent the effort of trying to understand what the code does,
236
+ and just marked the method as `@internal`. Generally, if you can't understand the code within 10 minutes, it's probably not something
237
+ you should be touching anyway. (Though feel free to open an issue if you understand what semi-arcane magic is happening here!)
238
+
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2023 Fevol
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Fevol
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,36 +1,63 @@
1
- This repository contains TypeScript typings for undocumented [Obsidian](https://obsidian.md/) API functions.
2
-
3
- There are three options for installing this package:
4
- 1. **Explicit type importing:** Each typing has to be imported explicitly, e.g. `import {App, MarkdownView} from "@fevol/obsidian-typings"`. <br> _Install via:_ `npm install --save-dev npm install @fevol/obsidian-typings`
5
-
6
-
7
-
8
-
9
-
10
- You can add the code as a submodule to your project - or as an NPM package via `npm install --save-dev npm install @fevol/obsidian-typings`.
11
-
12
- If you prefer to have automatic types discovery without needing to explicitly `import` current package, use `npm install --save-dev @types/obsidian-typings@npm:@fevol/obsidian-typings`
13
-
14
- These typings contain _almost_ all of the undocumented API methods and variables, excluding those that
15
- seem to be intended solely for internal use and will not be relevant for plugin development.
16
-
17
- Please be aware that there is a good reason why the functions and types defined here are not included with the official
18
- API definitions:
19
- - The methods are not fully defined, and will be changed or removed in the near-future
20
- - There is a high risk of the code behaving unexpectedly if used improperly
21
- - The function was never meant to be used
22
-
23
- So, please use the functions and variables provided with caution. Be prepared to update your code if the API changes,
24
- and only use the functions if you are confident that you understand what they do. Reference the [official API](https://github.com/obsidianmd/obsidian-api/blob/master/obsidian.d.ts)
25
- first to see if your problem may be solved with a documented function, or search
26
- in the #plugin-dev channel of the Obsidian Discord server.
27
-
28
- Furthermore, there is a very high chance that I made a mistake in the typings, despite my best efforts.
29
- All the types had to be deduced from either context, manually running the function, or the minified app code.
30
- You will have to verify if the code behaves as expected, both with regard to the expected types, as well as what
31
- the function description says.
32
-
33
- With all the scary disclaimers out of the way, hopefully these typings will help in removing 90% of the `@ts-ignore`s
34
- you have in your codebase, or let you discover solutions that didn't seem possible before.
35
-
36
- PR's and issue reports are welcome for missing, deprecated or incorrectly defined typings.
1
+
2
+ # Obsidian Extended Typings
3
+
4
+ This repository contains TypeScript typings for undocumented [Obsidian](https://obsidian.md/) API functions and variables and additional descriptions,
5
+ essentially extending the official [Obsidian API](https://github.com/obsidianmd/obsidian-api/blob/master/obsidian.d.ts).
6
+
7
+ Be aware that the typings currently only cover a subset of all methods: most of the `App` interface and its sub-interfaces
8
+ are covered, but typings for views like `Graph`, `Canvas`, ... are still missing -- contributions for these would be very welcome!
9
+
10
+ ## Installation
11
+
12
+ There are three options for installing this package:
13
+ 1. **Explicit type importing** <br> Each typing has to be imported explicitly from `obsidian-typings` instead of `obsidian`, e.g. `import {App, MarkdownView} from "obsidian-typings"`. <br> _Install via:_ `npm install --save-dev obsidian-typings`
14
+
15
+ 2. **Automatic type extending** (recommended) <br> The typings are automatically added to the existing `obsidian` module, so you can use them without any changes to your code. <br> _Install via:_ `npm install --save-dev @types/obsidian-typings@npm:obsidian-typings`
16
+
17
+ 3. **Add extended typings as submodule** <br> Your IDE will likely pick up the typings automatically when the project is added as a submodule for your plugin, this also makes it simpler to test and submit features to the repository. <br> _Install via:_ `git submodule add https://github.com/Fevol/obsidian-typings.git typings` (or any other folder)
18
+
19
+
20
+ ## Disclaimer
21
+
22
+ > [!WARNING]
23
+ > Make sure to read below section in detail before using these typings.
24
+
25
+ Please be aware that there is a good reason why (some of) the functions and types defined here are not included with the official API definitions:
26
+ - The methods are not fully defined, and will be changed or removed in the near-future
27
+ - There is a high risk of the code behaving unexpectedly if used improperly
28
+ - The function was never meant to be used
29
+
30
+ Please use the functions and variables provided with caution. Be prepared to update your code if the API changes,
31
+ and only use the functions if you are confident that you understand what they will do. Reference the [official API](https://github.com/obsidianmd/obsidian-api/blob/master/obsidian.d.ts)
32
+ first to see if your problem may be solved with a documented function, or search
33
+ in the #plugin-dev channel of the Obsidian Discord server. Some functions will also contain `@remark` TSDoc tags that provide
34
+ alternatives or better solutions.
35
+
36
+ Methods marked `@internal` are especially risky to use: these are either not fully typed yet, or are solely intended
37
+ to be used internally by the Obsidian app.
38
+
39
+ Furthermore, there is a very high chance that there are mistakes in the typings, despite best efforts.
40
+ All types had to be deduced from either context, manually running the function, or from the minified app code.
41
+ You _**should**_ verify that the code behaves as expected, both with regard to the expected (input/output)types, as well as what
42
+ the function description promises.
43
+
44
+ With these scary disclaimers out of the way, hopefully these typings will help you in removing 90% of the `@ts-ignore`s
45
+ you have in your codebase, or discover solutions that didn't seem possible before.
46
+
47
+
48
+ > [!NOTE]
49
+ > **TL;DR:** Use at your own risk, verify that the code behaves as expected, and be prepared to update your code if the API changes.
50
+ >
51
+ > `@internal` methods are especially risky to use.
52
+ >
53
+ > `@remark` tags give some warnings about the inputs/outputs of the function, or provide better alternatives.
54
+ >
55
+ > `@tutorial` gives additional information on how to use the function in your plugin.
56
+
57
+
58
+ ## Contributing
59
+
60
+ Feel free to start typing any part of the Obsidian API that is not yet typed, or fixing/adding additional descriptions to existing typings.
61
+ If you are unsure about anything, don't hesitate to open an issue.
62
+
63
+ A brief tutorial is available on how you can get started with adding new typings, or fixing existing ones, see: [CONTRIBUTING.md](CONTRIBUTING.md).
Binary file
Binary file