@mnaoumov/obsidian-dev-toolkit 2.1.0 → 3.0.0

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.
Files changed (129) hide show
  1. package/README.md +5 -1
  2. package/bin/archive-demo-vault.mjs +8 -0
  3. package/bin/generate-coverage-badge.mjs +8 -0
  4. package/bundlers/esbuild-impl/feature-options/package.json +6 -0
  5. package/bundlers/obsidian-cli-reload/package.json +6 -0
  6. package/bundlers/obsidian-plugin-build/package.json +6 -0
  7. package/bundlers/obsidian-plugin-features/package.json +6 -0
  8. package/bundlers/obsidian-plugin-transforms/package.json +6 -0
  9. package/bundlers/obsidian-plugin-webpack-loader/package.json +6 -0
  10. package/bundlers/obsidian-plugins-folder-deployment/package.json +6 -0
  11. package/bundlers/parcel/package.json +6 -0
  12. package/bundlers/rollup/package.json +6 -0
  13. package/bundlers/rollup-compatible/package.json +6 -0
  14. package/bundlers/rollup-compatible-features/package.json +6 -0
  15. package/bundlers/vite/package.json +6 -0
  16. package/bundlers/webpack/package.json +6 -0
  17. package/dist/lib/cjs/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.cjs +3 -188
  18. package/dist/lib/cjs/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.d.cts +2 -18
  19. package/dist/lib/cjs/bundlers/esbuild-impl/feature-options.cjs +173 -0
  20. package/dist/lib/cjs/bundlers/esbuild-impl/feature-options.d.cts +60 -0
  21. package/dist/lib/cjs/bundlers/esbuild-impl/index.cjs +4 -1
  22. package/dist/lib/cjs/bundlers/esbuild-impl/index.d.cts +1 -0
  23. package/dist/lib/cjs/bundlers/esbuild-impl/obsidian-plugin-builder.cjs +30 -82
  24. package/dist/lib/cjs/bundlers/esbuild-impl/obsidian-plugin-builder.d.cts +7 -24
  25. package/dist/lib/cjs/bundlers/index.cjs +39 -3
  26. package/dist/lib/cjs/bundlers/index.d.cts +12 -0
  27. package/dist/lib/cjs/bundlers/obsidian-cli-reload.cjs +182 -0
  28. package/dist/lib/cjs/bundlers/obsidian-cli-reload.d.cts +37 -0
  29. package/dist/lib/cjs/bundlers/obsidian-plugin-build.cjs +278 -0
  30. package/dist/lib/cjs/bundlers/obsidian-plugin-build.d.cts +217 -0
  31. package/dist/lib/cjs/bundlers/obsidian-plugin-features.cjs +242 -0
  32. package/dist/lib/cjs/bundlers/obsidian-plugin-features.d.cts +186 -0
  33. package/dist/lib/cjs/bundlers/obsidian-plugin-transforms.cjs +306 -0
  34. package/dist/lib/cjs/bundlers/obsidian-plugin-transforms.d.cts +231 -0
  35. package/dist/lib/cjs/bundlers/obsidian-plugin-webpack-loader.cjs +182 -0
  36. package/dist/lib/cjs/bundlers/obsidian-plugin-webpack-loader.d.cts +47 -0
  37. package/dist/lib/cjs/bundlers/obsidian-plugins-folder-deployment.cjs +320 -0
  38. package/dist/lib/cjs/bundlers/obsidian-plugins-folder-deployment.d.cts +44 -0
  39. package/dist/lib/cjs/bundlers/parcel.cjs +462 -0
  40. package/dist/lib/cjs/bundlers/parcel.d.cts +128 -0
  41. package/dist/lib/cjs/bundlers/rollup-compatible-features.cjs +181 -0
  42. package/dist/lib/cjs/bundlers/rollup-compatible-features.d.cts +128 -0
  43. package/dist/lib/cjs/bundlers/rollup-compatible.cjs +138 -0
  44. package/dist/lib/cjs/bundlers/rollup-compatible.d.cts +84 -0
  45. package/dist/lib/cjs/bundlers/rollup.cjs +218 -0
  46. package/dist/lib/cjs/bundlers/rollup.d.cts +99 -0
  47. package/dist/lib/cjs/bundlers/vite.cjs +229 -0
  48. package/dist/lib/cjs/bundlers/vite.d.cts +105 -0
  49. package/dist/lib/cjs/bundlers/webpack.cjs +354 -0
  50. package/dist/lib/cjs/bundlers/webpack.d.cts +133 -0
  51. package/dist/lib/cjs/demo-vault-cli.cjs +131 -0
  52. package/dist/lib/cjs/demo-vault-cli.d.cts +15 -0
  53. package/dist/lib/cjs/index.cjs +4 -1
  54. package/dist/lib/cjs/index.d.cts +1 -0
  55. package/dist/lib/cjs/test-runners/coverage-badge-cli.cjs +160 -0
  56. package/dist/lib/cjs/test-runners/coverage-badge-cli.d.cts +25 -0
  57. package/dist/lib/cjs/test-runners/coverage-badge.cjs +279 -0
  58. package/dist/lib/cjs/test-runners/coverage-badge.d.cts +143 -0
  59. package/dist/lib/cjs/test-runners/e2e-runner-support.cjs +170 -0
  60. package/dist/lib/cjs/test-runners/e2e-runner-support.d.cts +36 -0
  61. package/dist/lib/cjs/test-runners/index.cjs +18 -3
  62. package/dist/lib/cjs/test-runners/index.d.cts +5 -0
  63. package/dist/lib/cjs/test-runners/obsidian-test-runner.cjs +147 -0
  64. package/dist/lib/cjs/test-runners/obsidian-test-runner.d.cts +42 -0
  65. package/dist/lib/cjs/test-runners/wdio-obsidian.cjs +205 -0
  66. package/dist/lib/cjs/test-runners/wdio-obsidian.d.cts +199 -0
  67. package/dist/lib/esm/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.d.mts +2 -18
  68. package/dist/lib/esm/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.mjs +3 -192
  69. package/dist/lib/esm/bundlers/esbuild-impl/feature-options.d.mts +60 -0
  70. package/dist/lib/esm/bundlers/esbuild-impl/feature-options.mjs +82 -0
  71. package/dist/lib/esm/bundlers/esbuild-impl/index.d.mts +1 -0
  72. package/dist/lib/esm/bundlers/esbuild-impl/index.mjs +3 -1
  73. package/dist/lib/esm/bundlers/esbuild-impl/obsidian-plugin-builder.d.mts +7 -24
  74. package/dist/lib/esm/bundlers/esbuild-impl/obsidian-plugin-builder.mjs +41 -87
  75. package/dist/lib/esm/bundlers/index.d.mts +12 -0
  76. package/dist/lib/esm/bundlers/index.mjs +26 -2
  77. package/dist/lib/esm/bundlers/obsidian-cli-reload.d.mts +37 -0
  78. package/dist/lib/esm/bundlers/obsidian-cli-reload.mjs +83 -0
  79. package/dist/lib/esm/bundlers/obsidian-plugin-build.d.mts +217 -0
  80. package/dist/lib/esm/bundlers/obsidian-plugin-build.mjs +166 -0
  81. package/dist/lib/esm/bundlers/obsidian-plugin-features.d.mts +186 -0
  82. package/dist/lib/esm/bundlers/obsidian-plugin-features.mjs +126 -0
  83. package/dist/lib/esm/bundlers/obsidian-plugin-transforms.d.mts +231 -0
  84. package/dist/lib/esm/bundlers/obsidian-plugin-transforms.mjs +194 -0
  85. package/dist/lib/esm/bundlers/obsidian-plugin-webpack-loader.d.mts +47 -0
  86. package/dist/lib/esm/bundlers/obsidian-plugin-webpack-loader.mjs +89 -0
  87. package/dist/lib/esm/bundlers/obsidian-plugins-folder-deployment.d.mts +44 -0
  88. package/dist/lib/esm/bundlers/obsidian-plugins-folder-deployment.mjs +228 -0
  89. package/dist/lib/esm/bundlers/parcel.d.mts +128 -0
  90. package/dist/lib/esm/bundlers/parcel.mjs +361 -0
  91. package/dist/lib/esm/bundlers/rollup-compatible-features.d.mts +128 -0
  92. package/dist/lib/esm/bundlers/rollup-compatible-features.mjs +93 -0
  93. package/dist/lib/esm/bundlers/rollup-compatible.d.mts +84 -0
  94. package/dist/lib/esm/bundlers/rollup-compatible.mjs +43 -0
  95. package/dist/lib/esm/bundlers/rollup.d.mts +99 -0
  96. package/dist/lib/esm/bundlers/rollup.mjs +130 -0
  97. package/dist/lib/esm/bundlers/vite.d.mts +105 -0
  98. package/dist/lib/esm/bundlers/vite.mjs +144 -0
  99. package/dist/lib/esm/bundlers/webpack.d.mts +133 -0
  100. package/dist/lib/esm/bundlers/webpack.mjs +259 -0
  101. package/dist/lib/esm/demo-vault-cli.d.mts +15 -0
  102. package/dist/lib/esm/demo-vault-cli.mjs +23 -0
  103. package/dist/lib/esm/index.d.mts +1 -0
  104. package/dist/lib/esm/index.mjs +3 -1
  105. package/dist/lib/esm/test-runners/coverage-badge-cli.d.mts +25 -0
  106. package/dist/lib/esm/test-runners/coverage-badge-cli.mjs +51 -0
  107. package/dist/lib/esm/test-runners/coverage-badge.d.mts +143 -0
  108. package/dist/lib/esm/test-runners/coverage-badge.mjs +181 -0
  109. package/dist/lib/esm/test-runners/e2e-runner-support.d.mts +36 -0
  110. package/dist/lib/esm/test-runners/e2e-runner-support.mjs +61 -0
  111. package/dist/lib/esm/test-runners/index.d.mts +5 -0
  112. package/dist/lib/esm/test-runners/index.mjs +12 -2
  113. package/dist/lib/esm/test-runners/obsidian-test-runner.d.mts +42 -0
  114. package/dist/lib/esm/test-runners/obsidian-test-runner.mjs +52 -0
  115. package/dist/lib/esm/test-runners/wdio-obsidian.d.mts +199 -0
  116. package/dist/lib/esm/test-runners/wdio-obsidian.mjs +110 -0
  117. package/package.json +102 -4
  118. package/test-runners/coverage-badge/package.json +6 -0
  119. package/test-runners/coverage-badge-cli/package.json +6 -0
  120. package/test-runners/e2e-runner-support/package.json +6 -0
  121. package/test-runners/obsidian-test-runner/package.json +6 -0
  122. package/test-runners/wdio-obsidian/package.json +6 -0
  123. package/tsconfig/preact.json +7 -0
  124. package/tsconfig/react.json +7 -0
  125. package/tsconfig/solid.json +7 -0
  126. package/tsconfig/svelte.json +7 -0
  127. package/tsconfig/vue.json +7 -0
  128. package/types/styles.d.ts +32 -0
  129. package/types/wasm.d.ts +11 -0
@@ -0,0 +1,217 @@
1
+ /// <reference path="../library-references.d.mts" />
2
+ /**
3
+ * @file
4
+ *
5
+ * The bundler-independent half of building an Obsidian plugin: which modules stay external, where the
6
+ * output goes, what the output folder holds besides the bundle, and how a development build reaches the
7
+ * vault. Every bundler adapter in this folder (esbuild, rollup, vite, webpack, parcel) is a thin layer over
8
+ * it, so all of them produce the same `main.js` + `styles.css` + `manifest.json` layout.
9
+ */
10
+ /**
11
+ * Enumeration representing the build modes.
12
+ */
13
+ export declare enum BuildMode {
14
+ /**
15
+ Development mode for building the plugin
16
+ */
17
+ Development = 0,
18
+ /**
19
+ Production mode for building the plugin
20
+ */
21
+ Production = 1
22
+ }
23
+ /**
24
+ * The modules Obsidian supplies at runtime. A plugin must never bundle its own copy of them: a second copy
25
+ * of the API breaks `instanceof` against the running one, and a second CodeMirror breaks every extension.
26
+ *
27
+ * `esbuild` and `eslint` are here because a plugin that imports one of the toolkit's build-time modules
28
+ * would otherwise drag either into `main.js`.
29
+ */
30
+ export declare const OBSIDIAN_PLUGIN_RUNTIME_MODULES: readonly string[];
31
+ /**
32
+ * The module ids an Obsidian plugin bundle leaves to `require()` at runtime: the
33
+ * {@link OBSIDIAN_PLUGIN_RUNTIME_MODULES} and the Node builtins. Every `node:`-prefixed id is external too,
34
+ * which a bundler takes as a pattern (esbuild's `node:*`) or through {@link isObsidianPluginExternal}.
35
+ */
36
+ export declare const OBSIDIAN_PLUGIN_EXTERNALS: readonly string[];
37
+ /**
38
+ * A CSS file a bundler emitted, as {@link mergeCssAssets} sees it.
39
+ */
40
+ export interface CssAsset {
41
+ /**
42
+ * The file name relative to the output folder.
43
+ */
44
+ readonly fileName: string;
45
+ /**
46
+ * The file's contents.
47
+ */
48
+ readonly source: string;
49
+ }
50
+ /**
51
+ * What {@link mergeCssAssets} decided.
52
+ */
53
+ export interface MergeCssAssetsResult {
54
+ /**
55
+ * The file names to drop from the output, because their contents moved into `styles.css`. Includes
56
+ * `styles.css` itself when the bundler already emitted one, so it is always written afresh.
57
+ */
58
+ readonly fileNamesToRemove: readonly string[];
59
+ /**
60
+ * The contents of `styles.css`, or `undefined` when there is nothing to do: the bundle has no CSS at all,
61
+ * or its one CSS file already is `styles.css`.
62
+ */
63
+ readonly stylesCss: string | undefined;
64
+ }
65
+ /**
66
+ * Where a plugin build writes its output and what it builds.
67
+ */
68
+ export interface ObsidianPluginBuildContext {
69
+ /**
70
+ * The absolute path of the folder the build writes `main.js`, `styles.css` and `manifest.json` into.
71
+ */
72
+ readonly distFolder: string;
73
+ /**
74
+ * The absolute path of the plugin's entry point, `src/main.ts`.
75
+ */
76
+ readonly entryPoint: string;
77
+ /**
78
+ * Whether this is a production build.
79
+ */
80
+ readonly isProductionBuild: boolean;
81
+ /**
82
+ * The absolute path of the emitted `main.js`.
83
+ */
84
+ readonly mainJsPath: string;
85
+ /**
86
+ * The Obsidian configuration folder a development build is deployed into, or an empty string when none
87
+ * is configured.
88
+ */
89
+ readonly obsidianConfigFolder: string;
90
+ /**
91
+ * The plugin's folder name inside `<vault>/.obsidian/plugins`, which is the package name.
92
+ */
93
+ readonly pluginName: string;
94
+ /**
95
+ * How a development build is reloaded in Obsidian once it is deployed.
96
+ */
97
+ readonly reload: ObsidianPluginReload;
98
+ }
99
+ /**
100
+ * Where a development build is deployed and how Obsidian picks it up. Every bundler adapter takes these.
101
+ */
102
+ export interface ObsidianPluginDeploymentOptions {
103
+ /**
104
+ * A folder for Obsidian configuration. Defaults to the `OBSIDIAN_CONFIG_FOLDER` environment variable,
105
+ * read from the process or from a `.env` file in the project root.
106
+ */
107
+ readonly obsidianConfigFolder?: string;
108
+ /**
109
+ * How a development build is reloaded in Obsidian once it is copied into the vault. Defaults to
110
+ * `'hot-reload-plugin'`.
111
+ */
112
+ readonly reload?: ObsidianPluginReload;
113
+ }
114
+ /**
115
+ * How a development build is reloaded in Obsidian once it is copied into the vault.
116
+ *
117
+ * - `'hot-reload-plugin'`: the build writes the `.hotreload` marker, and `npm run dev` opens the vault in an
118
+ * Obsidian instance it owns, with the HotReload plugin installed and enabled there.
119
+ * - `'obsidian-cli'`: every rebuild runs `obsidian plugin:reload` against the Obsidian you already have open,
120
+ * through the Obsidian CLI (Settings → General → Command line interface). No HotReload, no second instance.
121
+ * - `false`: the build is copied into the vault and nothing reloads it.
122
+ */
123
+ export type ObsidianPluginReload = 'hot-reload-plugin' | 'obsidian-cli' | false;
124
+ /**
125
+ * Options for {@link resolveObsidianPluginBuildContext}.
126
+ */
127
+ export interface ResolveObsidianPluginBuildContextParams extends ObsidianPluginDeploymentOptions {
128
+ /**
129
+ * The output folder. Defaults to `dist/build` for a production build and `dist/dev` for a development
130
+ * one.
131
+ */
132
+ readonly distFolder?: string;
133
+ /**
134
+ * The build mode.
135
+ */
136
+ readonly mode: BuildMode;
137
+ }
138
+ /**
139
+ * Removes the output folder of a build and creates it empty again.
140
+ *
141
+ * @param distFolder - The output folder.
142
+ * @returns A {@link Promise} that resolves once the folder exists and is empty.
143
+ */
144
+ export declare function cleanObsidianPluginDistFolder(distFolder: string): Promise<void>;
145
+ /**
146
+ * Puts the files a plugin folder needs besides the bundle into the output folder: `manifest.json`, and for
147
+ * a development build reloaded by the HotReload plugin the empty `.hotreload` marker it watches for.
148
+ *
149
+ * @param context - The build context.
150
+ * @returns A {@link Promise} that resolves once the files are written.
151
+ */
152
+ export declare function completeObsidianPluginDistFolder(context: ObsidianPluginBuildContext): Promise<void>;
153
+ /**
154
+ * Builds the banner placed at the top of `main.js`.
155
+ *
156
+ * @param bundlerName - The bundler's name, as the banner states it.
157
+ * @returns The banner, a block comment followed by a newline.
158
+ */
159
+ export declare function getObsidianPluginBanner(bundlerName: string): string;
160
+ /**
161
+ * Resolves the default output folder of a build: `dist/build` for a production build, `dist/dev` for a
162
+ * development one.
163
+ *
164
+ * @param mode - The build mode.
165
+ * @returns The absolute path of the output folder.
166
+ */
167
+ export declare function getObsidianPluginDistFolder(mode: BuildMode): string;
168
+ /**
169
+ * Resolves the plugin's entry point, `src/main.ts`.
170
+ *
171
+ * @returns The absolute path of the entry point.
172
+ */
173
+ export declare function getObsidianPluginEntryPoint(): string;
174
+ /**
175
+ * Tells whether a file name is a CSS file.
176
+ *
177
+ * @param fileName - The file name.
178
+ * @returns `true` for a `.css` file.
179
+ */
180
+ export declare function isCssFileName(fileName: string): boolean;
181
+ /**
182
+ * Tells whether a module id is one an Obsidian plugin bundle must leave external: one of
183
+ * {@link OBSIDIAN_PLUGIN_EXTERNALS}, a subpath of one (`@codemirror/view/dist/index.js`, `fs/promises`),
184
+ * or any `node:`-prefixed id.
185
+ *
186
+ * @param moduleId - The module id as written in the importing file.
187
+ * @returns `true` when the bundle must leave the module to `require()` at runtime.
188
+ */
189
+ export declare function isObsidianPluginExternal(moduleId: string): boolean;
190
+ /**
191
+ * Decides how the CSS a bundler emitted becomes the one `styles.css` Obsidian loads.
192
+ *
193
+ * Obsidian reads a plugin's stylesheet from `styles.css` and nothing else, while a bundler names the CSS
194
+ * after the entry (`main.css`), after the package, or with a content hash. A lone CSS file is renamed; when
195
+ * there are several, they are concatenated in the order given.
196
+ *
197
+ * @param cssAssets - The CSS files the bundler emitted, in output order.
198
+ * @returns What to write as `styles.css` and which emitted files to drop.
199
+ */
200
+ export declare function mergeCssAssets(cssAssets: readonly CssAsset[]): MergeCssAssetsResult;
201
+ /**
202
+ * Resolves a path against the project root.
203
+ *
204
+ * @param path - The path, relative to the project root or absolute.
205
+ * @returns The absolute path.
206
+ */
207
+ export declare function resolveFromRoot(path: string): string;
208
+ /**
209
+ * Resolves where a plugin build writes its output, which entry point it builds and which vault a
210
+ * development build is deployed into.
211
+ *
212
+ * Loads the project's `.env` file first, so `OBSIDIAN_CONFIG_FOLDER` can live there.
213
+ *
214
+ * @param params - The {@link ResolveObsidianPluginBuildContextParams}.
215
+ * @returns A {@link Promise} that resolves to the {@link ObsidianPluginBuildContext}.
216
+ */
217
+ export declare function resolveObsidianPluginBuildContext(params: ResolveObsidianPluginBuildContextParams): Promise<ObsidianPluginBuildContext>;
@@ -0,0 +1,166 @@
1
+ /*
2
+ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
3
+ if you want to view the source, please visit the github repository of this plugin
4
+ */
5
+ (function () {
6
+ function ensureBrowserProcess() {
7
+ const browserProcess = {
8
+ browser: true,
9
+ cwd() {
10
+ return "/";
11
+ },
12
+ env: {},
13
+ platform: "android"
14
+ };
15
+ const existingProcess = globalThis.process;
16
+ if (!existingProcess) {
17
+ globalThis.process = browserProcess;
18
+ return;
19
+ }
20
+ if (existingProcess.versions?.node) {
21
+ return;
22
+ }
23
+ const existingProcessRecord = existingProcess;
24
+ for (const [key, value] of Object.entries(browserProcess)) {
25
+ existingProcessRecord[key] ??= value;
26
+ }
27
+ existingProcessRecord["browser"] = true;
28
+ }
29
+
30
+ ensureBrowserProcess();
31
+ })();
32
+
33
+ import { readPackageJson } from "@mnaoumov/typescript-dev-toolkit/npm";
34
+ import { resolvePathFromRoot } from "@mnaoumov/typescript-dev-toolkit/root";
35
+ import {
36
+ basename,
37
+ join
38
+ } from "@mnaoumov/typescript-lib/path";
39
+ import { ensureNonNullable } from "@mnaoumov/typescript-lib/type-guards";
40
+ import { existsSync } from "node:fs";
41
+ import {
42
+ cp,
43
+ mkdir,
44
+ rm,
45
+ writeFile
46
+ } from "node:fs/promises";
47
+ import { builtinModules } from "node:module";
48
+ import process, { loadEnvFile } from "node:process";
49
+ import { ObsidianPluginRepoPaths } from "../obsidian-plugin-repo-paths.mjs";
50
+ var BuildMode = /* @__PURE__ */ ((BuildMode2) => {
51
+ BuildMode2[BuildMode2["Development"] = 0] = "Development";
52
+ BuildMode2[BuildMode2["Production"] = 1] = "Production";
53
+ return BuildMode2;
54
+ })(BuildMode || {});
55
+ const OBSIDIAN_PLUGIN_RUNTIME_MODULES = [
56
+ "obsidian",
57
+ "electron",
58
+ "@codemirror/autocomplete",
59
+ "@codemirror/collab",
60
+ "@codemirror/commands",
61
+ "@codemirror/language",
62
+ "@codemirror/lint",
63
+ "@codemirror/search",
64
+ "@codemirror/state",
65
+ "@codemirror/view",
66
+ "@lezer/common",
67
+ "@lezer/highlight",
68
+ "@lezer/lr",
69
+ "esbuild",
70
+ "eslint"
71
+ ];
72
+ const OBSIDIAN_PLUGIN_EXTERNALS = [
73
+ ...OBSIDIAN_PLUGIN_RUNTIME_MODULES,
74
+ ...builtinModules
75
+ ];
76
+ const NODE_PREFIX = "node:";
77
+ const STYLES_CSS_FILE_NAME = ObsidianPluginRepoPaths.StylesCss;
78
+ const OBSIDIAN_PLUGIN_EXTERNALS_SET = new Set(OBSIDIAN_PLUGIN_EXTERNALS);
79
+ async function cleanObsidianPluginDistFolder(distFolder) {
80
+ if (existsSync(distFolder)) {
81
+ await rm(distFolder, { recursive: true });
82
+ }
83
+ await mkdir(distFolder, { recursive: true });
84
+ }
85
+ async function completeObsidianPluginDistFolder(context) {
86
+ await mkdir(context.distFolder, { recursive: true });
87
+ if (!context.isProductionBuild && context.reload === "hot-reload-plugin") {
88
+ await writeFile(join(context.distFolder, ObsidianPluginRepoPaths.HotReload), "", "utf-8");
89
+ }
90
+ const manifestPath = resolvePathFromRoot({ path: ObsidianPluginRepoPaths.ManifestJson });
91
+ if (manifestPath && existsSync(manifestPath)) {
92
+ await cp(manifestPath, join(context.distFolder, ObsidianPluginRepoPaths.ManifestJson));
93
+ }
94
+ }
95
+ function getObsidianPluginBanner(bundlerName) {
96
+ return `/*
97
+ THIS IS A GENERATED/BUNDLED FILE BY ${bundlerName.toUpperCase()}
98
+ if you want to view the source, please visit the github repository of this plugin
99
+ */
100
+ `;
101
+ }
102
+ function getObsidianPluginDistFolder(mode) {
103
+ return resolveFromRoot(mode === 1 /* Production */ ? ObsidianPluginRepoPaths.DistBuild : ObsidianPluginRepoPaths.DistDev);
104
+ }
105
+ function getObsidianPluginEntryPoint() {
106
+ return resolveFromRoot(join(ObsidianPluginRepoPaths.Src, ObsidianPluginRepoPaths.MainTs));
107
+ }
108
+ function isCssFileName(fileName) {
109
+ return basename(fileName).toLowerCase().endsWith(".css");
110
+ }
111
+ function isObsidianPluginExternal(moduleId) {
112
+ if (moduleId.startsWith(NODE_PREFIX) || OBSIDIAN_PLUGIN_EXTERNALS_SET.has(moduleId)) {
113
+ return true;
114
+ }
115
+ const SCOPED_PACKAGE_SEGMENT_COUNT = 2;
116
+ const packageName = moduleId.split("/").slice(0, moduleId.startsWith("@") ? SCOPED_PACKAGE_SEGMENT_COUNT : 1).join("/");
117
+ return packageName !== moduleId && OBSIDIAN_PLUGIN_EXTERNALS_SET.has(packageName);
118
+ }
119
+ function mergeCssAssets(cssAssets) {
120
+ const [firstCssAsset] = cssAssets;
121
+ if (firstCssAsset === void 0 || cssAssets.length === 1 && firstCssAsset.fileName === STYLES_CSS_FILE_NAME) {
122
+ return { fileNamesToRemove: [], stylesCss: void 0 };
123
+ }
124
+ return {
125
+ fileNamesToRemove: cssAssets.map((asset) => asset.fileName),
126
+ stylesCss: cssAssets.map((asset) => asset.source).join("\n")
127
+ };
128
+ }
129
+ function resolveFromRoot(path) {
130
+ return ensureNonNullable(resolvePathFromRoot({ path }), `Could not resolve '${path}' against the project root`);
131
+ }
132
+ async function resolveObsidianPluginBuildContext(params) {
133
+ const envPath = resolvePathFromRoot({ path: ".env" });
134
+ if (envPath && existsSync(envPath)) {
135
+ loadEnvFile(envPath);
136
+ }
137
+ const obsidianPluginBuilderEnv = process.env;
138
+ const isProductionBuild = params.mode === 1 /* Production */;
139
+ const distFolder = params.distFolder === void 0 ? getObsidianPluginDistFolder(params.mode) : resolveFromRoot(params.distFolder);
140
+ const packageJson = await readPackageJson();
141
+ return {
142
+ distFolder,
143
+ entryPoint: getObsidianPluginEntryPoint(),
144
+ isProductionBuild,
145
+ mainJsPath: join(distFolder, ObsidianPluginRepoPaths.MainJs),
146
+ obsidianConfigFolder: params.obsidianConfigFolder ?? obsidianPluginBuilderEnv.OBSIDIAN_CONFIG_FOLDER ?? "",
147
+ pluginName: packageJson.name ?? "(unknown)",
148
+ reload: params.reload ?? "hot-reload-plugin"
149
+ };
150
+ }
151
+ export {
152
+ BuildMode,
153
+ OBSIDIAN_PLUGIN_EXTERNALS,
154
+ OBSIDIAN_PLUGIN_RUNTIME_MODULES,
155
+ cleanObsidianPluginDistFolder,
156
+ completeObsidianPluginDistFolder,
157
+ getObsidianPluginBanner,
158
+ getObsidianPluginDistFolder,
159
+ getObsidianPluginEntryPoint,
160
+ isCssFileName,
161
+ isObsidianPluginExternal,
162
+ mergeCssAssets,
163
+ resolveFromRoot,
164
+ resolveObsidianPluginBuildContext
165
+ };
166
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9idW5kbGVycy9vYnNpZGlhbi1wbHVnaW4tYnVpbGQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFRoZSBidW5kbGVyLWluZGVwZW5kZW50IGhhbGYgb2YgYnVpbGRpbmcgYW4gT2JzaWRpYW4gcGx1Z2luOiB3aGljaCBtb2R1bGVzIHN0YXkgZXh0ZXJuYWwsIHdoZXJlIHRoZVxuICogb3V0cHV0IGdvZXMsIHdoYXQgdGhlIG91dHB1dCBmb2xkZXIgaG9sZHMgYmVzaWRlcyB0aGUgYnVuZGxlLCBhbmQgaG93IGEgZGV2ZWxvcG1lbnQgYnVpbGQgcmVhY2hlcyB0aGVcbiAqIHZhdWx0LiBFdmVyeSBidW5kbGVyIGFkYXB0ZXIgaW4gdGhpcyBmb2xkZXIgKGVzYnVpbGQsIHJvbGx1cCwgdml0ZSwgd2VicGFjaywgcGFyY2VsKSBpcyBhIHRoaW4gbGF5ZXIgb3ZlclxuICogaXQsIHNvIGFsbCBvZiB0aGVtIHByb2R1Y2UgdGhlIHNhbWUgYG1haW4uanNgICsgYHN0eWxlcy5jc3NgICsgYG1hbmlmZXN0Lmpzb25gIGxheW91dC5cbiAqL1xuXG5pbXBvcnQgeyByZWFkUGFja2FnZUpzb24gfSBmcm9tICdAbW5hb3Vtb3YvdHlwZXNjcmlwdC1kZXYtdG9vbGtpdC9ucG0nO1xuaW1wb3J0IHsgcmVzb2x2ZVBhdGhGcm9tUm9vdCB9IGZyb20gJ0BtbmFvdW1vdi90eXBlc2NyaXB0LWRldi10b29sa2l0L3Jvb3QnO1xuaW1wb3J0IHtcbiAgYmFzZW5hbWUsXG4gIGpvaW5cbn0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL3BhdGgnO1xuaW1wb3J0IHsgZW5zdXJlTm9uTnVsbGFibGUgfSBmcm9tICdAbW5hb3Vtb3YvdHlwZXNjcmlwdC1saWIvdHlwZS1ndWFyZHMnO1xuaW1wb3J0IHsgZXhpc3RzU3luYyB9IGZyb20gJ25vZGU6ZnMnO1xuaW1wb3J0IHtcbiAgY3AsXG4gIG1rZGlyLFxuICBybSxcbiAgd3JpdGVGaWxlXG59IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnO1xuaW1wb3J0IHsgYnVpbHRpbk1vZHVsZXMgfSBmcm9tICdub2RlOm1vZHVsZSc7XG5pbXBvcnQgcHJvY2VzcywgeyBsb2FkRW52RmlsZSB9IGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5cbmltcG9ydCB7IE9ic2lkaWFuUGx1Z2luUmVwb1BhdGhzIH0gZnJvbSAnLi4vb2JzaWRpYW4tcGx1Z2luLXJlcG8tcGF0aHMudHMnO1xuXG4vKipcbiAqIEVudW1lcmF0aW9uIHJlcHJlc2VudGluZyB0aGUgYnVpbGQgbW9kZXMuXG4gKi9cbmV4cG9ydCBlbnVtIEJ1aWxkTW9kZSB7XG4gIC8qKlxuICBEZXZlbG9wbWVudCBtb2RlIGZvciBidWlsZGluZyB0aGUgcGx1Z2luXG4gICAqL1xuICBEZXZlbG9wbWVudCxcbiAgLyoqXG4gIFByb2R1Y3Rpb24gbW9kZSBmb3IgYnVpbGRpbmcgdGhlIHBsdWdpblxuICAgKi9cbiAgUHJvZHVjdGlvblxufVxuXG4vKipcbiAqIFRoZSBtb2R1bGVzIE9ic2lkaWFuIHN1cHBsaWVzIGF0IHJ1bnRpbWUuIEEgcGx1Z2luIG11c3QgbmV2ZXIgYnVuZGxlIGl0cyBvd24gY29weSBvZiB0aGVtOiBhIHNlY29uZCBjb3B5XG4gKiBvZiB0aGUgQVBJIGJyZWFrcyBgaW5zdGFuY2VvZmAgYWdhaW5zdCB0aGUgcnVubmluZyBvbmUsIGFuZCBhIHNlY29uZCBDb2RlTWlycm9yIGJyZWFrcyBldmVyeSBleHRlbnNpb24uXG4gKlxuICogYGVzYnVpbGRgIGFuZCBgZXNsaW50YCBhcmUgaGVyZSBiZWNhdXNlIGEgcGx1Z2luIHRoYXQgaW1wb3J0cyBvbmUgb2YgdGhlIHRvb2xraXQncyBidWlsZC10aW1lIG1vZHVsZXNcbiAqIHdvdWxkIG90aGVyd2lzZSBkcmFnIGVpdGhlciBpbnRvIGBtYWluLmpzYC5cbiAqL1xuZXhwb3J0IGNvbnN0IE9CU0lESUFOX1BMVUdJTl9SVU5USU1FX01PRFVMRVM6IHJlYWRvbmx5IHN0cmluZ1tdID0gW1xuICAnb2JzaWRpYW4nLFxuICAnZWxlY3Ryb24nLFxuICAnQGNvZGVtaXJyb3IvYXV0b2NvbXBsZXRlJyxcbiAgJ0Bjb2RlbWlycm9yL2NvbGxhYicsXG4gICdAY29kZW1pcnJvci9jb21tYW5kcycsXG4gICdAY29kZW1pcnJvci9sYW5ndWFnZScsXG4gICdAY29kZW1pcnJvci9saW50JyxcbiAgJ0Bjb2RlbWlycm9yL3NlYXJjaCcsXG4gICdAY29kZW1pcnJvci9zdGF0ZScsXG4gICdAY29kZW1pcnJvci92aWV3JyxcbiAgJ0BsZXplci9jb21tb24nLFxuICAnQGxlemVyL2hpZ2hsaWdodCcsXG4gICdAbGV6ZXIvbHInLFxuICAnZXNidWlsZCcsXG4gICdlc2xpbnQnXG5dO1xuXG4vKipcbiAqIFRoZSBtb2R1bGUgaWRzIGFuIE9ic2lkaWFuIHBsdWdpbiBidW5kbGUgbGVhdmVzIHRvIGByZXF1aXJlKClgIGF0IHJ1bnRpbWU6IHRoZVxuICoge0BsaW5rIE9CU0lESUFOX1BMVUdJTl9SVU5USU1FX01PRFVMRVN9IGFuZCB0aGUgTm9kZSBidWlsdGlucy4gRXZlcnkgYG5vZGU6YC1wcmVmaXhlZCBpZCBpcyBleHRlcm5hbCB0b28sXG4gKiB3aGljaCBhIGJ1bmRsZXIgdGFrZXMgYXMgYSBwYXR0ZXJuIChlc2J1aWxkJ3MgYG5vZGU6KmApIG9yIHRocm91Z2gge0BsaW5rIGlzT2JzaWRpYW5QbHVnaW5FeHRlcm5hbH0uXG4gKi9cbmV4cG9ydCBjb25zdCBPQlNJRElBTl9QTFVHSU5fRVhURVJOQUxTOiByZWFkb25seSBzdHJpbmdbXSA9IFtcbiAgLi4uT0JTSURJQU5fUExVR0lOX1JVTlRJTUVfTU9EVUxFUyxcbiAgLi4uYnVpbHRpbk1vZHVsZXNcbl07XG5cbmNvbnN0IE5PREVfUFJFRklYID0gJ25vZGU6JztcbmNvbnN0IFNUWUxFU19DU1NfRklMRV9OQU1FOiBzdHJpbmcgPSBPYnNpZGlhblBsdWdpblJlcG9QYXRocy5TdHlsZXNDc3M7XG5cbmNvbnN0IE9CU0lESUFOX1BMVUdJTl9FWFRFUk5BTFNfU0VUID0gbmV3IFNldChPQlNJRElBTl9QTFVHSU5fRVhURVJOQUxTKTtcblxuLyoqXG4gKiBBIENTUyBmaWxlIGEgYnVuZGxlciBlbWl0dGVkLCBhcyB7QGxpbmsgbWVyZ2VDc3NBc3NldHN9IHNlZXMgaXQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ3NzQXNzZXQge1xuICAvKipcbiAgICogVGhlIGZpbGUgbmFtZSByZWxhdGl2ZSB0byB0aGUgb3V0cHV0IGZvbGRlci5cbiAgICovXG4gIHJlYWRvbmx5IGZpbGVOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBmaWxlJ3MgY29udGVudHMuXG4gICAqL1xuICByZWFkb25seSBzb3VyY2U6IHN0cmluZztcbn1cblxuLyoqXG4gKiBXaGF0IHtAbGluayBtZXJnZUNzc0Fzc2V0c30gZGVjaWRlZC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNZXJnZUNzc0Fzc2V0c1Jlc3VsdCB7XG4gIC8qKlxuICAgKiBUaGUgZmlsZSBuYW1lcyB0byBkcm9wIGZyb20gdGhlIG91dHB1dCwgYmVjYXVzZSB0aGVpciBjb250ZW50cyBtb3ZlZCBpbnRvIGBzdHlsZXMuY3NzYC4gSW5jbHVkZXNcbiAgICogYHN0eWxlcy5jc3NgIGl0c2VsZiB3aGVuIHRoZSBidW5kbGVyIGFscmVhZHkgZW1pdHRlZCBvbmUsIHNvIGl0IGlzIGFsd2F5cyB3cml0dGVuIGFmcmVzaC5cbiAgICovXG4gIHJlYWRvbmx5IGZpbGVOYW1lc1RvUmVtb3ZlOiByZWFkb25seSBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIGNvbnRlbnRzIG9mIGBzdHlsZXMuY3NzYCwgb3IgYHVuZGVmaW5lZGAgd2hlbiB0aGVyZSBpcyBub3RoaW5nIHRvIGRvOiB0aGUgYnVuZGxlIGhhcyBubyBDU1MgYXQgYWxsLFxuICAgKiBvciBpdHMgb25lIENTUyBmaWxlIGFscmVhZHkgaXMgYHN0eWxlcy5jc3NgLlxuICAgKi9cbiAgcmVhZG9ubHkgc3R5bGVzQ3NzOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogV2hlcmUgYSBwbHVnaW4gYnVpbGQgd3JpdGVzIGl0cyBvdXRwdXQgYW5kIHdoYXQgaXQgYnVpbGRzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE9ic2lkaWFuUGx1Z2luQnVpbGRDb250ZXh0IHtcbiAgLyoqXG4gICAqIFRoZSBhYnNvbHV0ZSBwYXRoIG9mIHRoZSBmb2xkZXIgdGhlIGJ1aWxkIHdyaXRlcyBgbWFpbi5qc2AsIGBzdHlsZXMuY3NzYCBhbmQgYG1hbmlmZXN0Lmpzb25gIGludG8uXG4gICAqL1xuICByZWFkb25seSBkaXN0Rm9sZGVyOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBhYnNvbHV0ZSBwYXRoIG9mIHRoZSBwbHVnaW4ncyBlbnRyeSBwb2ludCwgYHNyYy9tYWluLnRzYC5cbiAgICovXG4gIHJlYWRvbmx5IGVudHJ5UG9pbnQ6IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciB0aGlzIGlzIGEgcHJvZHVjdGlvbiBidWlsZC5cbiAgICovXG4gIHJlYWRvbmx5IGlzUHJvZHVjdGlvbkJ1aWxkOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgYWJzb2x1dGUgcGF0aCBvZiB0aGUgZW1pdHRlZCBgbWFpbi5qc2AuXG4gICAqL1xuICByZWFkb25seSBtYWluSnNQYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBPYnNpZGlhbiBjb25maWd1cmF0aW9uIGZvbGRlciBhIGRldmVsb3BtZW50IGJ1aWxkIGlzIGRlcGxveWVkIGludG8sIG9yIGFuIGVtcHR5IHN0cmluZyB3aGVuIG5vbmVcbiAgICogaXMgY29uZmlndXJlZC5cbiAgICovXG4gIHJlYWRvbmx5IG9ic2lkaWFuQ29uZmlnRm9sZGVyOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwbHVnaW4ncyBmb2xkZXIgbmFtZSBpbnNpZGUgYDx2YXVsdD4vLm9ic2lkaWFuL3BsdWdpbnNgLCB3aGljaCBpcyB0aGUgcGFja2FnZSBuYW1lLlxuICAgKi9cbiAgcmVhZG9ubHkgcGx1Z2luTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBIb3cgYSBkZXZlbG9wbWVudCBidWlsZCBpcyByZWxvYWRlZCBpbiBPYnNpZGlhbiBvbmNlIGl0IGlzIGRlcGxveWVkLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVsb2FkOiBPYnNpZGlhblBsdWdpblJlbG9hZDtcbn1cblxuLyoqXG4gKiBXaGVyZSBhIGRldmVsb3BtZW50IGJ1aWxkIGlzIGRlcGxveWVkIGFuZCBob3cgT2JzaWRpYW4gcGlja3MgaXQgdXAuIEV2ZXJ5IGJ1bmRsZXIgYWRhcHRlciB0YWtlcyB0aGVzZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPYnNpZGlhblBsdWdpbkRlcGxveW1lbnRPcHRpb25zIHtcbiAgLyoqXG4gICAqIEEgZm9sZGVyIGZvciBPYnNpZGlhbiBjb25maWd1cmF0aW9uLiBEZWZhdWx0cyB0byB0aGUgYE9CU0lESUFOX0NPTkZJR19GT0xERVJgIGVudmlyb25tZW50IHZhcmlhYmxlLFxuICAgKiByZWFkIGZyb20gdGhlIHByb2Nlc3Mgb3IgZnJvbSBhIGAuZW52YCBmaWxlIGluIHRoZSBwcm9qZWN0IHJvb3QuXG4gICAqL1xuICByZWFkb25seSBvYnNpZGlhbkNvbmZpZ0ZvbGRlcj86IHN0cmluZztcblxuICAvKipcbiAgICogSG93IGEgZGV2ZWxvcG1lbnQgYnVpbGQgaXMgcmVsb2FkZWQgaW4gT2JzaWRpYW4gb25jZSBpdCBpcyBjb3BpZWQgaW50byB0aGUgdmF1bHQuIERlZmF1bHRzIHRvXG4gICAqIGAnaG90LXJlbG9hZC1wbHVnaW4nYC5cbiAgICovXG4gIHJlYWRvbmx5IHJlbG9hZD86IE9ic2lkaWFuUGx1Z2luUmVsb2FkO1xufVxuXG4vKipcbiAqIEhvdyBhIGRldmVsb3BtZW50IGJ1aWxkIGlzIHJlbG9hZGVkIGluIE9ic2lkaWFuIG9uY2UgaXQgaXMgY29waWVkIGludG8gdGhlIHZhdWx0LlxuICpcbiAqIC0gYCdob3QtcmVsb2FkLXBsdWdpbidgOiB0aGUgYnVpbGQgd3JpdGVzIHRoZSBgLmhvdHJlbG9hZGAgbWFya2VyLCBhbmQgYG5wbSBydW4gZGV2YCBvcGVucyB0aGUgdmF1bHQgaW4gYW5cbiAqICAgT2JzaWRpYW4gaW5zdGFuY2UgaXQgb3ducywgd2l0aCB0aGUgSG90UmVsb2FkIHBsdWdpbiBpbnN0YWxsZWQgYW5kIGVuYWJsZWQgdGhlcmUuXG4gKiAtIGAnb2JzaWRpYW4tY2xpJ2A6IGV2ZXJ5IHJlYnVpbGQgcnVucyBgb2JzaWRpYW4gcGx1Z2luOnJlbG9hZGAgYWdhaW5zdCB0aGUgT2JzaWRpYW4geW91IGFscmVhZHkgaGF2ZSBvcGVuLFxuICogICB0aHJvdWdoIHRoZSBPYnNpZGlhbiBDTEkgKFNldHRpbmdzIOKGkiBHZW5lcmFsIOKGkiBDb21tYW5kIGxpbmUgaW50ZXJmYWNlKS4gTm8gSG90UmVsb2FkLCBubyBzZWNvbmQgaW5zdGFuY2UuXG4gKiAtIGBmYWxzZWA6IHRoZSBidWlsZCBpcyBjb3BpZWQgaW50byB0aGUgdmF1bHQgYW5kIG5vdGhpbmcgcmVsb2FkcyBpdC5cbiAqL1xuZXhwb3J0IHR5cGUgT2JzaWRpYW5QbHVnaW5SZWxvYWQgPSAnaG90LXJlbG9hZC1wbHVnaW4nIHwgJ29ic2lkaWFuLWNsaScgfCBmYWxzZTtcblxuLyoqXG4gKiBPcHRpb25zIGZvciB7QGxpbmsgcmVzb2x2ZU9ic2lkaWFuUGx1Z2luQnVpbGRDb250ZXh0fS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlT2JzaWRpYW5QbHVnaW5CdWlsZENvbnRleHRQYXJhbXMgZXh0ZW5kcyBPYnNpZGlhblBsdWdpbkRlcGxveW1lbnRPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBvdXRwdXQgZm9sZGVyLiBEZWZhdWx0cyB0byBgZGlzdC9idWlsZGAgZm9yIGEgcHJvZHVjdGlvbiBidWlsZCBhbmQgYGRpc3QvZGV2YCBmb3IgYSBkZXZlbG9wbWVudFxuICAgKiBvbmUuXG4gICAqL1xuICByZWFkb25seSBkaXN0Rm9sZGVyPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgYnVpbGQgbW9kZS5cbiAgICovXG4gIHJlYWRvbmx5IG1vZGU6IEJ1aWxkTW9kZTtcbn1cblxuaW50ZXJmYWNlIE9ic2lkaWFuUGx1Z2luQnVpbGRlckVudiB7XG4gIE9CU0lESUFOX0NPTkZJR19GT0xERVI6IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZW1vdmVzIHRoZSBvdXRwdXQgZm9sZGVyIG9mIGEgYnVpbGQgYW5kIGNyZWF0ZXMgaXQgZW1wdHkgYWdhaW4uXG4gKlxuICogQHBhcmFtIGRpc3RGb2xkZXIgLSBUaGUgb3V0cHV0IGZvbGRlci5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUgZm9sZGVyIGV4aXN0cyBhbmQgaXMgZW1wdHkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbGVhbk9ic2lkaWFuUGx1Z2luRGlzdEZvbGRlcihkaXN0Rm9sZGVyOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKGV4aXN0c1N5bmMoZGlzdEZvbGRlcikpIHtcbiAgICBhd2FpdCBybShkaXN0Rm9sZGVyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgfVxuICBhd2FpdCBta2RpcihkaXN0Rm9sZGVyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbn1cblxuLyoqXG4gKiBQdXRzIHRoZSBmaWxlcyBhIHBsdWdpbiBmb2xkZXIgbmVlZHMgYmVzaWRlcyB0aGUgYnVuZGxlIGludG8gdGhlIG91dHB1dCBmb2xkZXI6IGBtYW5pZmVzdC5qc29uYCwgYW5kIGZvclxuICogYSBkZXZlbG9wbWVudCBidWlsZCByZWxvYWRlZCBieSB0aGUgSG90UmVsb2FkIHBsdWdpbiB0aGUgZW1wdHkgYC5ob3RyZWxvYWRgIG1hcmtlciBpdCB3YXRjaGVzIGZvci5cbiAqXG4gKiBAcGFyYW0gY29udGV4dCAtIFRoZSBidWlsZCBjb250ZXh0LlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBmaWxlcyBhcmUgd3JpdHRlbi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvbXBsZXRlT2JzaWRpYW5QbHVnaW5EaXN0Rm9sZGVyKGNvbnRleHQ6IE9ic2lkaWFuUGx1Z2luQnVpbGRDb250ZXh0KTogUHJvbWlzZTx2b2lkPiB7XG4gIGF3YWl0IG1rZGlyKGNvbnRleHQuZGlzdEZvbGRlciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIGlmICghY29udGV4dC5pc1Byb2R1Y3Rpb25CdWlsZCAmJiBjb250ZXh0LnJlbG9hZCA9PT0gJ2hvdC1yZWxvYWQtcGx1Z2luJykge1xuICAgIGF3YWl0IHdyaXRlRmlsZShqb2luKGNvbnRleHQuZGlzdEZvbGRlciwgT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuSG90UmVsb2FkKSwgJycsICd1dGYtOCcpO1xuICB9XG5cbiAgY29uc3QgbWFuaWZlc3RQYXRoID0gcmVzb2x2ZVBhdGhGcm9tUm9vdCh7IHBhdGg6IE9ic2lkaWFuUGx1Z2luUmVwb1BhdGhzLk1hbmlmZXN0SnNvbiB9KTtcbiAgaWYgKG1hbmlmZXN0UGF0aCAmJiBleGlzdHNTeW5jKG1hbmlmZXN0UGF0aCkpIHtcbiAgICBhd2FpdCBjcChtYW5pZmVzdFBhdGgsIGpvaW4oY29udGV4dC5kaXN0Rm9sZGVyLCBPYnNpZGlhblBsdWdpblJlcG9QYXRocy5NYW5pZmVzdEpzb24pKTtcbiAgfVxufVxuXG4vKipcbiAqIEJ1aWxkcyB0aGUgYmFubmVyIHBsYWNlZCBhdCB0aGUgdG9wIG9mIGBtYWluLmpzYC5cbiAqXG4gKiBAcGFyYW0gYnVuZGxlck5hbWUgLSBUaGUgYnVuZGxlcidzIG5hbWUsIGFzIHRoZSBiYW5uZXIgc3RhdGVzIGl0LlxuICogQHJldHVybnMgVGhlIGJhbm5lciwgYSBibG9jayBjb21tZW50IGZvbGxvd2VkIGJ5IGEgbmV3bGluZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE9ic2lkaWFuUGx1Z2luQmFubmVyKGJ1bmRsZXJOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYC8qXG5USElTIElTIEEgR0VORVJBVEVEL0JVTkRMRUQgRklMRSBCWSAke2J1bmRsZXJOYW1lLnRvVXBwZXJDYXNlKCl9XG5pZiB5b3Ugd2FudCB0byB2aWV3IHRoZSBzb3VyY2UsIHBsZWFzZSB2aXNpdCB0aGUgZ2l0aHViIHJlcG9zaXRvcnkgb2YgdGhpcyBwbHVnaW5cbiovXG5gO1xufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBkZWZhdWx0IG91dHB1dCBmb2xkZXIgb2YgYSBidWlsZDogYGRpc3QvYnVpbGRgIGZvciBhIHByb2R1Y3Rpb24gYnVpbGQsIGBkaXN0L2RldmAgZm9yIGFcbiAqIGRldmVsb3BtZW50IG9uZS5cbiAqXG4gKiBAcGFyYW0gbW9kZSAtIFRoZSBidWlsZCBtb2RlLlxuICogQHJldHVybnMgVGhlIGFic29sdXRlIHBhdGggb2YgdGhlIG91dHB1dCBmb2xkZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRPYnNpZGlhblBsdWdpbkRpc3RGb2xkZXIobW9kZTogQnVpbGRNb2RlKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJlc29sdmVGcm9tUm9vdChtb2RlID09PSBCdWlsZE1vZGUuUHJvZHVjdGlvbiA/IE9ic2lkaWFuUGx1Z2luUmVwb1BhdGhzLkRpc3RCdWlsZCA6IE9ic2lkaWFuUGx1Z2luUmVwb1BhdGhzLkRpc3REZXYpO1xufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBwbHVnaW4ncyBlbnRyeSBwb2ludCwgYHNyYy9tYWluLnRzYC5cbiAqXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCBvZiB0aGUgZW50cnkgcG9pbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRPYnNpZGlhblBsdWdpbkVudHJ5UG9pbnQoKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJlc29sdmVGcm9tUm9vdChqb2luKE9ic2lkaWFuUGx1Z2luUmVwb1BhdGhzLlNyYywgT2JzaWRpYW5QbHVnaW5SZXBvUGF0aHMuTWFpblRzKSk7XG59XG5cbi8qKlxuICogVGVsbHMgd2hldGhlciBhIGZpbGUgbmFtZSBpcyBhIENTUyBmaWxlLlxuICpcbiAqIEBwYXJhbSBmaWxlTmFtZSAtIFRoZSBmaWxlIG5hbWUuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgZm9yIGEgYC5jc3NgIGZpbGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Nzc0ZpbGVOYW1lKGZpbGVOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGJhc2VuYW1lKGZpbGVOYW1lKS50b0xvd2VyQ2FzZSgpLmVuZHNXaXRoKCcuY3NzJyk7XG59XG5cbi8qKlxuICogVGVsbHMgd2hldGhlciBhIG1vZHVsZSBpZCBpcyBvbmUgYW4gT2JzaWRpYW4gcGx1Z2luIGJ1bmRsZSBtdXN0IGxlYXZlIGV4dGVybmFsOiBvbmUgb2ZcbiAqIHtAbGluayBPQlNJRElBTl9QTFVHSU5fRVhURVJOQUxTfSwgYSBzdWJwYXRoIG9mIG9uZSAoYEBjb2RlbWlycm9yL3ZpZXcvZGlzdC9pbmRleC5qc2AsIGBmcy9wcm9taXNlc2ApLFxuICogb3IgYW55IGBub2RlOmAtcHJlZml4ZWQgaWQuXG4gKlxuICogQHBhcmFtIG1vZHVsZUlkIC0gVGhlIG1vZHVsZSBpZCBhcyB3cml0dGVuIGluIHRoZSBpbXBvcnRpbmcgZmlsZS5cbiAqIEByZXR1cm5zIGB0cnVlYCB3aGVuIHRoZSBidW5kbGUgbXVzdCBsZWF2ZSB0aGUgbW9kdWxlIHRvIGByZXF1aXJlKClgIGF0IHJ1bnRpbWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc09ic2lkaWFuUGx1Z2luRXh0ZXJuYWwobW9kdWxlSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBpZiAobW9kdWxlSWQuc3RhcnRzV2l0aChOT0RFX1BSRUZJWCkgfHwgT0JTSURJQU5fUExVR0lOX0VYVEVSTkFMU19TRVQuaGFzKG1vZHVsZUlkKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgY29uc3QgU0NPUEVEX1BBQ0tBR0VfU0VHTUVOVF9DT1VOVCA9IDI7XG4gIGNvbnN0IHBhY2thZ2VOYW1lID0gbW9kdWxlSWQuc3BsaXQoJy8nKS5zbGljZSgwLCBtb2R1bGVJZC5zdGFydHNXaXRoKCdAJykgPyBTQ09QRURfUEFDS0FHRV9TRUdNRU5UX0NPVU5UIDogMSkuam9pbignLycpO1xuICByZXR1cm4gcGFja2FnZU5hbWUgIT09IG1vZHVsZUlkICYmIE9CU0lESUFOX1BMVUdJTl9FWFRFUk5BTFNfU0VULmhhcyhwYWNrYWdlTmFtZSk7XG59XG5cbi8qKlxuICogRGVjaWRlcyBob3cgdGhlIENTUyBhIGJ1bmRsZXIgZW1pdHRlZCBiZWNvbWVzIHRoZSBvbmUgYHN0eWxlcy5jc3NgIE9ic2lkaWFuIGxvYWRzLlxuICpcbiAqIE9ic2lkaWFuIHJlYWRzIGEgcGx1Z2luJ3Mgc3R5bGVzaGVldCBmcm9tIGBzdHlsZXMuY3NzYCBhbmQgbm90aGluZyBlbHNlLCB3aGlsZSBhIGJ1bmRsZXIgbmFtZXMgdGhlIENTU1xuICogYWZ0ZXIgdGhlIGVudHJ5IChgbWFpbi5jc3NgKSwgYWZ0ZXIgdGhlIHBhY2thZ2UsIG9yIHdpdGggYSBjb250ZW50IGhhc2guIEEgbG9uZSBDU1MgZmlsZSBpcyByZW5hbWVkOyB3aGVuXG4gKiB0aGVyZSBhcmUgc2V2ZXJhbCwgdGhleSBhcmUgY29uY2F0ZW5hdGVkIGluIHRoZSBvcmRlciBnaXZlbi5cbiAqXG4gKiBAcGFyYW0gY3NzQXNzZXRzIC0gVGhlIENTUyBmaWxlcyB0aGUgYnVuZGxlciBlbWl0dGVkLCBpbiBvdXRwdXQgb3JkZXIuXG4gKiBAcmV0dXJucyBXaGF0IHRvIHdyaXRlIGFzIGBzdHlsZXMuY3NzYCBhbmQgd2hpY2ggZW1pdHRlZCBmaWxlcyB0byBkcm9wLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VDc3NBc3NldHMoY3NzQXNzZXRzOiByZWFkb25seSBDc3NBc3NldFtdKTogTWVyZ2VDc3NBc3NldHNSZXN1bHQge1xuICBjb25zdCBbZmlyc3RDc3NBc3NldF0gPSBjc3NBc3NldHM7XG4gIGlmIChmaXJzdENzc0Fzc2V0ID09PSB1bmRlZmluZWQgfHwgKGNzc0Fzc2V0cy5sZW5ndGggPT09IDEgJiYgZmlyc3RDc3NBc3NldC5maWxlTmFtZSA9PT0gU1RZTEVTX0NTU19GSUxFX05BTUUpKSB7XG4gICAgcmV0dXJuIHsgZmlsZU5hbWVzVG9SZW1vdmU6IFtdLCBzdHlsZXNDc3M6IHVuZGVmaW5lZCB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBmaWxlTmFtZXNUb1JlbW92ZTogY3NzQXNzZXRzLm1hcCgoYXNzZXQpID0+IGFzc2V0LmZpbGVOYW1lKSxcbiAgICBzdHlsZXNDc3M6IGNzc0Fzc2V0cy5tYXAoKGFzc2V0KSA9PiBhc3NldC5zb3VyY2UpLmpvaW4oJ1xcbicpXG4gIH07XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgYSBwYXRoIGFnYWluc3QgdGhlIHByb2plY3Qgcm9vdC5cbiAqXG4gKiBAcGFyYW0gcGF0aCAtIFRoZSBwYXRoLCByZWxhdGl2ZSB0byB0aGUgcHJvamVjdCByb290IG9yIGFic29sdXRlLlxuICogQHJldHVybnMgVGhlIGFic29sdXRlIHBhdGguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlRnJvbVJvb3QocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGVuc3VyZU5vbk51bGxhYmxlKHJlc29sdmVQYXRoRnJvbVJvb3QoeyBwYXRoIH0pLCBgQ291bGQgbm90IHJlc29sdmUgJyR7cGF0aH0nIGFnYWluc3QgdGhlIHByb2plY3Qgcm9vdGApO1xufVxuXG4vKipcbiAqIFJlc29sdmVzIHdoZXJlIGEgcGx1Z2luIGJ1aWxkIHdyaXRlcyBpdHMgb3V0cHV0LCB3aGljaCBlbnRyeSBwb2ludCBpdCBidWlsZHMgYW5kIHdoaWNoIHZhdWx0IGFcbiAqIGRldmVsb3BtZW50IGJ1aWxkIGlzIGRlcGxveWVkIGludG8uXG4gKlxuICogTG9hZHMgdGhlIHByb2plY3QncyBgLmVudmAgZmlsZSBmaXJzdCwgc28gYE9CU0lESUFOX0NPTkZJR19GT0xERVJgIGNhbiBsaXZlIHRoZXJlLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUge0BsaW5rIFJlc29sdmVPYnNpZGlhblBsdWdpbkJ1aWxkQ29udGV4dFBhcmFtc30uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHRvIHRoZSB7QGxpbmsgT2JzaWRpYW5QbHVnaW5CdWlsZENvbnRleHR9LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZU9ic2lkaWFuUGx1Z2luQnVpbGRDb250ZXh0KHBhcmFtczogUmVzb2x2ZU9ic2lkaWFuUGx1Z2luQnVpbGRDb250ZXh0UGFyYW1zKTogUHJvbWlzZTxPYnNpZGlhblBsdWdpbkJ1aWxkQ29udGV4dD4ge1xuICBjb25zdCBlbnZQYXRoID0gcmVzb2x2ZVBhdGhGcm9tUm9vdCh7IHBhdGg6ICcuZW52JyB9KTtcbiAgaWYgKGVudlBhdGggJiYgZXhpc3RzU3luYyhlbnZQYXRoKSkge1xuICAgIGxvYWRFbnZGaWxlKGVudlBhdGgpO1xuICB9XG4gIGNvbnN0IG9ic2lkaWFuUGx1Z2luQnVpbGRlckVudiA9IHByb2Nlc3MuZW52IGFzIFBhcnRpYWw8T2JzaWRpYW5QbHVnaW5CdWlsZGVyRW52PjtcblxuICBjb25zdCBpc1Byb2R1Y3Rpb25CdWlsZCA9IHBhcmFtcy5tb2RlID09PSBCdWlsZE1vZGUuUHJvZHVjdGlvbjtcbiAgY29uc3QgZGlzdEZvbGRlciA9IHBhcmFtcy5kaXN0Rm9sZGVyID09PSB1bmRlZmluZWQgPyBnZXRPYnNpZGlhblBsdWdpbkRpc3RGb2xkZXIocGFyYW1zLm1vZGUpIDogcmVzb2x2ZUZyb21Sb290KHBhcmFtcy5kaXN0Rm9sZGVyKTtcbiAgY29uc3QgcGFja2FnZUpzb24gPSBhd2FpdCByZWFkUGFja2FnZUpzb24oKTtcblxuICByZXR1cm4ge1xuICAgIGRpc3RGb2xkZXIsXG4gICAgZW50cnlQb2ludDogZ2V0T2JzaWRpYW5QbHVnaW5FbnRyeVBvaW50KCksXG4gICAgaXNQcm9kdWN0aW9uQnVpbGQsXG4gICAgbWFpbkpzUGF0aDogam9pbihkaXN0Rm9sZGVyLCBPYnNpZGlhblBsdWdpblJlcG9QYXRocy5NYWluSnMpLFxuICAgIG9ic2lkaWFuQ29uZmlnRm9sZGVyOiBwYXJhbXMub2JzaWRpYW5Db25maWdGb2xkZXIgPz8gb2JzaWRpYW5QbHVnaW5CdWlsZGVyRW52Lk9CU0lESUFOX0NPTkZJR19GT0xERVIgPz8gJycsXG4gICAgcGx1Z2luTmFtZTogcGFja2FnZUpzb24ubmFtZSA/PyAnKHVua25vd24pJyxcbiAgICByZWxvYWQ6IHBhcmFtcy5yZWxvYWQgPz8gJ2hvdC1yZWxvYWQtcGx1Z2luJ1xuICB9O1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVNBLFNBQVMsdUJBQXVCO0FBQ2hDLFNBQVMsMkJBQTJCO0FBQ3BDO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1AsU0FBUyx5QkFBeUI7QUFDbEMsU0FBUyxrQkFBa0I7QUFDM0I7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMsc0JBQXNCO0FBQy9CLE9BQU8sV0FBVyxtQkFBbUI7QUFFckMsU0FBUywrQkFBK0I7QUFLakMsSUFBSyxZQUFMLGtCQUFLQSxlQUFMO0FBSUwsRUFBQUEsc0JBQUE7QUFJQSxFQUFBQSxzQkFBQTtBQVJVLFNBQUFBO0FBQUEsR0FBQTtBQWtCTCxNQUFNLGtDQUFxRDtBQUFBLEVBQ2hFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFDRjtBQU9PLE1BQU0sNEJBQStDO0FBQUEsRUFDMUQsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUNMO0FBRUEsTUFBTSxjQUFjO0FBQ3BCLE1BQU0sdUJBQStCLHdCQUF3QjtBQUU3RCxNQUFNLGdDQUFnQyxJQUFJLElBQUkseUJBQXlCO0FBaUl2RSxlQUFzQiw4QkFBOEIsWUFBbUM7QUFD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
@@ -0,0 +1,186 @@
1
+ /// <reference path="../library-references.d.mts" />
2
+ /**
3
+ * @file
4
+ *
5
+ * The build features every bundler adapter offers beside the plain plugin build: a UI framework, the stylesheet
6
+ * pipeline and WebAssembly. Every adapter takes the same {@link ObsidianPluginFeatureOptions}, so a project that
7
+ * switches bundler keeps its options and its installed packages.
8
+ *
9
+ * Each feature's packages are optional peer dependencies of the toolkit, imported from the PROJECT's own
10
+ * `node_modules` only when the feature is on, through {@link importOptionalPeer}.
11
+ *
12
+ * Erasable TypeScript only (no enums, no parameter properties): `obsidian-plugin-transforms.ts` imports this module,
13
+ * and a webpack loader or a parcel worker loads that one straight from source when the toolkit runs from source.
14
+ */
15
+ /**
16
+ * Which shared transform a module goes through, as {@link getFeatureFileKind} tells it.
17
+ */
18
+ export type FeatureFileKind = 'jsx' | 'stylesheet' | 'svelte' | 'wasm';
19
+ /**
20
+ * Parameters for {@link getFrameworkDefines}.
21
+ */
22
+ export interface GetFrameworkDefinesParams {
23
+ /**
24
+ * The UI framework, if any.
25
+ */
26
+ readonly framework: ObsidianPluginFramework | undefined;
27
+ /**
28
+ * Whether this is a production build.
29
+ */
30
+ readonly isProductionBuild: boolean;
31
+ }
32
+ /**
33
+ * Parameters for {@link importOptionalPeer}.
34
+ */
35
+ export interface ImportOptionalPeerParams {
36
+ /**
37
+ * The option that needs the package, as the error message names it, e.g. `framework: 'solid'`.
38
+ */
39
+ readonly feature: string;
40
+ /**
41
+ * The package to install when it is missing.
42
+ */
43
+ readonly packageName: string;
44
+ /**
45
+ * The folder whose `node_modules` the package is resolved from. Defaults to the project root.
46
+ */
47
+ readonly projectFolder?: string;
48
+ /**
49
+ * The module to import. Defaults to {@link packageName}.
50
+ */
51
+ readonly specifier?: string;
52
+ }
53
+ /**
54
+ * The build features beside the plain plugin build. Every option is off unless set.
55
+ */
56
+ export interface ObsidianPluginFeatureOptions {
57
+ /**
58
+ * The UI framework whose components the build compiles.
59
+ */
60
+ readonly framework?: ObsidianPluginFramework;
61
+ /**
62
+ * The stylesheet pipeline.
63
+ */
64
+ readonly styles?: ObsidianPluginStylesOptions;
65
+ /**
66
+ * Whether `import bytes from './module.wasm'` imports the module's bytes as a `Uint8Array`, inlined into `main.js`.
67
+ */
68
+ readonly wasm?: boolean;
69
+ }
70
+ /**
71
+ * A UI framework the bundler adapters compile.
72
+ *
73
+ * - `react` and `preact` compile JSX with the automatic runtime from `react` / `preact`.
74
+ * - `solid` compiles JSX with `babel-preset-solid`.
75
+ * - `svelte` compiles `.svelte` components and `.svelte.ts` / `.svelte.js` modules with the project's `svelte`.
76
+ * - `vue` compiles single-file components with `unplugin-vue` (on parcel, with `@parcel/transformer-vue`).
77
+ */
78
+ export type ObsidianPluginFramework = 'preact' | 'react' | 'solid' | 'svelte' | 'vue';
79
+ /**
80
+ * The stylesheet pipeline of {@link ObsidianPluginFeatureOptions}.
81
+ */
82
+ export interface ObsidianPluginStylesOptions {
83
+ /**
84
+ * Whether a `*.module.css` file is a CSS module: its class names are scoped, and importing it gives the scoped
85
+ * names by their original ones.
86
+ */
87
+ readonly cssModules?: boolean;
88
+ /**
89
+ * Whether every stylesheet goes through the project's PostCSS configuration (`postcss.config.*`, `.postcssrc*`, or
90
+ * `postcss` in `package.json`).
91
+ */
92
+ readonly postcss?: boolean;
93
+ /**
94
+ * Whether every stylesheet goes through Tailwind CSS 4 (`@tailwindcss/postcss`), so `@import "tailwindcss";`
95
+ * expands to the utilities the sources use.
96
+ */
97
+ readonly tailwind?: boolean;
98
+ }
99
+ /**
100
+ * Parameters for {@link requireOptionalPeer}: the same as {@link ImportOptionalPeerParams}.
101
+ */
102
+ export type RequireOptionalPeerParams = ImportOptionalPeerParams;
103
+ /**
104
+ * Parameters for {@link resolveOptionalPeer}: the same as {@link ImportOptionalPeerParams}.
105
+ */
106
+ export type ResolveOptionalPeerParams = ImportOptionalPeerParams;
107
+ /**
108
+ * Tells which shared transform a module of a rollup-family build goes through, by its id.
109
+ *
110
+ * A virtual module (an id starting with `\0`) goes through none. A query is part of the match for a stylesheet, so a
111
+ * Vue component's `?vue&type=style&lang.css` block counts as one, and is cut off for the rest.
112
+ *
113
+ * @param id - The module id.
114
+ * @returns The kind of file, or `undefined` for a module no feature transforms.
115
+ */
116
+ export declare function getFeatureFileKind(id: string): FeatureFileKind | undefined;
117
+ /**
118
+ * Builds the compile-time constants a framework's runtime reads, which Obsidian's renderer does not define.
119
+ *
120
+ * `process.env.NODE_ENV` picks a runtime's production build (React, Preact's devtools, Vue, Solid), and without it a
121
+ * production plugin would bundle and run the development one. Vue also reads its three feature flags.
122
+ *
123
+ * @param params - The {@link GetFrameworkDefinesParams}.
124
+ * @returns The constants, by expression, each value a JavaScript literal. Empty when there is no framework.
125
+ */
126
+ export declare function getFrameworkDefines(params: GetFrameworkDefinesParams): Record<string, string>;
127
+ /**
128
+ * Tells which package supplies the automatic JSX runtime of a framework.
129
+ *
130
+ * @param framework - The UI framework, if any.
131
+ * @returns `react` or `preact`, or `undefined` for a framework that does not compile JSX with the automatic runtime.
132
+ */
133
+ export declare function getJsxImportSource(framework: ObsidianPluginFramework | undefined): 'preact' | 'react' | undefined;
134
+ /**
135
+ * Imports an optional peer dependency from the project's own `node_modules`.
136
+ *
137
+ * Resolved from the project rather than from the toolkit, so a package manager that does not hoist still finds what
138
+ * the project installed.
139
+ *
140
+ * @typeParam Module - The module's type.
141
+ * @param params - The {@link ImportOptionalPeerParams}.
142
+ * @returns A {@link Promise} that resolves to the module namespace.
143
+ * @throws If the project does not have the package, naming the option that needs it and the command that installs it.
144
+ */
145
+ export declare function importOptionalPeer<Module>(params: ImportOptionalPeerParams): Promise<Module>;
146
+ /**
147
+ * Tells whether a stylesheet is a CSS module by its file name.
148
+ *
149
+ * @param filePath - The stylesheet's path.
150
+ * @returns `true` for `*.module.css` (and `.module.pcss`, `.module.scss`, `.module.sass`).
151
+ */
152
+ export declare function isCssModuleFile(filePath: string): boolean;
153
+ /**
154
+ * Tells whether a stylesheet goes through PostCSS at all.
155
+ *
156
+ * @param styles - The stylesheet options, if any.
157
+ * @returns `true` when the project's PostCSS configuration or Tailwind applies.
158
+ */
159
+ export declare function isPostcssNeeded(styles: ObsidianPluginStylesOptions | undefined): boolean;
160
+ /**
161
+ * Replaces each compile-time constant in a module's code with its value, as a bundler's `define` does: only where
162
+ * the whole expression stands on its own, so `process.env.NODE_ENV` is replaced and `a.process.env.NODE_ENV` or
163
+ * `process.env.NODE_ENV_X` are not.
164
+ *
165
+ * @param code - The module's code.
166
+ * @param defines - The constants, by expression, each value a JavaScript literal.
167
+ * @returns The code with the constants replaced.
168
+ */
169
+ export declare function replaceDefines(code: string, defines: Readonly<Record<string, string>>): string;
170
+ /**
171
+ * Loads an optional peer dependency from the project's own `node_modules` synchronously, for a bundler whose plugins
172
+ * are applied synchronously (webpack). Loads an ES module too, through `require`.
173
+ *
174
+ * @param params - The {@link RequireOptionalPeerParams}.
175
+ * @returns The module, for the caller to type.
176
+ * @throws If the project does not have the package, naming the option that needs it and the command that installs it.
177
+ */
178
+ export declare function requireOptionalPeer(params: RequireOptionalPeerParams): unknown;
179
+ /**
180
+ * Resolves an optional peer dependency from the project's own `node_modules`.
181
+ *
182
+ * @param params - The {@link ResolveOptionalPeerParams}.
183
+ * @returns The absolute path of the module.
184
+ * @throws If the project does not have the package, naming the option that needs it and the command that installs it.
185
+ */
186
+ export declare function resolveOptionalPeer(params: ResolveOptionalPeerParams): string;