@mnaoumov/create-obsidian-plugin 1.0.1 → 1.1.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.
- package/README.md +38 -7
- package/dist/main.js +1068 -333
- package/package.json +15 -6
- package/src/main.ts +118 -11
- package/templates/default/.github/ISSUE_TEMPLATE/config.yml.ejs +4 -0
- package/templates/default/.github/workflows/attest-release-assets.yml.ejs +1 -11
- package/templates/default/.github/workflows/ci.yml_framework.ejs +19 -0
- package/templates/default/.github/workflows/ci.yml_framework@job-permissions_measured-coverage-badge.ejs +3 -0
- package/templates/default/.github/workflows/ci.yml_framework@with_measured-coverage-badge.ejs +1 -0
- package/templates/default/.github/workflows/{ci.yml.ejs → ci.yml_standalone.ejs} +1 -1
- package/templates/default/.github/workflows/release.yml_framework.ejs +19 -0
- package/templates/default/.github/workflows/{release.yml.ejs → release.yml_standalone.ejs} +1 -1
- package/templates/default/.gitignore_common.ejs +1 -0
- package/templates/default/.gitignore_wdio-obsidian.ejs +2 -0
- package/templates/default/.nvmrc.ejs +1 -0
- package/templates/default/.prettierignore.ejs +1 -0
- package/templates/default/.prettierignore@ignores_docs-showcase.ejs +3 -0
- package/templates/default/{CONTRIBUTING.md@demo-vault_dev-utils.ejs → CONTRIBUTING.md@demo-vault_framework.ejs} +1 -1
- package/templates/default/{README.md@demo-vault_dev-utils.ejs → README.md@demo-vault_framework.ejs} +1 -1
- package/templates/default/README.md@preset_docs-showcase.ejs +4 -0
- package/templates/default/{README.md@preset_dev-utils.ejs → README.md@preset_framework.ejs} +1 -1
- package/templates/default/biome.jsonc_framework.ejs +16 -0
- package/templates/default/biome.jsonc_framework@excludes_docs-showcase.ejs +1 -0
- package/templates/default/{biome.jsonc.ejs → biome.jsonc_standalone.ejs} +1 -1
- package/templates/default/cspell.json.ejs +10 -2
- package/templates/default/cspell.json@ignore-paths_docs-showcase.ejs +1 -0
- package/templates/default/demo-vault/.gitignore.ejs +4 -4
- package/templates/default/demo-vault/00 Start.md.ejs +1 -1
- package/templates/default/demo-vault/01 Sample commands.md.ejs +4 -4
- package/templates/default/demo-vault/02 Settings.md.ejs +2 -2
- package/templates/default/demo-vault/03 WebAssembly.md.ejs +2 -2
- package/templates/default/demo-vault/README.md.ejs +1 -1
- package/templates/default/demo-vault/_assets/CodeScriptToolkit/demoSetup.ts.ejs +1 -1
- package/templates/default/demo-vault/_assets/CodeScriptToolkit/startup.ts.ejs +4 -4
- package/templates/default/dprint.json_framework.ejs +10 -0
- package/templates/default/dprint.json_framework@excludes_docs-showcase.ejs +2 -0
- package/templates/default/dprint.json_standalone.ejs +1 -0
- package/templates/default/eslint.config.mts_standalone.ejs +9 -0
- package/templates/default/jest.config.ts_framework.ejs +31 -0
- package/templates/default/{scripts/rollup.config.ts@lint-out-dir_dev-utils.ejs → jest.config.ts_framework@lint-root-dir_framework.ejs} +1 -1
- package/templates/default/jest.config.ts_framework@ts-jest-tsconfig_solid.ejs +8 -0
- package/templates/default/{jest.config.ts.ejs → jest.config.ts_standalone.ejs} +0 -1
- package/templates/default/package.json@targets_parcel-targets.ejs +31 -0
- package/templates/default/package.json@targets_parcel.ejs +2 -33
- package/templates/default/parcel-transformer-inline-imports.cjs.ejs +1 -1
- package/templates/default/prettier.config.mjs_framework.ejs +3 -0
- package/templates/default/scripts/build-clean.ts.ejs +2 -2
- package/templates/default/scripts/build-compile-typescript.ts.ejs +14 -0
- package/templates/default/scripts/build-compile.ts.ejs +2 -2
- package/templates/default/scripts/build-options.ts.ejs +9 -0
- package/templates/default/scripts/build-styles.ts.ejs +4 -7
- package/templates/default/scripts/build.ts.ejs +2 -2
- package/templates/default/scripts/build.ts@bundler_adapter-cli.ejs +11 -0
- package/templates/default/scripts/build.ts@bundler_adapter-cli@run_rollup.ejs +1 -0
- package/templates/default/scripts/build.ts@bundler_adapter-cli@run_vite.ejs +1 -0
- package/templates/default/scripts/build.ts@bundler_adapter-cli@run_webpack.ejs +1 -0
- package/templates/default/scripts/build.ts@bundler_cli-bundler.ejs +1 -1
- package/templates/default/scripts/build.ts@bundler_cli-bundler@import_tailwind.ejs +0 -1
- package/templates/default/scripts/build.ts@bundler_esbuild.ejs +2 -2
- package/templates/default/scripts/build.ts@bundler_esbuild@preset_framework.ejs +5 -0
- package/templates/default/scripts/build.ts@bundler_parcel-adapter.ejs +5 -0
- package/templates/default/scripts/commit.ts_framework.ejs +3 -0
- package/templates/default/scripts/commitlint-config.ts_framework.ejs +1 -0
- package/templates/default/scripts/demo-vault-global-setup.ts.ejs +7 -4
- package/templates/default/scripts/dev.ts.ejs +1 -1
- package/templates/default/scripts/dev.ts@bundler_adapter-cli.ejs +6 -0
- package/templates/default/scripts/dev.ts@bundler_adapter-cli@run_rollup.ejs +3 -0
- package/templates/default/scripts/dev.ts@bundler_adapter-cli@run_vite.ejs +3 -0
- package/templates/default/scripts/dev.ts@bundler_adapter-cli@run_webpack.ejs +3 -0
- package/templates/default/scripts/dev.ts@bundler_esbuild.ejs +2 -2
- package/templates/default/scripts/dev.ts@bundler_esbuild@preset_framework.ejs +5 -0
- package/templates/default/scripts/dev.ts@bundler_parcel-adapter.ejs +5 -0
- package/templates/default/scripts/eslint-config.ts.ejs +3 -14
- package/templates/default/scripts/eslint-config.ts@ignores_docs-showcase.ejs +4 -0
- package/templates/default/scripts/find-overexposed-fix.ts.ejs +4 -4
- package/templates/default/scripts/find-overexposed.ts.ejs +3 -3
- package/templates/default/scripts/format-check.ts@tool_biome-formatter.ejs +3 -8
- package/templates/default/scripts/format-check.ts@tool_biome-formatter@preset_framework.ejs +7 -0
- package/templates/default/scripts/format-check.ts@tool_biome-formatter@preset_standalone.ejs +8 -0
- package/templates/default/scripts/format-check.ts@tool_dprint.ejs +2 -2
- package/templates/default/scripts/format-check.ts@tool_dprint@preset_framework.ejs +7 -0
- package/templates/default/scripts/format-check.ts@tool_prettier.ejs +3 -8
- package/templates/default/scripts/format-check.ts@tool_prettier@preset_framework.ejs +7 -0
- package/templates/default/scripts/format-check.ts@tool_prettier@preset_standalone.ejs +8 -0
- package/templates/default/scripts/format.ts@tool_biome-formatter.ejs +3 -8
- package/templates/default/scripts/format.ts@tool_biome-formatter@preset_framework.ejs +7 -0
- package/templates/default/scripts/format.ts@tool_biome-formatter@preset_standalone.ejs +8 -0
- package/templates/default/scripts/format.ts@tool_dprint.ejs +2 -2
- package/templates/default/scripts/format.ts@tool_dprint@preset_framework.ejs +7 -0
- package/templates/default/scripts/format.ts@tool_prettier.ejs +3 -8
- package/templates/default/scripts/format.ts@tool_prettier@preset_framework.ejs +7 -0
- package/templates/default/scripts/format.ts@tool_prettier@preset_standalone.ejs +8 -0
- package/templates/default/scripts/gate.ts.ejs +3 -3
- package/templates/default/scripts/lint-fix.ts.ejs +2 -2
- package/templates/default/scripts/lint-fix.ts@tool_biome-linter.ejs +3 -8
- package/templates/default/scripts/lint-fix.ts@tool_biome-linter@preset_framework.ejs +7 -0
- package/templates/default/scripts/lint-fix.ts@tool_biome-linter@preset_standalone.ejs +8 -0
- package/templates/default/scripts/lint-fix.ts@tool_eslint.ejs +2 -2
- package/templates/default/scripts/lint-fix.ts@tool_eslint@preset_framework.ejs +7 -0
- package/templates/default/scripts/lint-md-fix.ts_framework.ejs +7 -0
- package/templates/default/scripts/lint-md.ts_framework.ejs +7 -0
- package/templates/default/scripts/lint.ts.ejs +2 -2
- package/templates/default/scripts/lint.ts@tool_biome-linter.ejs +3 -8
- package/templates/default/scripts/lint.ts@tool_biome-linter@preset_framework.ejs +7 -0
- package/templates/default/scripts/lint.ts@tool_biome-linter@preset_standalone.ejs +8 -0
- package/templates/default/scripts/lint.ts@tool_eslint.ejs +2 -2
- package/templates/default/scripts/lint.ts@tool_eslint@preset_framework.ejs +7 -0
- package/templates/default/scripts/{markdownlint-cli2-config.ts_dev-utils.ejs → markdownlint-cli2-config.ts_framework.ejs} +4 -4
- package/templates/default/scripts/markdownlint-cli2-config.ts_standalone.ejs +0 -3
- package/templates/default/scripts/nano-staged-config.ts_toolkit-nano-staged.ejs +3 -0
- package/templates/default/scripts/prepare.ts_framework.ejs +3 -0
- package/templates/default/scripts/rollup.config.ts_framework.ejs +49 -0
- package/templates/default/scripts/rollup.config.ts_framework@plugin_rollup-json.ejs +2 -0
- package/templates/default/scripts/rollup.config.ts_framework@plugin_scss.ejs +3 -0
- package/templates/default/scripts/{rollup.config.ts.ejs → rollup.config.ts_standalone.ejs} +4 -4
- package/templates/default/scripts/rollup.config.ts_standalone@import_rollup-json.ejs +1 -0
- package/templates/default/scripts/rollup.config.ts_standalone@import_scss.ejs +1 -0
- package/templates/default/scripts/rollup.config.ts_standalone@unwrap_rollup-json.ejs +1 -0
- package/templates/default/scripts/rollup.config.ts_standalone@unwrap_scss.ejs +1 -0
- package/templates/default/scripts/spellcheck.ts_framework.ejs +7 -0
- package/templates/default/scripts/stylesheet-stub.ts.ejs +1 -1
- package/templates/default/scripts/test-coverage.ts.ejs +2 -8
- package/templates/default/scripts/test-coverage.ts@tool_jest.ejs +5 -0
- package/templates/default/scripts/test-coverage.ts@tool_vitest.ejs +8 -0
- package/templates/default/scripts/test-e2e.ts@tool_obsidian-test.ejs +2 -8
- package/templates/default/scripts/test-e2e.ts@tool_obsidian-test@preset_framework.ejs +4 -0
- package/templates/default/scripts/test-e2e.ts@tool_obsidian-test@preset_standalone.ejs +8 -0
- package/templates/default/scripts/test-e2e.ts@tool_wdio-obsidian.ejs +2 -8
- package/templates/default/scripts/test-e2e.ts@tool_wdio-obsidian@preset_framework.ejs +5 -0
- package/templates/default/scripts/test-e2e.ts@tool_wdio-obsidian@preset_standalone.ejs +8 -0
- package/templates/default/scripts/test-integration-android.ts.ejs +2 -2
- package/templates/default/scripts/test-integration-demo-vault.ts.ejs +2 -2
- package/templates/default/scripts/test-integration-desktop-performance.ts.ejs +2 -2
- package/templates/default/scripts/test-integration-desktop.ts.ejs +2 -2
- package/templates/default/scripts/test-integration-no-app.ts.ejs +2 -2
- package/templates/default/scripts/test-integration.ts.ejs +2 -2
- package/templates/default/scripts/test-watch.ts_framework@tool_jest.ejs +5 -0
- package/templates/default/scripts/test-watch.ts_framework@tool_vitest.ejs +8 -0
- package/templates/default/scripts/test.ts_framework@tool_jest.ejs +5 -0
- package/templates/default/scripts/test.ts_framework@tool_vitest.ejs +8 -0
- package/templates/default/scripts/{version.ts_dev-utils.ejs → version.ts_framework.ejs} +3 -3
- package/templates/default/scripts/vite.config.ts_framework.ejs +10 -0
- package/templates/default/scripts/{vite.config.ts.ejs → vite.config.ts_standalone.ejs} +5 -8
- package/templates/default/scripts/vitest-config.ts.ejs +3 -2
- package/templates/default/scripts/vitest-config.ts@edit-context_docs-showcase.ejs +3 -0
- package/templates/default/scripts/webpack.config.ts_framework.ejs +19 -0
- package/templates/default/scripts/webpack.config.ts_framework@import_scss.ejs +1 -0
- package/templates/default/scripts/webpack.config.ts_framework@plugin_scss.ejs +1 -0
- package/templates/default/scripts/webpack.config.ts_framework@rule_scss.ejs +4 -0
- package/templates/default/scripts/{webpack.config.ts.ejs → webpack.config.ts_standalone.ejs} +4 -4
- package/templates/default/src/demo-vault-buttons.demo-vault.integration.test.ts.ejs +2 -2
- package/templates/default/src/demo-vault.no-app.integration.test.ts.ejs +3 -3
- package/templates/default/src/docs-showcase.desktop.integration.test.ts.ejs +77 -0
- package/templates/default/src/editor-extensions/{sample-state-field.ts_dev-utils.ejs → sample-state-field.ts_framework.ejs} +1 -1
- package/templates/default/src/main.ts@import_tailwind.ejs +1 -1
- package/templates/default/src/main.ts@import_tailwind@preset_framework.ejs +1 -0
- package/templates/default/src/main.ts@import_tailwind@preset_standalone.ejs +1 -0
- package/templates/default/src/{plugin-settings-component.test.ts_enhanced.ejs → plugin-settings-component.test.ts_all-in-one.ejs} +4 -4
- package/templates/default/src/plugin-settings-component.test.ts_demo.ejs +5 -5
- package/templates/default/src/{plugin-settings-component.ts_enhanced.ejs → plugin-settings-component.ts_all-in-one.ejs} +3 -3
- package/templates/default/src/plugin-settings-component.ts_demo.ejs +7 -7
- package/templates/default/src/{plugin-settings-tab.ts_enhanced.ejs → plugin-settings-tab.ts_all-in-one.ejs} +1 -1
- package/templates/default/src/plugin-settings-tab.ts_demo.ejs +3 -3
- package/templates/default/src/plugin-settings.ts_demo.ejs +2 -2
- package/templates/default/src/{plugin.ts_enhanced.ejs → plugin.ts_all-in-one.ejs} +5 -5
- package/templates/default/src/plugin.ts_all-in-one@import2_css-modules.ejs +1 -0
- package/templates/default/src/plugin.ts_all-in-one@import2_docs-showcase.ejs +1 -0
- package/templates/default/src/plugin.ts_all-in-one@onload_css-modules.ejs +1 -0
- package/templates/default/src/plugin.ts_all-in-one@onload_docs-showcase.ejs +3 -0
- package/templates/default/src/plugin.ts_demo.ejs +16 -16
- package/templates/default/src/plugin.ts_demo@import_css-modules.ejs +1 -0
- package/templates/default/src/plugin.ts_demo@onload_css-modules.ejs +1 -0
- package/templates/default/src/plugin.ts_standalone.ejs +5 -3
- package/templates/default/src/plugin.ts_standalone@import_css-modules.ejs +1 -0
- package/templates/default/src/plugin.ts_standalone@onload_css-modules.ejs +1 -0
- package/templates/default/src/react-components/{sample-react-component.tsx_dev-utils.ejs → sample-react-component.tsx_framework.ejs} +1 -1
- package/templates/default/src/styles/css-modules.d.ts.ejs +9 -3
- package/templates/default/src/styles/{main.css_dev-utils.ejs → main.css_framework.ejs} +2 -2
- package/templates/default/src/styles/main.module.css.ejs +4 -2
- package/templates/default/src/styles/{main.scss_dev-utils.ejs → main.scss_framework.ejs} +2 -2
- package/templates/default/src/styles/sample-css-module-command.ts.ejs +30 -0
- package/templates/default/src/views/{sample-react-view.tsx_dev-utils.ejs → sample-react-view.tsx_framework.ejs} +1 -1
- package/templates/default/src/wasm/README.md.ejs +1 -1
- package/templates/default/src/wasm/answer.ts_wasm-adapter.ejs +18 -0
- package/templates/default/{tsconfig.json_dev-utils.ejs → tsconfig.json_framework.ejs} +2 -2
- package/templates/default/tsconfig.json_framework@exclude_docs-showcase.ejs +4 -0
- package/templates/default/tsconfig.json_framework@include_wdio-obsidian.ejs +1 -0
- package/templates/default/tsconfig.json_framework@types_toolkit-styles.ejs +2 -0
- package/templates/default/tsconfig.json_framework@types_wasm.ejs +2 -0
- package/templates/default/tsconfig.json_standalone.ejs +1 -1
- package/templates/default/vitest.config.ts_standalone.ejs +11 -2
- package/templates/default/wdio.conf.mts.ejs +5 -0
- package/templates/default/wdio.conf.ts.ejs +4 -4
- package/templates/docs-showcase/files/src/docs/README.md +511 -0
- package/templates/docs-showcase/files/src/docs/entry.d.ts +8 -0
- package/templates/docs-showcase/files/src/docs/entry.js +4 -0
- package/templates/docs-showcase/files/src/docs/host.ts +449 -0
- package/templates/docs-showcase/files/src/docs/index.ts +699 -0
- package/templates/docs-showcase/files/src/docs/plugins/editor/communicating-with-editor-extensions/01-intro.ts +21 -0
- package/templates/docs-showcase/files/src/docs/plugins/editor/communicating-with-editor-extensions/03-state-field.ts +32 -0
- package/templates/docs-showcase/files/src/docs/plugins/editor/decorations/01-widgets.ts +23 -0
- package/templates/docs-showcase/files/src/docs/plugins/editor/decorations/02-widgets.ts +20 -0
- package/templates/docs-showcase/files/src/docs/plugins/editor/decorations/04-state-fields.ts +57 -0
- package/templates/docs-showcase/files/src/docs/plugins/editor/decorations/05-view-plugins.ts +79 -0
- package/templates/docs-showcase/files/src/docs/plugins/editor/editor/01-intro.ts +26 -0
- package/templates/docs-showcase/files/src/docs/plugins/editor/editor/03-replace-current-selection.ts +26 -0
- package/templates/docs-showcase/files/src/docs/plugins/editor/markdown-post-processing/01-intro.ts +39 -0
- package/templates/docs-showcase/files/src/docs/plugins/editor/state-fields/01-defining-state-effects.ts +19 -0
- package/templates/docs-showcase/files/src/docs/plugins/editor/state-fields/02-defining-a-state-field.ts +35 -0
- package/templates/docs-showcase/files/src/docs/plugins/editor/state-fields/04-dispatching-state-effects.ts +34 -0
- package/templates/docs-showcase/files/src/docs/plugins/editor/state-management/01-state-changes.ts +21 -0
- package/templates/docs-showcase/files/src/docs/plugins/editor/state-management/02-state-changes.ts +23 -0
- package/templates/docs-showcase/files/src/docs/plugins/editor/view-plugins/01-creating-a-view-plugin.ts +36 -0
- package/templates/docs-showcase/files/src/docs/plugins/events/01-intro.ts +21 -0
- package/templates/docs-showcase/files/src/docs/plugins/getting-started/anatomy-of-a-plugin/01-intro.ts +22 -0
- package/templates/docs-showcase/files/src/docs/plugins/getting-started/anatomy-of-a-plugin/02-plugin-lifecycle.ts +22 -0
- package/templates/docs-showcase/files/src/docs/plugins/getting-started/build-a-plugin/06-step-5-update-the-source-code.ts +19 -0
- package/templates/docs-showcase/files/src/docs/plugins/getting-started/build-a-plugin/07-step-5-update-the-source-code.ts +21 -0
- package/templates/docs-showcase/files/src/docs/plugins/getting-started/mobile-development/03-platform-specific-features.ts +25 -0
- package/templates/docs-showcase/files/src/docs/plugins/getting-started/use-react-in-your-plugin/03-configure-your-plugin.ts +23 -0
- package/templates/docs-showcase/files/src/docs/plugins/guides/build-a-bases-view/01-step-1-sample-plugin-setup.ts +18 -0
- package/templates/docs-showcase/files/src/docs/plugins/guides/build-a-bases-view/02-step-2-create-and-register-the-bases-vie.ts +46 -0
- package/templates/docs-showcase/files/src/docs/plugins/guides/build-a-bases-view/03-step-3-add-configuration.ts +40 -0
- package/templates/docs-showcase/files/src/docs/plugins/guides/defer-views/04-accessing-your-customview-without-reveal.ts +26 -0
- package/templates/docs-showcase/files/src/docs/plugins/guides/manage-plugin-lifecycle/01-overview.ts +26 -0
- package/templates/docs-showcase/files/src/docs/plugins/guides/manage-plugin-lifecycle/02-overview.ts +30 -0
- package/templates/docs-showcase/files/src/docs/plugins/guides/manage-plugin-lifecycle/03-automatic-resource-management-with-compo.ts +26 -0
- package/templates/docs-showcase/files/src/docs/plugins/guides/manage-plugin-lifecycle/04-registerevent-eventref.ts +22 -0
- package/templates/docs-showcase/files/src/docs/plugins/guides/manage-plugin-lifecycle/05-registerinterval-id.ts +21 -0
- package/templates/docs-showcase/files/src/docs/plugins/guides/manage-plugin-lifecycle/06-registerdomevent-el-event-handler.ts +20 -0
- package/templates/docs-showcase/files/src/docs/plugins/guides/manage-plugin-lifecycle/08-understanding-the-lifecycle-of-objects.ts +29 -0
- package/templates/docs-showcase/files/src/docs/plugins/guides/manage-plugin-lifecycle/14-componentized-modal-example.ts +37 -0
- package/templates/docs-showcase/files/src/docs/plugins/guides/optimize-plugin-load-time/01-option-a-check-if-the-layout-is-ready.ts +29 -0
- package/templates/docs-showcase/files/src/docs/plugins/guides/optimize-plugin-load-time/02-option-b-register-the-handler-once-the-l.ts +27 -0
- package/templates/docs-showcase/files/src/docs/plugins/guides/store-secrets/03-step-3-retrieve-the-secret-value.ts +22 -0
- package/templates/docs-showcase/files/src/docs/plugins/releasing/plugin-guidelines/01-use-setheading-instead-of-a-h1-h2.ts +20 -0
- package/templates/docs-showcase/files/src/docs/plugins/releasing/plugin-guidelines/03-clean-up-resources-when-plugin-unloads.ts +23 -0
- package/templates/docs-showcase/files/src/docs/plugins/releasing/plugin-guidelines/04-avoid-accessing-workspace-activeleaf-dir.ts +24 -0
- package/templates/docs-showcase/files/src/docs/plugins/releasing/plugin-guidelines/05-avoid-accessing-workspace-activeleaf-dir.ts +22 -0
- package/templates/docs-showcase/files/src/docs/plugins/releasing/plugin-guidelines/10-avoid-iterating-all-files-to-find-a-file.ts +20 -0
- package/templates/docs-showcase/files/src/docs/plugins/releasing/plugin-guidelines/11-avoid-iterating-all-files-to-find-a-file.ts +20 -0
- package/templates/docs-showcase/files/src/docs/plugins/releasing/plugin-guidelines/13-use-normalizepath-to-clean-up-user-defin.ts +18 -0
- package/templates/docs-showcase/files/src/docs/plugins/releasing/plugin-guidelines/15-no-hardcoded-styling.ts +21 -0
- package/templates/docs-showcase/files/src/docs/plugins/releasing/plugin-guidelines/16-no-hardcoded-styling.ts +19 -0
- package/templates/docs-showcase/files/src/docs/plugins/releasing/plugin-guidelines/17-no-hardcoded-styling.ts +14 -0
- package/templates/docs-showcase/files/src/docs/plugins/releasing/plugin-guidelines/18-prefer-async-await-over-promise.ts +24 -0
- package/templates/docs-showcase/files/src/docs/plugins/releasing/plugin-guidelines/19-prefer-async-await-over-promise.ts +27 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/commands/01-intro.ts +25 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/commands/03-editor-commands.ts +27 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/commands/05-hot-keys.ts +25 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/context-menus/01-intro.ts +41 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/html-elements/02-create-html-elements-using-createel.ts +19 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/html-elements/03-create-html-elements-using-createel.ts +21 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/html-elements/04-style-your-elements.ts +14 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/html-elements/05-style-your-elements.ts +21 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/html-elements/06-conditional-styles.ts +19 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/icons/01-use-icons.ts +20 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/icons/02-use-icons.ts +14 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/icons/03-add-your-own-icon.ts +23 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/modals/01-intro.ts +20 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/modals/02-intro.ts +26 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/modals/03-accept-user-input.ts +38 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/modals/04-accept-user-input.ts +22 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/modals/05-select-from-list-of-suggestions.ts +56 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/modals/06-approximate-string-matching-results.ts +28 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/modals/07-custom-rendering-of-fuzzy-search-results.ts +41 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/ribbon-actions/01-intro.ts +21 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/right-to-left/01-use-fallback-values-when-necessary.ts +14 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/right-to-left/02-global-selectors.ts +14 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/right-to-left/03-icons-are-mirrored-automatically.ts +14 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/09-toggle.ts +20 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/10-text.ts +23 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/11-textarea.ts +23 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/12-number.ts +23 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/13-slider.ts +23 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/14-dropdown.ts +28 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/15-file.ts +27 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/16-folder.ts +23 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/17-color-picker.ts +20 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/18-validating-input.ts +28 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/23-groups.ts +27 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/32-cleanup.ts +30 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/33-no-top-level-heading.ts +27 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/34-headings-only-when-there-are-multiple-se.ts +26 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/36-headings.ts +20 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/38-moment-format.ts +42 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/39-buttons.ts +26 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/40-extra-button.ts +28 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/settings/41-progress-bar.ts +23 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/status-bar/01-intro.ts +20 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/status-bar/02-intro.ts +25 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/views/01-intro.ts +39 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/workspace/05-inspect-the-workspace.ts +23 -0
- package/templates/docs-showcase/files/src/docs/plugins/user-interface/workspace/06-leaf-groups.ts +19 -0
- package/templates/docs-showcase/files/src/docs/plugins/vault/02-read-files.ts +37 -0
- package/templates/docs-showcase/files/src/docs/plugins/vault/03-modify-files.ts +19 -0
- package/templates/docs-showcase/files/src/docs/plugins/vault/04-modify-files.ts +22 -0
- package/templates/docs-showcase/files/src/docs/plugins/vault/05-is-it-a-file-or-folder.ts +25 -0
- package/templates/docs-showcase/files/src/docs/reference/css-variables/about-styling/01-for-plugins.ts +14 -0
- package/templates/docs-showcase/files/src/docs/reference/css-variables/about-styling/02-for-themes-and-snippets.ts +14 -0
- package/templates/docs-showcase/files/src/docs/reference/css-variables/publish/site-fonts/01-intro.ts +14 -0
- package/templates/docs-showcase/files/src/docs/reference/typescript-api/command/callback/01-example.ts +24 -0
- package/templates/docs-showcase/files/src/docs/reference/typescript-api/debounce/01-example.ts +24 -0
- package/templates/docs-showcase/files/src/docs/reference/typescript-api/vault/process/01-example.ts +22 -0
- package/templates/docs-showcase/files/src/docs/themes/app-themes/build-a-theme/05-step-4-change-the-font.ts +14 -0
- package/templates/docs-showcase/files/src/docs/themes/app-themes/build-a-theme/06-step-5-change-the-background-color.ts +14 -0
- package/templates/docs-showcase/files/src/docs/themes/app-themes/build-a-theme/07-step-6-change-the-input-hover-border-col.ts +14 -0
- package/templates/docs-showcase/files/src/docs/themes/app-themes/build-a-theme/08-step-7-discover-css-variables-in-use.ts +14 -0
- package/templates/docs-showcase/files/src/docs/themes/app-themes/embed-fonts-and-images-in-your-theme/02-use-data-urls.ts +14 -0
- package/templates/docs-showcase/files/src/docs/themes/app-themes/theme-guidelines/01-use-css-variables.ts +14 -0
- package/templates/docs-showcase/files/src/docs/themes/obsidian-publish-themes/best-practices-for-publish-themes/01-small-screens-and-mobile-devices.ts +14 -0
- package/templates/docs-showcase/files/src/docs/themes/obsidian-publish-themes/build-a-publish-theme/01-intro.ts +14 -0
- package/templates/docs-showcase/files/src/docs/tsconfig.json +25 -0
- package/templates/docs-showcase/host/entry.d.ts +8 -0
- package/templates/docs-showcase/host/entry.js +4 -0
- package/templates/docs-showcase/host/host.ts +449 -0
- package/templates/docs-showcase/host/tsconfig.json +25 -0
- package/templates/docs-showcase/snippets.json +3566 -0
- package/templates/official-sample/README.md +9 -0
- package/templates/official-sample/files/.editorconfig.vendored +11 -0
- package/templates/official-sample/files/.github/workflows/lint.yml.vendored +27 -0
- package/templates/official-sample/files/.github/workflows/release.yml.vendored +50 -0
- package/templates/official-sample/files/.gitignore.vendored +22 -0
- package/templates/official-sample/files/.npmrc.vendored +1 -0
- package/templates/official-sample/files/AGENTS.md.vendored +269 -0
- package/templates/official-sample/files/LICENSE.vendored +5 -0
- package/templates/official-sample/files/README.md.vendored +92 -0
- package/templates/official-sample/files/esbuild.config.mjs.vendored +49 -0
- package/templates/official-sample/files/eslint.config.mts.vendored +32 -0
- package/templates/official-sample/files/manifest.json.vendored +11 -0
- package/templates/official-sample/files/package-lock.json.vendored +5053 -0
- package/templates/official-sample/files/package.json.vendored +27 -0
- package/templates/official-sample/files/src/main.ts.vendored +114 -0
- package/templates/official-sample/files/src/settings.ts.vendored +38 -0
- package/templates/official-sample/files/styles.css.vendored +8 -0
- package/templates/official-sample/files/tsconfig.json.vendored +19 -0
- package/templates/official-sample/files/version-bump.mjs.vendored +17 -0
- package/templates/official-sample/files/versions.json.vendored +3 -0
- package/upstreams.json +35 -0
- package/templates/default/dprint.json_dev-utils.ejs +0 -10
- package/templates/default/jest.config.ts@lint-root-dir_dev-utils.ejs +0 -1
- package/templates/default/scripts/build.ts@bundler_cli-bundler@lint-build-styles_dev-utils.ejs +0 -1
- package/templates/default/scripts/build.ts@bundler_esbuild@dev-utils-pre-build_tailwind.ejs +0 -2
- package/templates/default/scripts/build.ts@bundler_esbuild@lint-build-styles_dev-utils.ejs +0 -1
- package/templates/default/scripts/build.ts@bundler_esbuild@preset_dev-utils.ejs +0 -7
- package/templates/default/scripts/commit.ts_dev-utils.ejs +0 -3
- package/templates/default/scripts/dev.ts@bundler_esbuild@dev-utils-pre-build_tailwind.ejs +0 -2
- package/templates/default/scripts/dev.ts@bundler_esbuild@lint-build-styles_dev-utils.ejs +0 -1
- package/templates/default/scripts/dev.ts@bundler_esbuild@preset_dev-utils.ejs +0 -7
- package/templates/default/scripts/esbuild-plugins.ts.ejs +0 -20
- package/templates/default/scripts/esbuild-plugins.ts@dev-utils-import_vue.ejs +0 -2
- package/templates/default/scripts/esbuild-plugins.ts@dev-utils-plugin_vue.ejs +0 -1
- package/templates/default/scripts/esbuild-plugins.ts@dev-utils-plugin_wasm.ejs +0 -13
- package/templates/default/scripts/format-check.ts@tool_dprint@preset_dev-utils.ejs +0 -7
- package/templates/default/scripts/format.ts@tool_dprint@preset_dev-utils.ejs +0 -7
- package/templates/default/scripts/lint-fix.ts@tool_eslint@preset_dev-utils.ejs +0 -7
- package/templates/default/scripts/lint-md-fix.ts_dev-utils.ejs +0 -7
- package/templates/default/scripts/lint-md.ts_dev-utils.ejs +0 -7
- package/templates/default/scripts/lint.ts@tool_eslint@preset_dev-utils.ejs +0 -7
- package/templates/default/scripts/prepare.ts_dev-utils.ejs +0 -3
- package/templates/default/scripts/spellcheck.ts_dev-utils.ejs +0 -7
- package/templates/default/scripts/test-watch.ts_dev-utils@tool_jest.ejs +0 -13
- package/templates/default/scripts/test-watch.ts_dev-utils@tool_vitest.ejs +0 -8
- package/templates/default/scripts/test.ts_dev-utils@tool_jest.ejs +0 -13
- package/templates/default/scripts/test.ts_dev-utils@tool_vitest.ejs +0 -8
- package/templates/default/scripts/vite.config.ts@lint-empty-out-dir_dev-utils.ejs +0 -1
- package/templates/default/scripts/vite.config.ts@lint-out-dir_dev-utils.ejs +0 -1
- package/templates/default/scripts/webpack.config.ts@lint-webpack-default_dev-utils.ejs +0 -1
- package/templates/default/src/main.ts@import_css-modules.ejs +0 -1
- package/templates/default/src/views/sample-preact-view.tsx_dev-utils.ejs +0 -45
- package/templates/default/tsconfig.json_dev-utils@compiler-options_preact.ejs +0 -2
- package/templates/default/tsconfig.json_dev-utils@compiler-options_react.ejs +0 -1
- package/templates/default/tsconfig.json_dev-utils@compiler-options_solid.ejs +0 -2
- /package/templates/default/.github/workflows/{ci.yml@steps_biome-linter.ejs → ci.yml_standalone@steps_biome-linter.ejs} +0 -0
- /package/templates/default/.github/workflows/{ci.yml@steps_cspell.ejs → ci.yml_standalone@steps_cspell.ejs} +0 -0
- /package/templates/default/.github/workflows/{ci.yml@steps_dprint.ejs → ci.yml_standalone@steps_dprint.ejs} +0 -0
- /package/templates/default/.github/workflows/{ci.yml@steps_eslint.ejs → ci.yml_standalone@steps_eslint.ejs} +0 -0
- /package/templates/default/.github/workflows/{ci.yml@steps_jest.ejs → ci.yml_standalone@steps_jest.ejs} +0 -0
- /package/templates/default/.github/workflows/{ci.yml@steps_markdownlint.ejs → ci.yml_standalone@steps_markdownlint.ejs} +0 -0
- /package/templates/default/.github/workflows/{ci.yml@steps_prettier.ejs → ci.yml_standalone@steps_prettier.ejs} +0 -0
- /package/templates/default/.github/workflows/{ci.yml@steps_vitest.ejs → ci.yml_standalone@steps_vitest.ejs} +0 -0
- /package/templates/default/{.gitignore_tailwind.ejs → .gitignore_tailwind-cli.ejs} +0 -0
- /package/templates/default/{CONTRIBUTING.md@scripts_dev-utils.ejs → CONTRIBUTING.md@scripts_framework.ejs} +0 -0
- /package/templates/default/e2e/{sample.spec.ts_obsidian-test@lint-no-void-disable_dev-utils.ejs → sample.spec.ts_obsidian-test@lint-no-void-disable_framework.ejs} +0 -0
- /package/templates/default/e2e/{sample.spec.ts_obsidian-test@lint-no-void-enable_dev-utils.ejs → sample.spec.ts_obsidian-test@lint-no-void-enable_framework.ejs} +0 -0
- /package/templates/default/{eslint.config.mts_dev-utils.ejs → eslint.config.mts_framework.ejs} +0 -0
- /package/templates/default/{jest.config.ts@ts-jest-tsconfig_solid.ejs → jest.config.ts_standalone@ts-jest-tsconfig_solid.ejs} +0 -0
- /package/templates/default/{prettier.config.mjs.ejs → prettier.config.mjs_standalone.ejs} +0 -0
- /package/templates/default/scripts/{commitlint-config.ts.ejs → commitlint-config.ts_standalone.ejs} +0 -0
- /package/templates/default/scripts/{nano-staged-config.ts.ejs → nano-staged-config.ts_inline-nano-staged.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@import_rollup-json.ejs → rollup.config.ts_framework@import_rollup-json.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@import_scss.ejs → rollup.config.ts_framework@import_scss.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@unwrap_rollup-json.ejs → rollup.config.ts_framework@unwrap_rollup-json.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@unwrap_scss.ejs → rollup.config.ts_framework@unwrap_scss.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@import_rollup-babel.ejs → rollup.config.ts_standalone@import_rollup-babel.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@import_rollup-postcss.ejs → rollup.config.ts_standalone@import_rollup-postcss.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@import_svelte.ejs → rollup.config.ts_standalone@import_svelte.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@import_vue.ejs → rollup.config.ts_standalone@import_vue.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@import_wasm.ejs → rollup.config.ts_standalone@import_wasm.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@post-plugin_preact.ejs → rollup.config.ts_standalone@post-plugin_preact.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@post-plugin_react.ejs → rollup.config.ts_standalone@post-plugin_react.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@post-plugin_rollup-json.ejs → rollup.config.ts_standalone@post-plugin_rollup-json.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@post-plugin_rollup-postcss.ejs → rollup.config.ts_standalone@post-plugin_rollup-postcss.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@post-plugin_scss.ejs → rollup.config.ts_standalone@post-plugin_scss.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@post-plugin_solid.ejs → rollup.config.ts_standalone@post-plugin_solid.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@post-plugin_wasm.ejs → rollup.config.ts_standalone@post-plugin_wasm.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@pre-plugin_svelte.ejs → rollup.config.ts_standalone@pre-plugin_svelte.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@pre-plugin_vue.ejs → rollup.config.ts_standalone@pre-plugin_vue.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@unwrap_rollup-babel.ejs → rollup.config.ts_standalone@unwrap_rollup-babel.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@unwrap_rollup-postcss.ejs → rollup.config.ts_standalone@unwrap_rollup-postcss.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@unwrap_svelte.ejs → rollup.config.ts_standalone@unwrap_svelte.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@unwrap_vue.ejs → rollup.config.ts_standalone@unwrap_vue.ejs} +0 -0
- /package/templates/default/scripts/{rollup.config.ts@unwrap_wasm.ejs → rollup.config.ts_standalone@unwrap_wasm.ejs} +0 -0
- /package/templates/default/scripts/{test-watch.ts_dev-utils.ejs → test-watch.ts_framework.ejs} +0 -0
- /package/templates/default/scripts/{test.ts_dev-utils.ejs → test.ts_framework.ejs} +0 -0
- /package/templates/default/scripts/{vite.config.ts@import_preact.ejs → vite.config.ts_standalone@import_preact.ejs} +0 -0
- /package/templates/default/scripts/{vite.config.ts@import_react.ejs → vite.config.ts_standalone@import_react.ejs} +0 -0
- /package/templates/default/scripts/{vite.config.ts@import_solid.ejs → vite.config.ts_standalone@import_solid.ejs} +0 -0
- /package/templates/default/scripts/{vite.config.ts@import_svelte.ejs → vite.config.ts_standalone@import_svelte.ejs} +0 -0
- /package/templates/default/scripts/{vite.config.ts@import_vue.ejs → vite.config.ts_standalone@import_vue.ejs} +0 -0
- /package/templates/default/scripts/{vite.config.ts@plugin_preact.ejs → vite.config.ts_standalone@plugin_preact.ejs} +0 -0
- /package/templates/default/scripts/{vite.config.ts@plugin_react.ejs → vite.config.ts_standalone@plugin_react.ejs} +0 -0
- /package/templates/default/scripts/{vite.config.ts@plugin_solid.ejs → vite.config.ts_standalone@plugin_solid.ejs} +0 -0
- /package/templates/default/scripts/{vite.config.ts@plugin_svelte.ejs → vite.config.ts_standalone@plugin_svelte.ejs} +0 -0
- /package/templates/default/scripts/{vite.config.ts@plugin_vue.ejs → vite.config.ts_standalone@plugin_vue.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@import_svelte.ejs → webpack.config.ts_standalone@import_svelte.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@import_vue.ejs → webpack.config.ts_standalone@import_vue.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@import_webpack-css-extract.ejs → webpack.config.ts_standalone@import_webpack-css-extract.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@plugin_vue.ejs → webpack.config.ts_standalone@plugin_vue.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@plugin_webpack-css-extract.ejs → webpack.config.ts_standalone@plugin_webpack-css-extract.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@rule_css-modules.ejs → webpack.config.ts_standalone@rule_css-modules.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@rule_css.ejs → webpack.config.ts_standalone@rule_css.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@rule_postcss.ejs → webpack.config.ts_standalone@rule_postcss.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@rule_scss.ejs → webpack.config.ts_standalone@rule_scss.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@rule_solid.ejs → webpack.config.ts_standalone@rule_solid.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@rule_svelte.ejs → webpack.config.ts_standalone@rule_svelte.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@rule_tailwind.ejs → webpack.config.ts_standalone@rule_tailwind.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@rule_vue.ejs → webpack.config.ts_standalone@rule_vue.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@rule_wasm.ejs → webpack.config.ts_standalone@rule_wasm.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@ts-loader-compiler-options_vue.ejs → webpack.config.ts_standalone@ts-loader-compiler-options_vue.ejs} +0 -0
- /package/templates/default/scripts/{webpack.config.ts@ts-loader-options_vue.ejs → webpack.config.ts_standalone@ts-loader-options_vue.ejs} +0 -0
- /package/templates/default/src/{plugin-settings-component.test.ts_enhanced@test-imports_vitest.ejs → plugin-settings-component.test.ts_all-in-one@test-imports_vitest.ejs} +0 -0
- /package/templates/default/src/{plugin-settings.ts_enhanced.ejs → plugin-settings.ts_all-in-one.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@import2_codemirror.ejs → plugin.ts_all-in-one@import2_codemirror.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@import2_i18next.ejs → plugin.ts_all-in-one@import2_i18next.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@import2_lit.ejs → plugin.ts_all-in-one@import2_lit.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@import2_preact.ejs → plugin.ts_all-in-one@import2_preact.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@import2_react.ejs → plugin.ts_all-in-one@import2_react.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@import2_solid.ejs → plugin.ts_all-in-one@import2_solid.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@import2_svelte.ejs → plugin.ts_all-in-one@import2_svelte.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@import2_typesafe-i18n.ejs → plugin.ts_all-in-one@import2_typesafe-i18n.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@import2_vue.ejs → plugin.ts_all-in-one@import2_vue.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@import2_wasm.ejs → plugin.ts_all-in-one@import2_wasm.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@method_ui-view.ejs → plugin.ts_all-in-one@method_ui-view.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@onload_codemirror.ejs → plugin.ts_all-in-one@onload_codemirror.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@onload_i18next.ejs → plugin.ts_all-in-one@onload_i18next.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@onload_lit.ejs → plugin.ts_all-in-one@onload_lit.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@onload_preact.ejs → plugin.ts_all-in-one@onload_preact.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@onload_react.ejs → plugin.ts_all-in-one@onload_react.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@onload_solid.ejs → plugin.ts_all-in-one@onload_solid.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@onload_svelte.ejs → plugin.ts_all-in-one@onload_svelte.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@onload_typesafe-i18n.ejs → plugin.ts_all-in-one@onload_typesafe-i18n.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@onload_vue.ejs → plugin.ts_all-in-one@onload_vue.ejs} +0 -0
- /package/templates/default/src/{plugin.ts_enhanced@onload_wasm.ejs → plugin.ts_all-in-one@onload_wasm.ejs} +0 -0
- /package/templates/default/src/preact-components/{sample-preact-component.tsx_dev-utils.ejs → sample-preact-component.tsx_framework.ejs} +0 -0
- /package/templates/default/src/solid-components/{sample-solid-component.tsx_dev-utils.ejs → sample-solid-component.tsx_framework.ejs} +0 -0
- /package/templates/default/src/styles/{main.css_dev-utils@content_tailwind.ejs → main.css_framework@content_tailwind.ejs} +0 -0
- /package/templates/default/src/views/{sample-lit-view.ts@lint-register-element_dev-utils.ejs → sample-lit-view.ts@lint-register-element_framework.ejs} +0 -0
- /package/templates/default/src/views/{sample-preact-view.tsx_standalone.ejs → sample-preact-view.tsx.ejs} +0 -0
- /package/templates/default/src/views/{sample-solid-view.tsx_dev-utils.ejs → sample-solid-view.tsx_framework.ejs} +0 -0
- /package/templates/default/src/wasm/{answer.ts_esbuild.ejs → answer.ts_wasm-esbuild.ejs} +0 -0
- /package/templates/default/src/wasm/{answer.ts_parcel.ejs → answer.ts_wasm-parcel.ejs} +0 -0
- /package/templates/default/src/wasm/{answer.ts_rollup.ejs → answer.ts_wasm-rollup.ejs} +0 -0
- /package/templates/default/src/wasm/{answer.ts_vite.ejs → answer.ts_wasm-vite.ejs} +0 -0
- /package/templates/default/src/wasm/{answer.ts_webpack.ejs → answer.ts_wasm-webpack.ejs} +0 -0
- /package/templates/default/src/{wasm.d.ts_esbuild.ejs → wasm.d.ts_wasm-esbuild.ejs} +0 -0
- /package/templates/default/src/{wasm.d.ts_parcel.ejs → wasm.d.ts_wasm-parcel.ejs} +0 -0
- /package/templates/default/src/{wasm.d.ts_rollup.ejs → wasm.d.ts_wasm-rollup.ejs} +0 -0
- /package/templates/default/src/{wasm.d.ts_vite.ejs → wasm.d.ts_wasm-vite.ejs} +0 -0
- /package/templates/default/src/{wasm.d.ts_webpack.ejs → wasm.d.ts_wasm-webpack.ejs} +0 -0
- /package/templates/default/{tsconfig.json_dev-utils@compiler-options_i18next.ejs → tsconfig.json_framework@compiler-options_i18next.ejs} +0 -0
- /package/templates/default/{tsconfig.json_dev-utils@compiler-options_lit.ejs → tsconfig.json_framework@compiler-options_lit.ejs} +0 -0
- /package/templates/default/{tsconfig.json_dev-utils@include_has-e2e.ejs → tsconfig.json_framework@include_has-e2e.ejs} +0 -0
- /package/templates/default/{tsconfig.json_dev-utils@include_svelte.ejs → tsconfig.json_framework@include_svelte.ejs} +0 -0
- /package/templates/default/{tsconfig.json_dev-utils@include_vue.ejs → tsconfig.json_framework@include_vue.ejs} +0 -0
- /package/templates/default/{tsconfig.json_dev-utils@types_jest.ejs → tsconfig.json_framework@types_jest.ejs} +0 -0
- /package/templates/default/{tsconfig.json_dev-utils@types_svelte.ejs → tsconfig.json_framework@types_svelte.ejs} +0 -0
- /package/templates/default/{tsconfig.json_dev-utils@types_wdio-obsidian.ejs → tsconfig.json_framework@types_wdio-obsidian.ejs} +0 -0
- /package/templates/default/{tsconfig.json_dev-utils@types_with-unofficial.ejs → tsconfig.json_framework@types_with-unofficial.ejs} +0 -0
- /package/templates/default/{vitest.config.ts_dev-utils.ejs → vitest.config.ts_framework.ejs} +0 -0
package/dist/main.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
cancel as cancel3,
|
|
6
6
|
confirm,
|
|
7
7
|
intro,
|
|
8
|
-
log as
|
|
8
|
+
log as log5,
|
|
9
9
|
note,
|
|
10
10
|
outro,
|
|
11
11
|
select as select2,
|
|
@@ -15,12 +15,12 @@ import {
|
|
|
15
15
|
import { spawn } from "node:child_process";
|
|
16
16
|
import {
|
|
17
17
|
chmodSync,
|
|
18
|
-
existsSync as
|
|
19
|
-
readFileSync as
|
|
18
|
+
existsSync as existsSync8,
|
|
19
|
+
readFileSync as readFileSync8,
|
|
20
20
|
writeFileSync as writeFileSync2
|
|
21
21
|
} from "node:fs";
|
|
22
22
|
import {
|
|
23
|
-
join as
|
|
23
|
+
join as join8,
|
|
24
24
|
resolve as resolvePath
|
|
25
25
|
} from "node:path";
|
|
26
26
|
import { compare } from "semver";
|
|
@@ -191,38 +191,38 @@ async function promptApiSubset(savedValue) {
|
|
|
191
191
|
return promptFeature({ defaultOption: new Official(), message: "Obsidian API subset", options: API_SUBSET_OPTIONS, savedValue });
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
// src/features/preset/is-dev-utils-preset.ts
|
|
195
|
-
var DEV_UTILS_PRESETS = /* @__PURE__ */ new Set(["demo", "enhanced"]);
|
|
196
|
-
function isDevUtilsPreset(preset) {
|
|
197
|
-
return DEV_UTILS_PRESETS.has(preset);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
194
|
// src/features/bundler/esbuild.ts
|
|
201
195
|
var Esbuild = class extends FeatureOption {
|
|
202
196
|
constructor() {
|
|
203
197
|
super({ promptHint: "Fast and simple (recommended)", promptLabel: "esbuild", settingValue: "esbuild" });
|
|
204
198
|
}
|
|
205
|
-
configure(builder
|
|
199
|
+
configure(builder) {
|
|
206
200
|
builder.addPackage("esbuild");
|
|
207
|
-
if (isDevUtilsPreset(answers.preset)) {
|
|
208
|
-
builder.addFiles(["scripts/esbuild-plugins.ts"]);
|
|
209
|
-
}
|
|
210
201
|
}
|
|
211
202
|
};
|
|
212
203
|
|
|
204
|
+
// src/features/preset/is-framework-preset.ts
|
|
205
|
+
var FRAMEWORK_PRESETS = /* @__PURE__ */ new Set(["all-in-one", "demo", "docs-showcase"]);
|
|
206
|
+
function isFrameworkPreset(preset) {
|
|
207
|
+
return FRAMEWORK_PRESETS.has(preset);
|
|
208
|
+
}
|
|
209
|
+
|
|
213
210
|
// src/features/bundler/parcel.ts
|
|
214
211
|
var Parcel = class extends FeatureOption {
|
|
215
212
|
constructor() {
|
|
216
213
|
super({ promptHint: "Zero-config bundler", promptLabel: "Parcel", settingValue: "parcel" });
|
|
217
214
|
}
|
|
218
|
-
configure(builder) {
|
|
215
|
+
configure(builder, answers) {
|
|
216
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
217
|
+
builder.addPackage("@parcel/core").addPackage("@parcel/config-default").addDepcheckIgnore("@parcel/config-default", "extended by name by the `.parcelrc` obsidian-dev-toolkit writes.").addPackage("@parcel/plugin").addDepcheckIgnore("@parcel/plugin", "the base of the parcel plugins obsidian-dev-toolkit registers; nothing here imports it.").addPartial("parcel-adapter");
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
219
220
|
builder.addPackage("parcel").addDepcheckIgnore("parcel", "run as a CLI by the build script.").addPackage("@parcel/config-default").addDepcheckIgnore("@parcel/config-default", "extended by name in `.parcelrc`.").addPackage("@parcel/plugin").addFiles([
|
|
220
221
|
".parcelrc",
|
|
221
222
|
"parcel-namer-obsidian.cjs",
|
|
222
223
|
"parcel-resolver-obsidian.cjs",
|
|
223
224
|
"parcel-transformer-inline-imports.cjs"
|
|
224
|
-
]);
|
|
225
|
-
builder.addPartial("cli-bundler");
|
|
225
|
+
]).addPartial("parcel-targets").addPartial("cli-bundler");
|
|
226
226
|
}
|
|
227
227
|
};
|
|
228
228
|
|
|
@@ -231,12 +231,16 @@ var Rollup = class extends FeatureOption {
|
|
|
231
231
|
constructor() {
|
|
232
232
|
super({ promptHint: "Flexible with plugin ecosystem", promptLabel: "Rollup", settingValue: "rollup" });
|
|
233
233
|
}
|
|
234
|
-
configure(builder) {
|
|
235
|
-
builder.addPackage("@rollup/plugin-commonjs").addPackage("@rollup/plugin-node-resolve").addPackage("
|
|
234
|
+
configure(builder, answers) {
|
|
235
|
+
builder.addPackage("@rollup/plugin-commonjs").addPackage("@rollup/plugin-node-resolve").addPackage("rollup").addFiles([
|
|
236
236
|
"rollup.config.mjs",
|
|
237
237
|
"scripts/rollup.config.ts"
|
|
238
238
|
]);
|
|
239
|
-
|
|
239
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
240
|
+
builder.addPackage("esbuild").addDepcheckIgnore("esbuild", "the peer dependency `rollup-plugin-esbuild` runs; nothing imports it.").addPackage("rollup-plugin-esbuild").addPartial("adapter-cli");
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
builder.addPackage("@rollup/plugin-typescript").addPackage("@rollup/plugin-terser").addPartial("cli-bundler");
|
|
240
244
|
}
|
|
241
245
|
};
|
|
242
246
|
|
|
@@ -245,12 +249,12 @@ var Vite = class extends FeatureOption {
|
|
|
245
249
|
constructor() {
|
|
246
250
|
super({ promptHint: "Modern dev server with HMR", promptLabel: "Vite", settingValue: "vite" });
|
|
247
251
|
}
|
|
248
|
-
configure(builder) {
|
|
252
|
+
configure(builder, answers) {
|
|
249
253
|
builder.addPackage("vite").addFiles([
|
|
250
254
|
"vite.config.ts",
|
|
251
255
|
"scripts/vite.config.ts"
|
|
252
256
|
]);
|
|
253
|
-
builder.addPartial("cli-bundler");
|
|
257
|
+
builder.addPartial(isFrameworkPreset(answers.preset) ? "adapter-cli" : "cli-bundler");
|
|
254
258
|
}
|
|
255
259
|
};
|
|
256
260
|
|
|
@@ -259,12 +263,16 @@ var Webpack = class extends FeatureOption {
|
|
|
259
263
|
constructor() {
|
|
260
264
|
super({ promptHint: "Mature bundler with broad plugin support", promptLabel: "Webpack", settingValue: "webpack" });
|
|
261
265
|
}
|
|
262
|
-
configure(builder) {
|
|
263
|
-
builder.addPackage("webpack").addPackage("webpack-cli").addDepcheckIgnore("webpack-cli", "what
|
|
266
|
+
configure(builder, answers) {
|
|
267
|
+
builder.addPackage("webpack").addPackage("webpack-cli").addDepcheckIgnore("webpack-cli", "what the build script runs as the `webpack` command.").addFiles([
|
|
264
268
|
"webpack.config.ts",
|
|
265
269
|
"scripts/webpack.config.ts"
|
|
266
270
|
]);
|
|
267
|
-
|
|
271
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
272
|
+
builder.addPackage("esbuild-loader").addDepcheckIgnore("esbuild-loader", "named as a loader string in `scripts/webpack.config.ts`.").addPartial("adapter-cli");
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
builder.addPackage("terser-webpack-plugin").addPackage("ts-loader").addDepcheckIgnore("ts-loader", "named as a loader string in `scripts/webpack.config.ts`.").addPartial("cli-bundler");
|
|
268
276
|
}
|
|
269
277
|
};
|
|
270
278
|
|
|
@@ -275,31 +283,40 @@ async function promptBundler(savedValue) {
|
|
|
275
283
|
}
|
|
276
284
|
|
|
277
285
|
// src/features/git-hooks.ts
|
|
286
|
+
var INITIAL_COMMIT_MESSAGE = "chore: initial commit from create-obsidian-plugin";
|
|
278
287
|
function addHusky(builder) {
|
|
279
288
|
builder.addPackage("husky").addDepcheckIgnore("husky", "run as a CLI by `scripts/prepare.ts`; the hooks in `.husky/` are its output.").addScript("prepare").addFiles(["scripts/prepare.ts"]);
|
|
280
289
|
}
|
|
281
|
-
function addStagedFilesHook(builder) {
|
|
290
|
+
function addStagedFilesHook(builder, preset) {
|
|
282
291
|
addHusky(builder);
|
|
292
|
+
builder.addPartial(usesToolkitNanoStagedConfig(preset) ? "toolkit-nano-staged" : "inline-nano-staged");
|
|
283
293
|
builder.addPackage("nano-staged").addDepcheckIgnore("nano-staged", "`.husky/pre-commit` runs it; configured by `scripts/nano-staged-config.ts`.").addFiles([
|
|
284
294
|
".husky/pre-commit",
|
|
285
295
|
".nano-staged.mjs",
|
|
286
296
|
"scripts/nano-staged-config.ts"
|
|
287
297
|
]);
|
|
288
298
|
}
|
|
299
|
+
function usesToolkitNanoStagedConfig(preset) {
|
|
300
|
+
return isFrameworkPreset(preset);
|
|
301
|
+
}
|
|
289
302
|
|
|
290
303
|
// src/features/commit-linting/conventional-commits.ts
|
|
291
304
|
var ConventionalCommits = class extends FeatureOption {
|
|
292
305
|
constructor() {
|
|
293
306
|
super({ promptHint: "commitlint + a husky commit-msg hook", promptLabel: "Conventional Commits", settingValue: "conventional-commits" });
|
|
294
307
|
}
|
|
295
|
-
configure(builder) {
|
|
308
|
+
configure(builder, answers) {
|
|
296
309
|
addHusky(builder);
|
|
297
|
-
builder.addPackage("@commitlint/cli").addDepcheckIgnore("@commitlint/cli", "`.husky/commit-msg` runs it as the `commitlint` binary.").addPackage("
|
|
310
|
+
builder.addPackage("@commitlint/cli").addDepcheckIgnore("@commitlint/cli", "`.husky/commit-msg` runs it as the `commitlint` binary.").addPackage("czg").addDepcheckIgnore("czg", "run as a CLI by `scripts/commit.ts`.").addScript("commit").addFiles([
|
|
298
311
|
"commitlint.config.ts",
|
|
299
312
|
"scripts/commit.ts",
|
|
300
313
|
"scripts/commitlint-config.ts",
|
|
301
314
|
".husky/commit-msg"
|
|
302
315
|
]);
|
|
316
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
builder.addPackage("@commitlint/config-conventional").addDepcheckIgnore("@commitlint/config-conventional", "extended by name (a string in the `extends` of `scripts/commitlint-config.ts`), never imported.").addPackage("@commitlint/types");
|
|
303
320
|
}
|
|
304
321
|
};
|
|
305
322
|
|
|
@@ -319,14 +336,24 @@ async function promptCommitLinting(savedValue) {
|
|
|
319
336
|
// src/features/coverage-badge/coverage-badge.ts
|
|
320
337
|
var CoverageBadge = class extends FeatureOption {
|
|
321
338
|
constructor() {
|
|
322
|
-
super({ promptHint:
|
|
339
|
+
super({ promptHint: "A coverage README badge, measured by CI where the project has one", promptLabel: "Coverage badge", settingValue: "coverage-badge" });
|
|
323
340
|
}
|
|
324
341
|
configure(builder, answers) {
|
|
325
|
-
|
|
326
|
-
|
|
342
|
+
const repoUrl = `https://github.com/${answers.authorGitHubName}/obsidian-${answers.pluginId}`;
|
|
343
|
+
if (!isMeasured(answers)) {
|
|
344
|
+
builder.addBadge(`[](${repoUrl})`);
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
builder.addPartial("measured-coverage-badge").addBadge(
|
|
348
|
+
`[](${repoUrl}/actions/workflows/ci.yml)`
|
|
327
349
|
);
|
|
328
350
|
}
|
|
329
351
|
};
|
|
352
|
+
var CI_ANSWERS = /* @__PURE__ */ new Set(["ci", "ci-and-release"]);
|
|
353
|
+
var MEASURING_TEST_RUNNERS = /* @__PURE__ */ new Set(["jest", "vitest"]);
|
|
354
|
+
function isMeasured(answers) {
|
|
355
|
+
return isFrameworkPreset(answers.preset) && CI_ANSWERS.has(answers.gitHubActions) && MEASURING_TEST_RUNNERS.has(answers.testRunner);
|
|
356
|
+
}
|
|
330
357
|
|
|
331
358
|
// src/features/coverage-badge/none.ts
|
|
332
359
|
var None2 = class extends FeatureOption {
|
|
@@ -366,12 +393,16 @@ var WdioObsidian = class extends FeatureOption {
|
|
|
366
393
|
constructor() {
|
|
367
394
|
super({ promptHint: "WebdriverIO service for Obsidian, multi-version & CI/CD", promptLabel: "wdio-obsidian", settingValue: "wdio-obsidian" });
|
|
368
395
|
}
|
|
369
|
-
configure(builder) {
|
|
370
|
-
builder.addPackage("@wdio/cli").addDepcheckIgnore("@wdio/cli", "run as the `wdio` CLI by `scripts/test-e2e.ts`.").addPackage("@wdio/globals").addPackage("@wdio/mocha-framework").addPackage("expect-webdriverio").addPackage("wdio-obsidian-service").addScript("test:e2e").addFiles([
|
|
371
|
-
"wdio.conf.ts",
|
|
396
|
+
configure(builder, answers) {
|
|
397
|
+
builder.addPackage("@wdio/cli").addDepcheckIgnore("@wdio/cli", "run as the `wdio` CLI by `scripts/test-e2e.ts`.").addPackage("@wdio/globals").addPackage("@wdio/local-runner").addDepcheckIgnore("@wdio/local-runner", "loaded by name by wdio for the config's `runner: 'local'`.").addPackage("@wdio/mocha-framework").addPackage("expect-webdriverio").addPackage("wdio-obsidian-service").addScript("test:e2e").addFiles([
|
|
372
398
|
"e2e/sample.spec.ts",
|
|
373
399
|
"scripts/test-e2e.ts"
|
|
374
400
|
]).addPartial("has-e2e");
|
|
401
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
402
|
+
builder.addPackage("wdio-obsidian-reporter").addDepcheckIgnore("wdio-obsidian-reporter", "loaded by name by wdio for the `obsidian` reporter `defineWdioObsidianConfig` names.").addFiles(["wdio.conf.mts"]);
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
builder.addFiles(["wdio.conf.ts"]);
|
|
375
406
|
}
|
|
376
407
|
};
|
|
377
408
|
|
|
@@ -452,14 +483,16 @@ var Prettier = class extends FeatureOption {
|
|
|
452
483
|
constructor() {
|
|
453
484
|
super({ promptHint: "Opinionated, widely adopted", promptLabel: "Prettier", settingValue: "prettier" });
|
|
454
485
|
}
|
|
455
|
-
configure(builder) {
|
|
486
|
+
configure(builder, answers) {
|
|
456
487
|
builder.addLintStagedCommand("*.{ts,tsx,mts}", "prettier --write").addPackage("prettier").addScript("format").addScript("format:check").addFiles([
|
|
457
488
|
".prettierignore",
|
|
458
489
|
"prettier.config.mjs",
|
|
459
|
-
"scripts/prettier.config.ts",
|
|
460
490
|
"scripts/format.ts",
|
|
461
491
|
"scripts/format-check.ts"
|
|
462
492
|
]);
|
|
493
|
+
if (!isFrameworkPreset(answers.preset)) {
|
|
494
|
+
builder.addFiles(["scripts/prettier.config.ts"]);
|
|
495
|
+
}
|
|
463
496
|
}
|
|
464
497
|
};
|
|
465
498
|
|
|
@@ -806,6 +839,11 @@ var None9 = class extends FeatureOption {
|
|
|
806
839
|
constructor() {
|
|
807
840
|
super({ promptHint: "No hot reload support", promptLabel: "(none)", settingValue: "none" });
|
|
808
841
|
}
|
|
842
|
+
configure(builder, answers) {
|
|
843
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
844
|
+
builder.addBuildOption("reload", "false");
|
|
845
|
+
}
|
|
846
|
+
}
|
|
809
847
|
};
|
|
810
848
|
|
|
811
849
|
// src/features/hot-reload/obsidian-cli.ts
|
|
@@ -813,6 +851,11 @@ var ObsidianCli = class extends FeatureOption {
|
|
|
813
851
|
constructor() {
|
|
814
852
|
super({ promptHint: "Reloads via obsidian plugin:reload CLI command", promptLabel: "Obsidian CLI", settingValue: "obsidian-cli" });
|
|
815
853
|
}
|
|
854
|
+
configure(builder, answers) {
|
|
855
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
856
|
+
builder.addBuildOption("reload", "'obsidian-cli'");
|
|
857
|
+
}
|
|
858
|
+
}
|
|
816
859
|
};
|
|
817
860
|
|
|
818
861
|
// src/features/hot-reload/index.ts
|
|
@@ -889,7 +932,7 @@ var Eslint = class extends FeatureOption {
|
|
|
889
932
|
"scripts/lint.ts",
|
|
890
933
|
"scripts/lint-fix.ts"
|
|
891
934
|
]);
|
|
892
|
-
if (
|
|
935
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
893
936
|
builder.addDepcheckIgnore("typescript-eslint", "imported by nothing here -- the shared config brings its own -- but the `typescript` pin's check reads its `package.json` for the peer range.").addFiles(["scripts/eslint-config.ts"]);
|
|
894
937
|
return;
|
|
895
938
|
}
|
|
@@ -918,7 +961,7 @@ var Markdownlint = class extends FeatureOption {
|
|
|
918
961
|
configure(builder, answers) {
|
|
919
962
|
builder.addLintStagedCommand("*.md", "markdownlint-cli2 --fix").addPackage("markdownlint-cli2").addDepcheckIgnore("markdownlint-cli2", "run as a CLI by the `lint:md` scripts, configured by `.markdownlint-cli2.mjs`.").addPackage("linkinator").addDepcheckIgnore("linkinator", "run as a CLI by the `lint:md` scripts.").addScript("lint:md").addScript("lint:md:fix").addFiles([
|
|
920
963
|
// `markdownlint-cli2` only discovers a config named `.markdownlint-cli2.{jsonc,yaml,cjs,mjs}`, and
|
|
921
|
-
// So does
|
|
964
|
+
// So does the toolkit's runner -- which copies its own `.mjs` in when it finds none, pointing
|
|
922
965
|
// At a `scripts/markdownlint-cli2-config.ts` that then has to exist. Hence this shape rather than a
|
|
923
966
|
// Single `.mts` that nothing reads.
|
|
924
967
|
".markdownlint-cli2.mjs",
|
|
@@ -929,7 +972,7 @@ var Markdownlint = class extends FeatureOption {
|
|
|
929
972
|
// Repository, which 404 until the user pushes it.
|
|
930
973
|
"linkinator.config.json"
|
|
931
974
|
]);
|
|
932
|
-
if (
|
|
975
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
933
976
|
return;
|
|
934
977
|
}
|
|
935
978
|
builder.addPackage("markdownlint").addPackage("markdownlint-rule-relative-links");
|
|
@@ -1032,17 +1075,17 @@ var DEMO_VAULT_TEMPLATE_FILES = [
|
|
|
1032
1075
|
"demo-vault/_assets/CodeScriptToolkit/startup.ts"
|
|
1033
1076
|
];
|
|
1034
1077
|
|
|
1035
|
-
// src/features/preset/
|
|
1036
|
-
var
|
|
1078
|
+
// src/features/preset/all-in-one.ts
|
|
1079
|
+
var AllInOne = class extends FeatureOption {
|
|
1037
1080
|
constructor() {
|
|
1038
|
-
super({
|
|
1081
|
+
super({
|
|
1082
|
+
promptHint: "Recommended. The author's framework: @mnaoumov/obsidian-lib, a library of ready-made helpers for settings, commands, modals, notices, file and link handling, and more, plus the @mnaoumov toolkits for building, linting, testing and releases",
|
|
1083
|
+
promptLabel: "All-in-one Framework",
|
|
1084
|
+
settingValue: "all-in-one"
|
|
1085
|
+
});
|
|
1039
1086
|
}
|
|
1040
|
-
configure(builder) {
|
|
1041
|
-
builder.addPackage("@tsconfig/strictest").addPackage("
|
|
1042
|
-
// Not gated on the gitHubActions answer, and deliberately so: this attests the assets of a
|
|
1043
|
-
// Published RELEASE, and the release flow is the preset's, not CI's. Every plugin compared here
|
|
1044
|
-
// Ships this workflow -- they have no ci.yml at all.
|
|
1045
|
-
".github/workflows/attest-release-assets.yml",
|
|
1087
|
+
configure(builder, answers) {
|
|
1088
|
+
builder.addPackage("@tsconfig/strictest").addPackage("@mnaoumov/obsidian-lib").addPackage("@mnaoumov/obsidian-dev-toolkit").addPackage("@mnaoumov/typescript-dev-toolkit").addPackage("obsidian-integration-testing").addScript("dev").addScript("build").addScript("build:clean").addScript("build:compile").addScript("find-overexposed").addScript("find-overexposed:fix").addScript("version").addScript("gate").addFiles([
|
|
1046
1089
|
// Not gated on the answers either: the shared ESLint config's `obsidianmd/validate-license` compares
|
|
1047
1090
|
// The LICENSE year with the current one, so without this bump every project turns red on 1 January.
|
|
1048
1091
|
".github/workflows/update-license-year.yml",
|
|
@@ -1054,28 +1097,24 @@ var Demo = class extends FeatureOption {
|
|
|
1054
1097
|
"scripts/dev.ts",
|
|
1055
1098
|
"scripts/gate.ts",
|
|
1056
1099
|
"scripts/version.ts",
|
|
1057
|
-
"src/modals/sample-form-modal.ts",
|
|
1058
|
-
"src/modals/sample-suggest-modal.ts",
|
|
1059
1100
|
"src/plugin-settings.ts",
|
|
1060
1101
|
"src/plugin-settings-component.ts",
|
|
1061
1102
|
"src/plugin-settings-tab.ts",
|
|
1062
|
-
"src/views/sample-view.ts",
|
|
1063
1103
|
...DEMO_VAULT_TEMPLATE_FILES
|
|
1064
|
-
]).addPartial("
|
|
1104
|
+
]).addPartial("framework");
|
|
1105
|
+
if (answers.gitHubActions !== "ci-and-release") {
|
|
1106
|
+
builder.addFiles([".github/workflows/attest-release-assets.yml"]);
|
|
1107
|
+
}
|
|
1065
1108
|
}
|
|
1066
1109
|
};
|
|
1067
1110
|
|
|
1068
|
-
// src/features/preset/
|
|
1069
|
-
var
|
|
1111
|
+
// src/features/preset/demo.ts
|
|
1112
|
+
var Demo = class extends FeatureOption {
|
|
1070
1113
|
constructor() {
|
|
1071
|
-
super({ promptHint: "
|
|
1114
|
+
super({ promptHint: "All features enabled for demonstration", promptLabel: "Demo", settingValue: "demo" });
|
|
1072
1115
|
}
|
|
1073
|
-
configure(builder) {
|
|
1074
|
-
builder.addPackage("@tsconfig/strictest").addPackage("obsidian-dev-
|
|
1075
|
-
// Not gated on the gitHubActions answer, and deliberately so: this attests the assets of a
|
|
1076
|
-
// Published RELEASE, and the release flow is the preset's, not CI's. Every plugin compared here
|
|
1077
|
-
// Ships this workflow -- they have no ci.yml at all.
|
|
1078
|
-
".github/workflows/attest-release-assets.yml",
|
|
1116
|
+
configure(builder, answers) {
|
|
1117
|
+
builder.addPackage("@tsconfig/strictest").addPackage("moment").addDepcheckIgnore("moment", "imported through `obsidian` rather than directly, and the typings of `obsidian` resolve it by name.").addPackage("@mnaoumov/obsidian-lib").addPackage("@mnaoumov/typescript-lib").addPackage("@mnaoumov/obsidian-dev-toolkit").addPackage("@mnaoumov/typescript-dev-toolkit").addPackage("obsidian-integration-testing").addScript("dev").addScript("build").addScript("build:clean").addScript("build:compile").addScript("find-overexposed").addScript("find-overexposed:fix").addScript("version").addScript("gate").addFiles([
|
|
1079
1118
|
// Not gated on the answers either: the shared ESLint config's `obsidianmd/validate-license` compares
|
|
1080
1119
|
// The LICENSE year with the current one, so without this bump every project turns red on 1 January.
|
|
1081
1120
|
".github/workflows/update-license-year.yml",
|
|
@@ -1087,18 +1126,70 @@ var Enhanced = class extends FeatureOption {
|
|
|
1087
1126
|
"scripts/dev.ts",
|
|
1088
1127
|
"scripts/gate.ts",
|
|
1089
1128
|
"scripts/version.ts",
|
|
1129
|
+
"src/modals/sample-form-modal.ts",
|
|
1130
|
+
"src/modals/sample-suggest-modal.ts",
|
|
1090
1131
|
"src/plugin-settings.ts",
|
|
1091
1132
|
"src/plugin-settings-component.ts",
|
|
1092
1133
|
"src/plugin-settings-tab.ts",
|
|
1134
|
+
"src/views/sample-view.ts",
|
|
1093
1135
|
...DEMO_VAULT_TEMPLATE_FILES
|
|
1094
|
-
]).addPartial("
|
|
1136
|
+
]).addPartial("framework");
|
|
1137
|
+
if (answers.gitHubActions !== "ci-and-release") {
|
|
1138
|
+
builder.addFiles([".github/workflows/attest-release-assets.yml"]);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
};
|
|
1142
|
+
|
|
1143
|
+
// src/features/preset/docs-showcase.ts
|
|
1144
|
+
var DOCS_SHOWCASE_PRESET = "docs-showcase";
|
|
1145
|
+
var DocsShowcase = class extends FeatureOption {
|
|
1146
|
+
constructor() {
|
|
1147
|
+
super({
|
|
1148
|
+
promptHint: "The All-in-one Framework project, plus every code block of the Obsidian developer docs as a command you can run",
|
|
1149
|
+
promptLabel: "Developer docs showcase",
|
|
1150
|
+
settingValue: DOCS_SHOWCASE_PRESET
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
configure(builder, answers) {
|
|
1154
|
+
new AllInOne().configure(builder, answers);
|
|
1155
|
+
builder.addPartial("all-in-one").addPackage("@codemirror/language").addPackage("@codemirror/state").addPackage("@codemirror/view").addScript("build:compile:typescript").addFiles(["scripts/build-compile-typescript.ts"]);
|
|
1156
|
+
if (answers.testRunner === "vitest") {
|
|
1157
|
+
builder.addFiles(["src/docs-showcase.desktop.integration.test.ts"]);
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
};
|
|
1161
|
+
|
|
1162
|
+
// src/features/preset/official-sample.ts
|
|
1163
|
+
var OFFICIAL_SAMPLE_PRESET = "official-sample";
|
|
1164
|
+
var OFFICIAL_SAMPLE_ANSWER_KEYS = [
|
|
1165
|
+
"authorGitHubName",
|
|
1166
|
+
"authorName",
|
|
1167
|
+
"defaultBranch",
|
|
1168
|
+
"fundingPlatform",
|
|
1169
|
+
"fundingUrl",
|
|
1170
|
+
"fundingUsername",
|
|
1171
|
+
"pluginDescription",
|
|
1172
|
+
"pluginId",
|
|
1173
|
+
"pluginName",
|
|
1174
|
+
"preset"
|
|
1175
|
+
];
|
|
1176
|
+
var OfficialSample = class extends FeatureOption {
|
|
1177
|
+
constructor() {
|
|
1178
|
+
super({
|
|
1179
|
+
promptHint: "Exactly obsidianmd/obsidian-sample-plugin, with your plugin's id, name, author and description filled in",
|
|
1180
|
+
promptLabel: "Official sample plugin",
|
|
1181
|
+
settingValue: OFFICIAL_SAMPLE_PRESET
|
|
1182
|
+
});
|
|
1095
1183
|
}
|
|
1096
1184
|
};
|
|
1185
|
+
function isOfficialSamplePreset(preset) {
|
|
1186
|
+
return preset === OFFICIAL_SAMPLE_PRESET;
|
|
1187
|
+
}
|
|
1097
1188
|
|
|
1098
1189
|
// src/features/preset/standalone.ts
|
|
1099
1190
|
var Standalone = class extends FeatureOption {
|
|
1100
1191
|
constructor() {
|
|
1101
|
-
super({ promptHint: "Standalone plugin without
|
|
1192
|
+
super({ promptHint: "Standalone plugin without the @mnaoumov library dependencies", promptLabel: "Standalone", settingValue: "standalone" });
|
|
1102
1193
|
}
|
|
1103
1194
|
configure(builder) {
|
|
1104
1195
|
builder.addScript("dev").addScript("build").addScript("version").addFiles([
|
|
@@ -1111,9 +1202,10 @@ var Standalone = class extends FeatureOption {
|
|
|
1111
1202
|
};
|
|
1112
1203
|
|
|
1113
1204
|
// src/features/preset/index.ts
|
|
1114
|
-
var PRESET_OPTIONS = [new Demo(), new
|
|
1205
|
+
var PRESET_OPTIONS = [new AllInOne(), new Demo(), new DocsShowcase(), new Standalone()];
|
|
1206
|
+
var PRESET_PROMPT_OPTIONS = [...PRESET_OPTIONS, new OfficialSample()];
|
|
1115
1207
|
async function promptPreset(savedValue) {
|
|
1116
|
-
return promptFeature({ defaultOption: new
|
|
1208
|
+
return promptFeature({ defaultOption: new AllInOne(), message: "Choose a preset", options: PRESET_PROMPT_OPTIONS, savedValue });
|
|
1117
1209
|
}
|
|
1118
1210
|
|
|
1119
1211
|
// src/features/spell-checker/cspell.ts
|
|
@@ -1142,16 +1234,25 @@ async function promptSpellChecker(savedValue) {
|
|
|
1142
1234
|
return promptFeature({ defaultOption: new Cspell(), message: "Spell checker", options: SPELL_CHECKER_OPTIONS, savedValue });
|
|
1143
1235
|
}
|
|
1144
1236
|
|
|
1237
|
+
// src/features/styling/toolkit-styles.ts
|
|
1238
|
+
function addToolkitStyles(builder, bundler, flag) {
|
|
1239
|
+
builder.addBuildStyles(flag).addPartial("toolkit-styles");
|
|
1240
|
+
if (bundler === "webpack") {
|
|
1241
|
+
builder.addPackage("css-loader").addDepcheckIgnore("css-loader", "resolved by name by obsidian-dev-toolkit's webpack plugin for the stylesheet rule.").addPackage("mini-css-extract-plugin").addDepcheckIgnore("mini-css-extract-plugin", "applied by obsidian-dev-toolkit's webpack plugin to extract `styles.css`.");
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1145
1245
|
// src/features/styling/css-modules.ts
|
|
1146
1246
|
var CssModules = class extends FeatureOption {
|
|
1147
1247
|
constructor() {
|
|
1148
1248
|
super({ promptHint: "Scoped CSS with .module.css files", promptLabel: "CSS Modules", settingValue: "css-modules" });
|
|
1149
1249
|
}
|
|
1150
1250
|
configure(builder, answers) {
|
|
1151
|
-
builder.addFiles([
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1251
|
+
builder.addFiles(["src/styles/css-modules.d.ts", "src/styles/main.module.css", "src/styles/sample-css-module-command.ts"]);
|
|
1252
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
1253
|
+
addToolkitStyles(builder, answers.bundler, "cssModules");
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1155
1256
|
if (answers.bundler === "rollup") {
|
|
1156
1257
|
builder.addPackage("rollup-plugin-postcss").addPartial("rollup-postcss");
|
|
1157
1258
|
}
|
|
@@ -1167,7 +1268,12 @@ var Css = class extends FeatureOption {
|
|
|
1167
1268
|
super({ promptHint: "Plain CSS styles", promptLabel: "CSS", settingValue: "css" });
|
|
1168
1269
|
}
|
|
1169
1270
|
configure(builder, answers) {
|
|
1170
|
-
builder.addFiles(["src/styles/main.css"
|
|
1271
|
+
builder.addFiles(["src/styles/main.css"]);
|
|
1272
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
1273
|
+
addToolkitStyles(builder, answers.bundler);
|
|
1274
|
+
return;
|
|
1275
|
+
}
|
|
1276
|
+
builder.addFiles(["src/styles/styles.d.ts"]);
|
|
1171
1277
|
if (answers.bundler === "rollup") {
|
|
1172
1278
|
builder.addPackage("rollup-plugin-postcss").addPartial("rollup-postcss");
|
|
1173
1279
|
}
|
|
@@ -1193,9 +1299,13 @@ var PostCss = class extends FeatureOption {
|
|
|
1193
1299
|
builder.addPackage("autoprefixer").addPackage("postcss").addFiles([
|
|
1194
1300
|
"postcss.config.cjs",
|
|
1195
1301
|
"scripts/postcss.config.ts",
|
|
1196
|
-
"src/styles/main.css"
|
|
1197
|
-
"src/styles/styles.d.ts"
|
|
1302
|
+
"src/styles/main.css"
|
|
1198
1303
|
]);
|
|
1304
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
1305
|
+
addToolkitStyles(builder, answers.bundler, "postcss");
|
|
1306
|
+
return;
|
|
1307
|
+
}
|
|
1308
|
+
builder.addFiles(["src/styles/styles.d.ts"]);
|
|
1199
1309
|
if (answers.bundler === "esbuild") {
|
|
1200
1310
|
builder.addPackage("esbuild-postcss");
|
|
1201
1311
|
}
|
|
@@ -1226,8 +1336,13 @@ var Scss = class extends FeatureOption {
|
|
|
1226
1336
|
super({ promptHint: "Sass/SCSS preprocessor", promptLabel: "SCSS", settingValue: "scss" });
|
|
1227
1337
|
}
|
|
1228
1338
|
configure(builder, answers) {
|
|
1229
|
-
builder.addFiles(["src/styles/main.scss"
|
|
1230
|
-
|
|
1339
|
+
builder.addFiles(["src/styles/main.scss"]);
|
|
1340
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
1341
|
+
builder.addPartial("toolkit-styles");
|
|
1342
|
+
} else {
|
|
1343
|
+
builder.addFiles(["src/styles/styles.d.ts"]);
|
|
1344
|
+
}
|
|
1345
|
+
const plugin = isFrameworkPreset(answers.preset) && answers.bundler === "esbuild" ? void 0 : SCSS_PLUGINS[answers.bundler];
|
|
1231
1346
|
if (plugin) {
|
|
1232
1347
|
builder.addPackage(plugin);
|
|
1233
1348
|
const depcheckReason = SCSS_PLUGIN_DEPCHECK_REASONS[answers.bundler];
|
|
@@ -1239,7 +1354,10 @@ var Scss = class extends FeatureOption {
|
|
|
1239
1354
|
builder.addPackage("sass-embedded").addDepcheckIgnore("sass-embedded", "the Sass compiler `esbuild-sass-plugin` peers on; nothing imports it directly.");
|
|
1240
1355
|
}
|
|
1241
1356
|
if (answers.bundler === "webpack") {
|
|
1242
|
-
builder.addPackage("css-loader").addDepcheckIgnore("css-loader", "named as a loader string in `scripts/webpack.config.ts`.").addPackage("mini-css-extract-plugin").addPackage("sass").addDepcheckIgnore("sass", "the Sass compiler `sass-loader` resolves by name; nothing imports it directly.")
|
|
1357
|
+
builder.addPackage("css-loader").addDepcheckIgnore("css-loader", "named as a loader string in `scripts/webpack.config.ts`.").addPackage("mini-css-extract-plugin").addPackage("sass").addDepcheckIgnore("sass", "the Sass compiler `sass-loader` resolves by name; nothing imports it directly.");
|
|
1358
|
+
if (!isFrameworkPreset(answers.preset)) {
|
|
1359
|
+
builder.addPartial("webpack-css-extract");
|
|
1360
|
+
}
|
|
1243
1361
|
}
|
|
1244
1362
|
}
|
|
1245
1363
|
};
|
|
@@ -1250,11 +1368,16 @@ var Tailwind = class extends FeatureOption {
|
|
|
1250
1368
|
super({ promptHint: "Utility-first CSS framework", promptLabel: "Tailwind CSS", settingValue: "tailwind" });
|
|
1251
1369
|
}
|
|
1252
1370
|
configure(builder, answers) {
|
|
1253
|
-
builder.addPackage("
|
|
1371
|
+
builder.addPackage("tailwindcss").addDepcheckIgnore("tailwindcss", 'imported by `src/styles/main.css` (`@import "tailwindcss"`), which depcheck does not read.').addFiles(["src/styles/main.css"]);
|
|
1372
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
1373
|
+
builder.addPackage("@tailwindcss/postcss").addDepcheckIgnore("@tailwindcss/postcss", "loaded by obsidian-dev-toolkit for its `styles.tailwind` build option.");
|
|
1374
|
+
addToolkitStyles(builder, answers.bundler, "tailwind");
|
|
1375
|
+
return;
|
|
1376
|
+
}
|
|
1377
|
+
builder.addPackage("@tailwindcss/cli").addDepcheckIgnore("@tailwindcss/cli", "run as a CLI by `scripts/build-styles.ts`.").addScript("build:styles").addFiles([
|
|
1254
1378
|
"scripts/build-styles.ts",
|
|
1255
|
-
"src/styles/main.css",
|
|
1256
1379
|
"src/styles/styles.d.ts"
|
|
1257
|
-
]);
|
|
1380
|
+
]).addPartial("tailwind-cli");
|
|
1258
1381
|
if (answers.bundler === "rollup") {
|
|
1259
1382
|
builder.addPackage("rollup-plugin-postcss").addPartial("rollup-postcss");
|
|
1260
1383
|
}
|
|
@@ -1273,12 +1396,12 @@ async function promptStyling(savedValue) {
|
|
|
1273
1396
|
// src/features/test-runner/sample-unit-tests.ts
|
|
1274
1397
|
function addSampleUnitTests(builder, answers) {
|
|
1275
1398
|
builder.addFiles(["src/main.test.ts"]);
|
|
1276
|
-
if (!
|
|
1399
|
+
if (!isFrameworkPreset(answers.preset)) {
|
|
1277
1400
|
return;
|
|
1278
1401
|
}
|
|
1279
|
-
builder.addFiles(["src/plugin-settings-component.test.ts"]);
|
|
1402
|
+
builder.addFiles(["src/plugin-settings-component.test.ts"]).addPackage("@mnaoumov/typescript-lib");
|
|
1280
1403
|
if (answers.preset === "demo") {
|
|
1281
|
-
builder.addFiles(["src/plugin-settings.test.ts"]);
|
|
1404
|
+
builder.addFiles(["src/plugin-settings.test.ts"]).addPackage("@mnaoumov/typescript-test-toolkit");
|
|
1282
1405
|
}
|
|
1283
1406
|
}
|
|
1284
1407
|
|
|
@@ -1288,7 +1411,9 @@ var Jest = class extends FeatureOption {
|
|
|
1288
1411
|
super({ promptHint: "Feature-rich, widely adopted", promptLabel: "Jest", settingValue: "jest" });
|
|
1289
1412
|
}
|
|
1290
1413
|
configure(builder, answers) {
|
|
1291
|
-
|
|
1414
|
+
const isFramework = isFrameworkPreset(answers.preset);
|
|
1415
|
+
const configNames = isFramework ? "`defineObsidianPluginJestConfig` from @mnaoumov/obsidian-dev-toolkit" : "`jest.config.ts`";
|
|
1416
|
+
builder.addPackage("@types/jest").addPackage("jest").addPackage("jest-environment-jsdom").addDepcheckIgnore("jest-environment-jsdom", `named by \`testEnvironment\` in ${configNames}, never imported.`).addPackage("obsidian-test-mocks").addPackage("ts-jest").addDepcheckIgnore("ts-jest", `named as the TypeScript transform by ${configNames}, never imported.`).addScript("test").addScript("test:watch").addFiles([
|
|
1292
1417
|
"jest.config.ts",
|
|
1293
1418
|
"scripts/framework-component-stub.ts",
|
|
1294
1419
|
"scripts/stylesheet-stub.ts",
|
|
@@ -1297,6 +1422,9 @@ var Jest = class extends FeatureOption {
|
|
|
1297
1422
|
"scripts/test.ts",
|
|
1298
1423
|
"scripts/test-watch.ts"
|
|
1299
1424
|
]);
|
|
1425
|
+
if (isFramework) {
|
|
1426
|
+
builder.addDepcheckIgnore("obsidian-test-mocks", "mapped onto `obsidian` and loaded as a setup file by name by `defineObsidianPluginJestConfig` from @mnaoumov/obsidian-dev-toolkit.").addPackage("@jest/globals").addDepcheckIgnore("@jest/globals", "imported by `@mnaoumov/obsidian-dev-toolkit/jest-setup`, which `defineObsidianPluginJestConfig` loads.").addScript("test:coverage").addFiles(["scripts/test-coverage.ts"]);
|
|
1427
|
+
}
|
|
1300
1428
|
addSampleUnitTests(builder, answers);
|
|
1301
1429
|
}
|
|
1302
1430
|
};
|
|
@@ -1316,23 +1444,23 @@ var Vitest = class extends FeatureOption {
|
|
|
1316
1444
|
configure(builder, answers) {
|
|
1317
1445
|
builder.addPackage("jsdom").addPackage("obsidian-test-mocks").addDepcheckIgnore(
|
|
1318
1446
|
"obsidian-test-mocks",
|
|
1319
|
-
|
|
1447
|
+
isFrameworkPreset(answers.preset) ? "aliased and loaded as a setup file by name by `defineObsidianPluginVitestConfig` from @mnaoumov/obsidian-dev-toolkit." : "aliased and loaded as a setup file by name in `vitest.config.ts`."
|
|
1320
1448
|
).addPackage("vitest").addScript("test").addScript("test:watch").addFiles([
|
|
1321
1449
|
"vitest.config.ts",
|
|
1322
1450
|
"src/plugin.test.ts",
|
|
1323
1451
|
"scripts/test.ts",
|
|
1324
1452
|
"scripts/test-watch.ts",
|
|
1325
|
-
// Both presets, not just the
|
|
1326
|
-
// On every preset when the `wasm` answer is chosen,
|
|
1327
|
-
//
|
|
1328
|
-
// Reaches a single-file component.
|
|
1453
|
+
// Both presets, not just the framework ones: the emitted `src/plugin.ts` reaches `src/wasm/answer.ts`
|
|
1454
|
+
// On every preset when the `wasm` answer is chosen, and registers the answered view, which may be a
|
|
1455
|
+
// Single-file component. So every vitest config aliases `.wasm` and `.svelte` / `.vue` to these stubs.
|
|
1329
1456
|
"scripts/wasm-module-stub.ts",
|
|
1457
|
+
"scripts/framework-component-stub.ts",
|
|
1330
1458
|
// `src/main.test.ts` imports `src/main.ts`, which imports the stylesheet -- and on `tailwind` that
|
|
1331
1459
|
// File does not exist until the first build. See the stub's own comment.
|
|
1332
1460
|
"scripts/stylesheet-stub.ts"
|
|
1333
1461
|
]);
|
|
1334
1462
|
addSampleUnitTests(builder, answers);
|
|
1335
|
-
if (!
|
|
1463
|
+
if (!isFrameworkPreset(answers.preset)) {
|
|
1336
1464
|
return;
|
|
1337
1465
|
}
|
|
1338
1466
|
builder.addPackage("@vitest/coverage-v8").addScript("test:coverage").addScript("test:integration").addScript("test:integration:android").addScript("test:integration:demo-vault").addScript("test:integration:desktop").addScript("test:integration:desktop:performance").addScript("test:integration:no-app").addFiles([
|
|
@@ -1340,7 +1468,6 @@ var Vitest = class extends FeatureOption {
|
|
|
1340
1468
|
"scripts/test-integration-desktop.ts",
|
|
1341
1469
|
"scripts/test-integration-desktop-performance.ts",
|
|
1342
1470
|
"scripts/demo-vault-global-setup.ts",
|
|
1343
|
-
"scripts/framework-component-stub.ts",
|
|
1344
1471
|
"scripts/test-coverage.ts",
|
|
1345
1472
|
"scripts/test-integration.ts",
|
|
1346
1473
|
"scripts/test-integration-demo-vault.ts",
|
|
@@ -1392,6 +1519,10 @@ var Preact = class extends FeatureOption {
|
|
|
1392
1519
|
"src/preact-components/sample-preact-component.tsx",
|
|
1393
1520
|
"src/views/sample-preact-view.tsx"
|
|
1394
1521
|
]);
|
|
1522
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
1523
|
+
builder.addBuildFramework("preact").addTsconfigExtends("@mnaoumov/obsidian-dev-toolkit/tsconfig/preact.json");
|
|
1524
|
+
return;
|
|
1525
|
+
}
|
|
1395
1526
|
const plugin = BUILD_PLUGINS[answers.bundler];
|
|
1396
1527
|
if (plugin) {
|
|
1397
1528
|
builder.addPackage(plugin);
|
|
@@ -1419,6 +1550,10 @@ var React = class extends FeatureOption {
|
|
|
1419
1550
|
"src/react-components/sample-react-component.tsx",
|
|
1420
1551
|
"src/views/sample-react-view.tsx"
|
|
1421
1552
|
]);
|
|
1553
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
1554
|
+
builder.addBuildFramework("react").addTsconfigExtends("@mnaoumov/obsidian-dev-toolkit/tsconfig/react.json");
|
|
1555
|
+
return;
|
|
1556
|
+
}
|
|
1422
1557
|
const plugin = BUILD_PLUGINS2[answers.bundler];
|
|
1423
1558
|
if (plugin) {
|
|
1424
1559
|
builder.addPackage(plugin);
|
|
@@ -1446,6 +1581,10 @@ var Solid = class extends FeatureOption {
|
|
|
1446
1581
|
"src/solid-components/sample-solid-component.tsx",
|
|
1447
1582
|
"src/views/sample-solid-view.tsx"
|
|
1448
1583
|
]);
|
|
1584
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
1585
|
+
builder.addBuildFramework("solid").addTsconfigExtends("@mnaoumov/obsidian-dev-toolkit/tsconfig/solid.json").addPackage("@babel/core").addDepcheckIgnore("@babel/core", "loaded by obsidian-dev-toolkit to compile Solid's JSX.").addPackage("babel-preset-solid").addDepcheckIgnore("babel-preset-solid", "loaded by obsidian-dev-toolkit to compile Solid's JSX.");
|
|
1586
|
+
return;
|
|
1587
|
+
}
|
|
1449
1588
|
const plugin = BUILD_PLUGINS3[answers.bundler];
|
|
1450
1589
|
if (plugin) {
|
|
1451
1590
|
builder.addPackage(plugin);
|
|
@@ -1487,16 +1626,17 @@ var Svelte = class extends FeatureOption {
|
|
|
1487
1626
|
"src/svelte-components/sample-svelte-component.svelte",
|
|
1488
1627
|
"src/views/sample-svelte-view.ts"
|
|
1489
1628
|
]);
|
|
1490
|
-
|
|
1629
|
+
builder.addPackage("svelte-check");
|
|
1630
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
1631
|
+
builder.addBuildFramework("svelte").addTsconfigExtends("@mnaoumov/obsidian-dev-toolkit/tsconfig/svelte.json").addDepcheckIgnore("svelte-check", "run as a CLI by typescript-dev-toolkit's `build:compile`, which refuses to build without it declared.");
|
|
1632
|
+
return;
|
|
1633
|
+
}
|
|
1491
1634
|
const plugin = getBuildPlugin(answers.bundler);
|
|
1492
|
-
if (plugin !== null
|
|
1635
|
+
if (plugin !== null) {
|
|
1493
1636
|
builder.addPackage(plugin);
|
|
1494
1637
|
}
|
|
1495
|
-
builder.
|
|
1496
|
-
|
|
1497
|
-
isDevUtilsEsbuild ? "run as a CLI by obsidian-dev-utils' `build:compile`, which refuses to build without it declared." : "run as a CLI by `scripts/build.ts`."
|
|
1498
|
-
);
|
|
1499
|
-
if (!isDevUtilsEsbuild && SVELTE_PREPROCESS_BUNDLERS.has(answers.bundler)) {
|
|
1638
|
+
builder.addDepcheckIgnore("svelte-check", "run as a CLI by `scripts/build.ts`.");
|
|
1639
|
+
if (SVELTE_PREPROCESS_BUNDLERS.has(answers.bundler)) {
|
|
1500
1640
|
builder.addPackage("svelte-preprocess");
|
|
1501
1641
|
}
|
|
1502
1642
|
if (answers.bundler === "webpack") {
|
|
@@ -1527,11 +1667,19 @@ var Vue = class extends FeatureOption {
|
|
|
1527
1667
|
super({ promptHint: "Progressive framework with SFC", promptLabel: "Vue", settingValue: "vue" });
|
|
1528
1668
|
}
|
|
1529
1669
|
configure(builder, answers) {
|
|
1530
|
-
builder.addPackage("vue").
|
|
1670
|
+
builder.addPackage("vue").addPartial("ui-view").addSentenceCaseBrand("Vue").addFiles([
|
|
1531
1671
|
"src/vue-components/sample-vue-component.d.ts",
|
|
1532
1672
|
"src/vue-components/sample-vue-component.vue",
|
|
1533
1673
|
"src/views/sample-vue-view.ts"
|
|
1534
1674
|
]);
|
|
1675
|
+
if (isFrameworkPreset(answers.preset)) {
|
|
1676
|
+
builder.addBuildFramework("vue").addPackage("unplugin-vue").addDepcheckIgnore("unplugin-vue", "loaded by obsidian-dev-toolkit to compile `.vue` components.");
|
|
1677
|
+
if (answers.bundler === "parcel") {
|
|
1678
|
+
builder.addPackage("@parcel/transformer-vue").addDepcheckIgnore("@parcel/transformer-vue", "resolved by name by `@parcel/config-default` for `.vue`; nothing imports it.");
|
|
1679
|
+
}
|
|
1680
|
+
return;
|
|
1681
|
+
}
|
|
1682
|
+
builder.addPackage(getBuildPlugin2(answers.bundler));
|
|
1535
1683
|
if (answers.bundler === "rollup") {
|
|
1536
1684
|
builder.addPackage("@babel/core").addPackage("@babel/preset-typescript").addPackage("@rollup/plugin-babel").addDepcheckIgnore("@babel/preset-typescript", "named as a string in `scripts/rollup.config.ts`, never imported.").addPartial("rollup-babel");
|
|
1537
1685
|
}
|
|
@@ -1574,24 +1722,29 @@ var Wasm = class extends FeatureOption {
|
|
|
1574
1722
|
super({ promptHint: "Import and use .wasm modules", promptLabel: "WASM", settingValue: "wasm" });
|
|
1575
1723
|
}
|
|
1576
1724
|
configure(builder, answers) {
|
|
1577
|
-
const
|
|
1578
|
-
if (
|
|
1579
|
-
builder.
|
|
1725
|
+
const isFramework = isFrameworkPreset(answers.preset);
|
|
1726
|
+
if (isFramework) {
|
|
1727
|
+
builder.addBuildOption("wasm", "true").addPartial("wasm-adapter");
|
|
1728
|
+
} else {
|
|
1729
|
+
const plugin = getWasmPlugin(answers.bundler);
|
|
1730
|
+
if (plugin !== null) {
|
|
1731
|
+
builder.addPackage(plugin);
|
|
1732
|
+
}
|
|
1733
|
+
builder.addFiles(["src/wasm.d.ts"]).addPartial(`wasm-${answers.bundler}`);
|
|
1580
1734
|
}
|
|
1581
1735
|
builder.addSentenceCaseBrand("WASM");
|
|
1582
1736
|
builder.addFiles([
|
|
1583
1737
|
// The one binary in the template tree, copied verbatim (see `ASSET_EXTENSIONS`). 39 bytes, one
|
|
1584
|
-
// Export, `answer()`, returning 42 -- the sample module from CodeScript Toolkit's demo vault.
|
|
1738
|
+
// Export, `answer()`, returning 42 -- the sample module from `CodeScript Toolkit`'s demo vault.
|
|
1585
1739
|
"src/wasm/module.wasm",
|
|
1586
1740
|
// Its source in WebAssembly text format. Documentation only: nothing in the build reads it, and it
|
|
1587
1741
|
// Is here so the binary beside it is not opaque.
|
|
1588
1742
|
"src/wasm/module.wat",
|
|
1589
|
-
"src/wasm.d.ts",
|
|
1590
1743
|
"src/wasm/answer.ts",
|
|
1591
1744
|
"src/wasm/sample-command.ts",
|
|
1592
1745
|
"src/wasm/README.md"
|
|
1593
1746
|
]);
|
|
1594
|
-
if (
|
|
1747
|
+
if (isFramework) {
|
|
1595
1748
|
builder.addFiles(["demo-vault/03 WebAssembly.md"]);
|
|
1596
1749
|
}
|
|
1597
1750
|
}
|
|
@@ -1656,6 +1809,22 @@ function getPluginShortName(pluginId) {
|
|
|
1656
1809
|
return pluginId.split("-").map((word) => (word[0] ?? "").toUpperCase() + word.slice(1)).join("");
|
|
1657
1810
|
}
|
|
1658
1811
|
|
|
1812
|
+
// src/deprecated-answers.ts
|
|
1813
|
+
import { log } from "@clack/prompts";
|
|
1814
|
+
var DEPRECATED_ANSWER_VALUES = {
|
|
1815
|
+
preset: {
|
|
1816
|
+
enhanced: "all-in-one"
|
|
1817
|
+
}
|
|
1818
|
+
};
|
|
1819
|
+
function resolveDeprecatedAnswer(key, value, source) {
|
|
1820
|
+
const replacement = DEPRECATED_ANSWER_VALUES[key]?.[value];
|
|
1821
|
+
if (replacement === void 0) {
|
|
1822
|
+
return value;
|
|
1823
|
+
}
|
|
1824
|
+
log.warn(`${key} "${value}" in ${source} is deprecated and was read as "${replacement}". Use "${replacement}" instead.`);
|
|
1825
|
+
return replacement;
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1659
1828
|
// src/directory-constraints.ts
|
|
1660
1829
|
var CORE_FEATURE_NAMES = [
|
|
1661
1830
|
"Audio recorder",
|
|
@@ -1795,7 +1964,7 @@ function findCoreFeatureName(name) {
|
|
|
1795
1964
|
// src/prompts.ts
|
|
1796
1965
|
import {
|
|
1797
1966
|
cancel as cancel2,
|
|
1798
|
-
log
|
|
1967
|
+
log as log2
|
|
1799
1968
|
} from "@clack/prompts";
|
|
1800
1969
|
import { styleText as styleText3 } from "node:util";
|
|
1801
1970
|
|
|
@@ -1891,6 +2060,30 @@ ${barEnd}
|
|
|
1891
2060
|
}
|
|
1892
2061
|
|
|
1893
2062
|
// src/prompts.ts
|
|
2063
|
+
var MAX_HINTED_CHANGES = 3;
|
|
2064
|
+
var TOOLING_QUESTIONS = {
|
|
2065
|
+
bundler: { message: "Bundler", options: BUNDLER_OPTIONS },
|
|
2066
|
+
uiFramework: { message: "UI framework", options: UI_FRAMEWORK_OPTIONS },
|
|
2067
|
+
linter: { message: "Linter", options: LINTER_OPTIONS },
|
|
2068
|
+
formatter: { message: "Formatter", options: FORMATTER_OPTIONS },
|
|
2069
|
+
spellChecker: { message: "Spell checker", options: SPELL_CHECKER_OPTIONS },
|
|
2070
|
+
markdownLinter: { message: "Markdown linter", options: MARKDOWN_LINTER_OPTIONS },
|
|
2071
|
+
testRunner: { message: "Unit testing", options: TEST_RUNNER_OPTIONS },
|
|
2072
|
+
e2eTestRunner: { message: "E2E testing", options: E2E_TEST_RUNNER_OPTIONS },
|
|
2073
|
+
editorExtensions: { message: "Editor extensions", options: EDITOR_EXTENSIONS_OPTIONS },
|
|
2074
|
+
styling: { message: "Styling", options: STYLING_OPTIONS },
|
|
2075
|
+
wasmSupport: { message: "WebAssembly support", options: WASM_SUPPORT_OPTIONS },
|
|
2076
|
+
commitLinting: { message: "Commit linting", options: COMMIT_LINTING_OPTIONS },
|
|
2077
|
+
hotReload: { message: "Hot reload", options: HOT_RELOAD_OPTIONS },
|
|
2078
|
+
internationalization: { message: "Internationalization", options: INTERNATIONALIZATION_OPTIONS },
|
|
2079
|
+
gitHubActions: { message: "GitHub Actions", options: GITHUB_ACTIONS_OPTIONS },
|
|
2080
|
+
gitHubIssueTemplates: { message: "GitHub issue templates", options: GITHUB_ISSUE_TEMPLATES_OPTIONS },
|
|
2081
|
+
coverageBadge: { message: "Coverage badge", options: COVERAGE_BADGE_OPTIONS },
|
|
2082
|
+
apiSubset: { message: "Obsidian API subset", options: API_SUBSET_OPTIONS },
|
|
2083
|
+
packageManager: { message: "Package manager", options: PACKAGE_MANAGER_OPTIONS },
|
|
2084
|
+
platformSupport: { message: "Platform support", options: PLATFORM_SUPPORT_OPTIONS }
|
|
2085
|
+
};
|
|
2086
|
+
var API_SUBSET_PRESETS = ["all-in-one", "docs-showcase"];
|
|
1894
2087
|
var DEFAULT_PLUGIN_ID = "my-awesome-helper";
|
|
1895
2088
|
function getDefaultAnswers(defaults) {
|
|
1896
2089
|
const pluginId = defaults?.pluginId ?? DEFAULT_PLUGIN_ID;
|
|
@@ -1909,10 +2102,10 @@ function getDefaultAnswers(defaults) {
|
|
|
1909
2102
|
function makePluginName(pluginId) {
|
|
1910
2103
|
return extractWords(pluginId).join(" ");
|
|
1911
2104
|
}
|
|
1912
|
-
async function promptAnswers(defaults) {
|
|
2105
|
+
async function promptAnswers(defaults, supplied = defaults ?? {}) {
|
|
1913
2106
|
showHotkeyHints();
|
|
1914
2107
|
const defaultTooling = getDefaultTooling();
|
|
1915
|
-
const steps = skipSuppliedAnswers(buildPromptSteps(defaults ?? {}, defaultTooling),
|
|
2108
|
+
const steps = skipSuppliedAnswers(buildPromptSteps(defaults ?? {}, supplied, defaultTooling), supplied);
|
|
1916
2109
|
const answers = await runPromptSteps(steps);
|
|
1917
2110
|
return buildAnswers(answers, defaultTooling);
|
|
1918
2111
|
}
|
|
@@ -1922,6 +2115,9 @@ function validateNotEmpty(value) {
|
|
|
1922
2115
|
}
|
|
1923
2116
|
return void 0;
|
|
1924
2117
|
}
|
|
2118
|
+
function asksApiSubset(preset) {
|
|
2119
|
+
return API_SUBSET_PRESETS.includes(preset ?? "");
|
|
2120
|
+
}
|
|
1925
2121
|
function buildAnswers(answers, defaultTooling) {
|
|
1926
2122
|
function get(key, fallback) {
|
|
1927
2123
|
return answers.get(key) ?? fallback;
|
|
@@ -1931,7 +2127,7 @@ function buildAnswers(answers, defaultTooling) {
|
|
|
1931
2127
|
apiSubset: get("apiSubset", defaultTooling.apiSubset),
|
|
1932
2128
|
authorGitHubName: get("authorGitHubName", "johndoe"),
|
|
1933
2129
|
authorName: get("authorName", "John Doe"),
|
|
1934
|
-
bundler: get("bundler",
|
|
2130
|
+
bundler: get("bundler", defaultTooling.bundler),
|
|
1935
2131
|
commitLinting: get("commitLinting", defaultTooling.commitLinting),
|
|
1936
2132
|
coverageBadge: get("coverageBadge", defaultTooling.coverageBadge),
|
|
1937
2133
|
currentYear: (/* @__PURE__ */ new Date()).getFullYear(),
|
|
@@ -1949,154 +2145,165 @@ function buildAnswers(answers, defaultTooling) {
|
|
|
1949
2145
|
linter: get("linter", defaultTooling.linter),
|
|
1950
2146
|
markdownLinter: get("markdownLinter", defaultTooling.markdownLinter),
|
|
1951
2147
|
obsidianConfigFolder: get("obsidianConfigFolder", ""),
|
|
1952
|
-
packageManager: get("packageManager",
|
|
1953
|
-
platformSupport: get("platformSupport",
|
|
2148
|
+
packageManager: get("packageManager", defaultTooling.packageManager),
|
|
2149
|
+
platformSupport: get("platformSupport", defaultTooling.platformSupport),
|
|
1954
2150
|
pluginDescription: get("pluginDescription", "Does something awesome."),
|
|
1955
2151
|
pluginId,
|
|
1956
2152
|
pluginName: get("pluginName", makePluginName(pluginId)),
|
|
1957
|
-
preset: get("preset", "
|
|
2153
|
+
preset: get("preset", "all-in-one"),
|
|
1958
2154
|
spellChecker: get("spellChecker", defaultTooling.spellChecker),
|
|
1959
2155
|
styling: get("styling", defaultTooling.styling),
|
|
1960
2156
|
testRunner: get("testRunner", defaultTooling.testRunner),
|
|
1961
|
-
uiFramework: get("uiFramework",
|
|
2157
|
+
uiFramework: get("uiFramework", defaultTooling.uiFramework),
|
|
1962
2158
|
wasmSupport: get("wasmSupport", defaultTooling.wasmSupport)
|
|
1963
2159
|
};
|
|
1964
2160
|
}
|
|
1965
|
-
function buildPromptSteps(d, defaultTooling) {
|
|
2161
|
+
function buildPromptSteps(d, supplied, defaultTooling) {
|
|
1966
2162
|
function isCustomize(answers) {
|
|
1967
2163
|
return answers.get("toolingMode") === "customize";
|
|
1968
2164
|
}
|
|
1969
2165
|
function skipUnlessCustomize(answers) {
|
|
1970
2166
|
return !isCustomize(answers);
|
|
1971
2167
|
}
|
|
2168
|
+
function tooling(key, answers) {
|
|
2169
|
+
if (answers.get("toolingMode") === "defaults" && supplied[key] === void 0) {
|
|
2170
|
+
return defaultTooling[key];
|
|
2171
|
+
}
|
|
2172
|
+
return d[key] ?? defaultTooling[key];
|
|
2173
|
+
}
|
|
2174
|
+
function changes(answers) {
|
|
2175
|
+
return findToolingChanges(d, supplied, defaultTooling, answers.get("preset"));
|
|
2176
|
+
}
|
|
1972
2177
|
return [
|
|
1973
2178
|
{
|
|
1974
|
-
defaultValue: () => d.preset ?? "
|
|
2179
|
+
defaultValue: () => d.preset ?? "all-in-one",
|
|
1975
2180
|
key: "preset",
|
|
1976
2181
|
prompt: (saved) => promptPreset(saved)
|
|
1977
2182
|
},
|
|
1978
2183
|
{
|
|
1979
|
-
|
|
2184
|
+
// A skipped `Tooling` keeps what was saved, which is what the question offers first when there is any.
|
|
2185
|
+
defaultValue: (answers) => changes(answers).length > 0 ? "keep" : "defaults",
|
|
1980
2186
|
key: "toolingMode",
|
|
1981
|
-
prompt: () => promptToolingMode(),
|
|
1982
|
-
|
|
2187
|
+
prompt: (saved, answers) => promptToolingMode(saved, changes(answers)),
|
|
2188
|
+
// The official sample is upstream's tooling as it is, so there is nothing to customize.
|
|
2189
|
+
skip: (answers) => answers.get("preset") === "demo" || isOfficialSamplePreset(answers.get("preset"))
|
|
1983
2190
|
},
|
|
1984
2191
|
{
|
|
1985
|
-
defaultValue: (answers) => answers.get("preset") === "demo" ? "esbuild" :
|
|
2192
|
+
defaultValue: (answers) => answers.get("preset") === "demo" ? "esbuild" : tooling("bundler", answers),
|
|
1986
2193
|
key: "bundler",
|
|
1987
2194
|
prompt: (saved) => promptBundler(saved),
|
|
1988
2195
|
skip: skipUnlessCustomize
|
|
1989
2196
|
},
|
|
1990
2197
|
{
|
|
1991
|
-
defaultValue: (answers) => answers.get("preset") === "demo" ? "none" :
|
|
2198
|
+
defaultValue: (answers) => answers.get("preset") === "demo" ? "none" : tooling("uiFramework", answers),
|
|
1992
2199
|
key: "uiFramework",
|
|
1993
2200
|
prompt: (saved) => promptUiFramework(saved),
|
|
1994
2201
|
skip: skipUnlessCustomize
|
|
1995
2202
|
},
|
|
1996
2203
|
{
|
|
1997
|
-
defaultValue: () =>
|
|
2204
|
+
defaultValue: (answers) => tooling("linter", answers),
|
|
1998
2205
|
key: "linter",
|
|
1999
2206
|
prompt: (saved) => promptLinter(saved),
|
|
2000
2207
|
skip: skipUnlessCustomize
|
|
2001
2208
|
},
|
|
2002
2209
|
{
|
|
2003
|
-
defaultValue: () =>
|
|
2210
|
+
defaultValue: (answers) => tooling("formatter", answers),
|
|
2004
2211
|
key: "formatter",
|
|
2005
2212
|
prompt: (saved) => promptFormatter(saved),
|
|
2006
2213
|
skip: skipUnlessCustomize
|
|
2007
2214
|
},
|
|
2008
2215
|
{
|
|
2009
|
-
defaultValue: () =>
|
|
2216
|
+
defaultValue: (answers) => tooling("spellChecker", answers),
|
|
2010
2217
|
key: "spellChecker",
|
|
2011
2218
|
prompt: (saved) => promptSpellChecker(saved),
|
|
2012
2219
|
skip: skipUnlessCustomize
|
|
2013
2220
|
},
|
|
2014
2221
|
{
|
|
2015
|
-
defaultValue: () =>
|
|
2222
|
+
defaultValue: (answers) => tooling("markdownLinter", answers),
|
|
2016
2223
|
key: "markdownLinter",
|
|
2017
2224
|
prompt: (saved) => promptMarkdownLinter(saved),
|
|
2018
2225
|
skip: skipUnlessCustomize
|
|
2019
2226
|
},
|
|
2020
2227
|
{
|
|
2021
|
-
defaultValue: () =>
|
|
2228
|
+
defaultValue: (answers) => tooling("testRunner", answers),
|
|
2022
2229
|
key: "testRunner",
|
|
2023
2230
|
prompt: (saved) => promptTestRunner(saved),
|
|
2024
2231
|
skip: skipUnlessCustomize
|
|
2025
2232
|
},
|
|
2026
2233
|
{
|
|
2027
|
-
defaultValue: () =>
|
|
2234
|
+
defaultValue: (answers) => tooling("e2eTestRunner", answers),
|
|
2028
2235
|
key: "e2eTestRunner",
|
|
2029
2236
|
prompt: (saved) => promptE2eTestRunner(saved),
|
|
2030
2237
|
skip: skipUnlessCustomize
|
|
2031
2238
|
},
|
|
2032
2239
|
{
|
|
2033
|
-
defaultValue: () =>
|
|
2240
|
+
defaultValue: (answers) => tooling("editorExtensions", answers),
|
|
2034
2241
|
key: "editorExtensions",
|
|
2035
2242
|
prompt: (saved) => promptEditorExtensions(saved),
|
|
2036
2243
|
skip: skipUnlessCustomize
|
|
2037
2244
|
},
|
|
2038
2245
|
{
|
|
2039
|
-
defaultValue: () =>
|
|
2246
|
+
defaultValue: (answers) => tooling("styling", answers),
|
|
2040
2247
|
key: "styling",
|
|
2041
2248
|
prompt: (saved) => promptStyling(saved),
|
|
2042
2249
|
skip: skipUnlessCustomize
|
|
2043
2250
|
},
|
|
2044
2251
|
{
|
|
2045
|
-
defaultValue: () =>
|
|
2252
|
+
defaultValue: (answers) => tooling("wasmSupport", answers),
|
|
2046
2253
|
key: "wasmSupport",
|
|
2047
2254
|
prompt: (saved) => promptWasmSupport(saved),
|
|
2048
2255
|
skip: skipUnlessCustomize
|
|
2049
2256
|
},
|
|
2050
2257
|
{
|
|
2051
|
-
defaultValue: () =>
|
|
2258
|
+
defaultValue: (answers) => tooling("commitLinting", answers),
|
|
2052
2259
|
key: "commitLinting",
|
|
2053
2260
|
prompt: (saved) => promptCommitLinting(saved),
|
|
2054
2261
|
skip: skipUnlessCustomize
|
|
2055
2262
|
},
|
|
2056
2263
|
{
|
|
2057
|
-
defaultValue: () =>
|
|
2264
|
+
defaultValue: (answers) => tooling("hotReload", answers),
|
|
2058
2265
|
key: "hotReload",
|
|
2059
2266
|
prompt: (saved) => promptHotReload(saved),
|
|
2060
2267
|
skip: skipUnlessCustomize
|
|
2061
2268
|
},
|
|
2062
2269
|
{
|
|
2063
|
-
defaultValue: () =>
|
|
2270
|
+
defaultValue: (answers) => tooling("internationalization", answers),
|
|
2064
2271
|
key: "internationalization",
|
|
2065
2272
|
prompt: (saved) => promptInternationalization(saved),
|
|
2066
2273
|
skip: skipUnlessCustomize
|
|
2067
2274
|
},
|
|
2068
2275
|
{
|
|
2069
|
-
defaultValue: () =>
|
|
2276
|
+
defaultValue: (answers) => tooling("gitHubActions", answers),
|
|
2070
2277
|
key: "gitHubActions",
|
|
2071
2278
|
prompt: (saved) => promptGitHubActions(saved),
|
|
2072
2279
|
skip: skipUnlessCustomize
|
|
2073
2280
|
},
|
|
2074
2281
|
{
|
|
2075
|
-
defaultValue: () =>
|
|
2282
|
+
defaultValue: (answers) => tooling("gitHubIssueTemplates", answers),
|
|
2076
2283
|
key: "gitHubIssueTemplates",
|
|
2077
2284
|
prompt: (saved) => promptGitHubIssueTemplates(saved),
|
|
2078
2285
|
skip: skipUnlessCustomize
|
|
2079
2286
|
},
|
|
2080
2287
|
{
|
|
2081
|
-
defaultValue: () =>
|
|
2288
|
+
defaultValue: (answers) => tooling("coverageBadge", answers),
|
|
2082
2289
|
key: "coverageBadge",
|
|
2083
2290
|
prompt: (saved) => promptCoverageBadge(saved),
|
|
2084
2291
|
skip: skipUnlessCustomize
|
|
2085
2292
|
},
|
|
2086
2293
|
{
|
|
2087
|
-
defaultValue: () =>
|
|
2294
|
+
defaultValue: (answers) => tooling("apiSubset", answers),
|
|
2088
2295
|
key: "apiSubset",
|
|
2089
2296
|
prompt: (saved) => promptApiSubset(saved),
|
|
2090
|
-
skip: (answers) => !(isCustomize(answers) && answers.get("preset")
|
|
2297
|
+
skip: (answers) => !(isCustomize(answers) && asksApiSubset(answers.get("preset")))
|
|
2091
2298
|
},
|
|
2092
2299
|
{
|
|
2093
|
-
defaultValue: () =>
|
|
2300
|
+
defaultValue: (answers) => tooling("packageManager", answers),
|
|
2094
2301
|
key: "packageManager",
|
|
2095
2302
|
prompt: (saved) => promptPackageManager(saved),
|
|
2096
2303
|
skip: skipUnlessCustomize
|
|
2097
2304
|
},
|
|
2098
2305
|
{
|
|
2099
|
-
defaultValue: () =>
|
|
2306
|
+
defaultValue: (answers) => tooling("platformSupport", answers),
|
|
2100
2307
|
key: "platformSupport",
|
|
2101
2308
|
prompt: (saved) => promptPlatformSupport(saved),
|
|
2102
2309
|
skip: skipUnlessCustomize
|
|
@@ -2187,37 +2394,59 @@ function buildPromptSteps(d, defaultTooling) {
|
|
|
2187
2394
|
defaultValue: saved || void 0,
|
|
2188
2395
|
message: "Path to test vault config folder (.obsidian, by default, but it is configurable in Obsidian settings). This enables auto-update of your plugin in your test vault during dev. Leave empty if you prefer to update the plugin manually.",
|
|
2189
2396
|
placeholder: saved || "path/to/test-vault/.obsidian"
|
|
2190
|
-
})
|
|
2397
|
+
}),
|
|
2398
|
+
// Upstream builds into the project folder and copies nothing into a vault.
|
|
2399
|
+
skip: (answers) => isOfficialSamplePreset(answers.get("preset"))
|
|
2191
2400
|
}
|
|
2192
2401
|
];
|
|
2193
2402
|
}
|
|
2403
|
+
function describeChanges(changes, describe) {
|
|
2404
|
+
const named = changes.slice(0, MAX_HINTED_CHANGES).map(describe).join(", ");
|
|
2405
|
+
const rest = changes.length - MAX_HINTED_CHANGES;
|
|
2406
|
+
return rest > 0 ? `${named}, and ${String(rest)} more` : named;
|
|
2407
|
+
}
|
|
2194
2408
|
function extractWords(pluginId) {
|
|
2195
2409
|
return pluginId.split("-").map((w) => (w[0] ?? "").toUpperCase() + w.slice(1));
|
|
2196
2410
|
}
|
|
2411
|
+
function findToolingChanges(d, supplied, defaultTooling, preset) {
|
|
2412
|
+
const changes = [];
|
|
2413
|
+
for (const [key, question] of Object.entries(TOOLING_QUESTIONS)) {
|
|
2414
|
+
const saved = d[key];
|
|
2415
|
+
if (saved === void 0 || supplied[key] !== void 0 || saved === defaultTooling[key]) {
|
|
2416
|
+
continue;
|
|
2417
|
+
}
|
|
2418
|
+
if (key === "apiSubset" && !asksApiSubset(preset)) {
|
|
2419
|
+
continue;
|
|
2420
|
+
}
|
|
2421
|
+
changes.push({
|
|
2422
|
+
question: question.message,
|
|
2423
|
+
recommended: getOptionLabel(question, defaultTooling[key]),
|
|
2424
|
+
saved: getOptionLabel(question, saved)
|
|
2425
|
+
});
|
|
2426
|
+
}
|
|
2427
|
+
return changes;
|
|
2428
|
+
}
|
|
2197
2429
|
function getDefaultAnswersBase(pluginId) {
|
|
2198
2430
|
return {
|
|
2199
2431
|
...getDefaultTooling(),
|
|
2200
2432
|
authorGitHubName: "johndoe",
|
|
2201
2433
|
authorName: "John Doe",
|
|
2202
|
-
bundler: "esbuild",
|
|
2203
2434
|
currentYear: (/* @__PURE__ */ new Date()).getFullYear(),
|
|
2204
2435
|
defaultBranch: "main",
|
|
2205
2436
|
fundingPlatform: "buy-me-a-coffee",
|
|
2206
2437
|
fundingUrl: "",
|
|
2207
2438
|
fundingUsername: "johndoe",
|
|
2208
2439
|
obsidianConfigFolder: "",
|
|
2209
|
-
packageManager: "npm",
|
|
2210
|
-
platformSupport: "desktop-only",
|
|
2211
2440
|
pluginDescription: "Does something awesome.",
|
|
2212
2441
|
pluginId,
|
|
2213
2442
|
pluginName: makePluginName(pluginId),
|
|
2214
|
-
preset: "
|
|
2215
|
-
uiFramework: "none"
|
|
2443
|
+
preset: "all-in-one"
|
|
2216
2444
|
};
|
|
2217
2445
|
}
|
|
2218
2446
|
function getDefaultTooling() {
|
|
2219
2447
|
return {
|
|
2220
2448
|
apiSubset: "official",
|
|
2449
|
+
bundler: "esbuild",
|
|
2221
2450
|
commitLinting: "conventional-commits",
|
|
2222
2451
|
coverageBadge: "none",
|
|
2223
2452
|
e2eTestRunner: "none",
|
|
@@ -2229,12 +2458,18 @@ function getDefaultTooling() {
|
|
|
2229
2458
|
internationalization: "none",
|
|
2230
2459
|
linter: "eslint",
|
|
2231
2460
|
markdownLinter: "markdownlint",
|
|
2461
|
+
packageManager: "npm",
|
|
2462
|
+
platformSupport: "desktop-only",
|
|
2232
2463
|
spellChecker: "cspell",
|
|
2233
2464
|
styling: "scss",
|
|
2234
2465
|
testRunner: "vitest",
|
|
2466
|
+
uiFramework: "none",
|
|
2235
2467
|
wasmSupport: "none"
|
|
2236
2468
|
};
|
|
2237
2469
|
}
|
|
2470
|
+
function getOptionLabel(question, value) {
|
|
2471
|
+
return question.options.find((option) => option.settingValue === value)?.promptLabel ?? value;
|
|
2472
|
+
}
|
|
2238
2473
|
function promptPluginDescription(saved) {
|
|
2239
2474
|
const value = saved || void 0;
|
|
2240
2475
|
return text({
|
|
@@ -2253,13 +2488,29 @@ function promptPluginName(saved) {
|
|
|
2253
2488
|
validate: validatePluginName
|
|
2254
2489
|
});
|
|
2255
2490
|
}
|
|
2256
|
-
async function promptToolingMode() {
|
|
2491
|
+
async function promptToolingMode(savedValue, changes) {
|
|
2492
|
+
const customize = { hint: "Choose each tool individually", label: "Customize", value: "customize" };
|
|
2493
|
+
if (changes.length === 0) {
|
|
2494
|
+
return select({
|
|
2495
|
+
initialValue: savedValue,
|
|
2496
|
+
message: "Tooling",
|
|
2497
|
+
options: [
|
|
2498
|
+
customize,
|
|
2499
|
+
{ hint: "ESLint, dprint, SCSS, Vitest, and more", label: "Use recommended defaults", value: "defaults" }
|
|
2500
|
+
]
|
|
2501
|
+
});
|
|
2502
|
+
}
|
|
2257
2503
|
return select({
|
|
2258
|
-
initialValue:
|
|
2504
|
+
initialValue: savedValue,
|
|
2259
2505
|
message: "Tooling",
|
|
2260
2506
|
options: [
|
|
2261
|
-
{ hint:
|
|
2262
|
-
|
|
2507
|
+
{ hint: describeChanges(changes, (change) => `${change.question}: ${change.saved}`), label: "Keep current tooling", value: "keep" },
|
|
2508
|
+
customize,
|
|
2509
|
+
{
|
|
2510
|
+
hint: describeChanges(changes, (change) => `${change.question}: ${change.saved} -> ${change.recommended}`),
|
|
2511
|
+
label: "Use recommended defaults",
|
|
2512
|
+
value: "defaults"
|
|
2513
|
+
}
|
|
2263
2514
|
]
|
|
2264
2515
|
});
|
|
2265
2516
|
}
|
|
@@ -2275,7 +2526,7 @@ async function runPromptSteps(steps) {
|
|
|
2275
2526
|
}
|
|
2276
2527
|
try {
|
|
2277
2528
|
const savedValue = answers.get(step.key) ?? step.defaultValue(answers);
|
|
2278
|
-
answers.set(step.key, await step.prompt(savedValue));
|
|
2529
|
+
answers.set(step.key, await step.prompt(savedValue, answers));
|
|
2279
2530
|
i++;
|
|
2280
2531
|
} catch (error) {
|
|
2281
2532
|
if (!(error instanceof GoBackError)) {
|
|
@@ -2303,7 +2554,7 @@ function showHotkeyHints() {
|
|
|
2303
2554
|
function key(s) {
|
|
2304
2555
|
return styleText3("cyan", s);
|
|
2305
2556
|
}
|
|
2306
|
-
|
|
2557
|
+
log2.info([
|
|
2307
2558
|
`${key("\u2191\u2193")} Navigate ${key("Enter")} Confirm ${key("Esc")} Go back`,
|
|
2308
2559
|
`${dim("Text inputs:")} ${key("Tab")}/${key("\u2192")}/${key("End")} Accept suggestion`
|
|
2309
2560
|
].join("\n"));
|
|
@@ -2323,6 +2574,7 @@ var ANSWERS_FILE_PREFIX = "--answersFile=";
|
|
|
2323
2574
|
var CUSTOM_TEMPLATE_PREFIX = "--customTemplate=";
|
|
2324
2575
|
var MODE_PREFIX = "--mode=";
|
|
2325
2576
|
var MODES = ["create" /* Create */, "update" /* Update */];
|
|
2577
|
+
var MODE_BY_VALUE = new Map(MODES.map((mode) => [mode, mode]));
|
|
2326
2578
|
var FLAG_PREFIX_LENGTH = 2;
|
|
2327
2579
|
var FREE_TEXT_VALIDATORS = {
|
|
2328
2580
|
authorGitHubName: validateNotEmpty,
|
|
@@ -2334,6 +2586,9 @@ var FREE_TEXT_VALIDATORS = {
|
|
|
2334
2586
|
pluginName: validatePluginName
|
|
2335
2587
|
};
|
|
2336
2588
|
var DEMO_PINNED_ANSWER_KEYS = ["bundler", "uiFramework"];
|
|
2589
|
+
var VALUES_OUTSIDE_ANSWER_SPACE = {
|
|
2590
|
+
preset: [OFFICIAL_SAMPLE_PRESET]
|
|
2591
|
+
};
|
|
2337
2592
|
function assertValidAnswer(key, value) {
|
|
2338
2593
|
const dimension = findChoiceDimension(key);
|
|
2339
2594
|
if (dimension) {
|
|
@@ -2366,6 +2621,8 @@ function getHelpText() {
|
|
|
2366
2621
|
" --customTemplate=<dir> Layer your own templates over the built-in ones: a directory",
|
|
2367
2622
|
" mirroring templates/default, plus an overlay.json. Recorded in the",
|
|
2368
2623
|
" project and re-applied on update; pass it empty to drop it.",
|
|
2624
|
+
" --latest With --preset=official-sample: copy obsidianmd/obsidian-sample-plugin",
|
|
2625
|
+
" as it is upstream today, not the snapshot this release vendored.",
|
|
2369
2626
|
"",
|
|
2370
2627
|
"Answers (any of these may be given as --<key>=<value>):"
|
|
2371
2628
|
];
|
|
@@ -2380,6 +2637,7 @@ function parseCliArgs(argv) {
|
|
|
2380
2637
|
let answersFilePath = null;
|
|
2381
2638
|
let customTemplate;
|
|
2382
2639
|
let force = false;
|
|
2640
|
+
let latest = false;
|
|
2383
2641
|
let mode;
|
|
2384
2642
|
let showHelp = false;
|
|
2385
2643
|
let useDefaults = false;
|
|
@@ -2404,27 +2662,40 @@ function parseCliArgs(argv) {
|
|
|
2404
2662
|
force = true;
|
|
2405
2663
|
continue;
|
|
2406
2664
|
}
|
|
2665
|
+
if (argument === "--latest") {
|
|
2666
|
+
latest = true;
|
|
2667
|
+
continue;
|
|
2668
|
+
}
|
|
2407
2669
|
if (argument.startsWith(MODE_PREFIX)) {
|
|
2408
2670
|
mode = toMode(argument.slice(MODE_PREFIX.length));
|
|
2409
2671
|
continue;
|
|
2410
2672
|
}
|
|
2411
|
-
const [rawKey,
|
|
2673
|
+
const [rawKey, rawValue] = splitFlag(argument);
|
|
2412
2674
|
const key = toAnswerKey(rawKey);
|
|
2413
|
-
|
|
2414
|
-
flagAnswers[key] = value;
|
|
2675
|
+
flagAnswers[key] = resolveAnswer(key, rawValue, `--${key}`);
|
|
2415
2676
|
}
|
|
2416
2677
|
const fileAnswers = answersFilePath === null ? {} : readAnswersFile(answersFilePath);
|
|
2417
|
-
const
|
|
2678
|
+
const isOfficialSample = isOfficialSamplePreset(flagAnswers.preset ?? fileAnswers.preset);
|
|
2679
|
+
if (isOfficialSample) {
|
|
2680
|
+
assertNoOfficialSampleConflict(flagAnswers);
|
|
2681
|
+
}
|
|
2682
|
+
const answers = { ...isOfficialSample ? pickOfficialSampleAnswers(fileAnswers) : fileAnswers, ...flagAnswers };
|
|
2418
2683
|
assertNoDemoConflict(answers);
|
|
2419
2684
|
return {
|
|
2420
2685
|
answers,
|
|
2421
2686
|
customTemplate,
|
|
2422
2687
|
force,
|
|
2688
|
+
latest,
|
|
2423
2689
|
mode,
|
|
2424
2690
|
showHelp,
|
|
2425
2691
|
useDefaults
|
|
2426
2692
|
};
|
|
2427
2693
|
}
|
|
2694
|
+
function resolveAnswer(key, value, source) {
|
|
2695
|
+
const resolved = resolveDeprecatedAnswer(key, value, source);
|
|
2696
|
+
assertValidAnswer(key, resolved);
|
|
2697
|
+
return resolved;
|
|
2698
|
+
}
|
|
2428
2699
|
function toAnswerKey(key) {
|
|
2429
2700
|
if (REFUSED_KEYS.includes(key)) {
|
|
2430
2701
|
throw new Error(`${key} is computed by the generator, not answered, so it cannot be set.`);
|
|
@@ -2445,12 +2716,23 @@ function assertNoDemoConflict(answers) {
|
|
|
2445
2716
|
}
|
|
2446
2717
|
}
|
|
2447
2718
|
}
|
|
2719
|
+
function assertNoOfficialSampleConflict(answers) {
|
|
2720
|
+
const conflicting = Object.keys(answers).filter((key) => answers[key] !== void 0 && !OFFICIAL_SAMPLE_ANSWER_KEYS.includes(key));
|
|
2721
|
+
if (conflicting.length > 0) {
|
|
2722
|
+
const flags = conflicting.map((key) => `--${key}`).join(", ");
|
|
2723
|
+
throw new Error(`preset=official-sample copies obsidianmd/obsidian-sample-plugin as it is, so it takes no ${conflicting.join(", ")}. Drop ${flags}, or choose another preset.`);
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2448
2726
|
function findChoiceDimension(key) {
|
|
2449
2727
|
const dimension = ANSWER_SPACE.find((candidate) => candidate.answerKey === key);
|
|
2450
2728
|
if (!dimension || dimension.values.includes("")) {
|
|
2451
2729
|
return null;
|
|
2452
2730
|
}
|
|
2453
|
-
|
|
2731
|
+
const extraValues = VALUES_OUTSIDE_ANSWER_SPACE[key];
|
|
2732
|
+
return extraValues ? { ...dimension, values: [...dimension.values, ...extraValues] } : dimension;
|
|
2733
|
+
}
|
|
2734
|
+
function pickOfficialSampleAnswers(answers) {
|
|
2735
|
+
return Object.fromEntries(Object.entries(answers).filter(([key]) => OFFICIAL_SAMPLE_ANSWER_KEYS.includes(key)));
|
|
2454
2736
|
}
|
|
2455
2737
|
function readAnswersFile(path) {
|
|
2456
2738
|
if (!existsSync(path)) {
|
|
@@ -2477,8 +2759,7 @@ function readAnswersFile(path) {
|
|
|
2477
2759
|
throw new Error(`${rawKey} in ${path} should be a string, got ${typeof value}.`);
|
|
2478
2760
|
}
|
|
2479
2761
|
const key = toAnswerKey(rawKey);
|
|
2480
|
-
|
|
2481
|
-
answers[key] = value;
|
|
2762
|
+
answers[key] = resolveAnswer(key, value, path);
|
|
2482
2763
|
}
|
|
2483
2764
|
return answers;
|
|
2484
2765
|
}
|
|
@@ -2493,10 +2774,11 @@ function splitFlag(argument) {
|
|
|
2493
2774
|
return [argument.slice(FLAG_PREFIX_LENGTH, separatorIndex), argument.slice(separatorIndex + 1)];
|
|
2494
2775
|
}
|
|
2495
2776
|
function toMode(value) {
|
|
2496
|
-
|
|
2777
|
+
const mode = MODE_BY_VALUE.get(value);
|
|
2778
|
+
if (mode === void 0) {
|
|
2497
2779
|
throw new Error(`"${value}" is not a mode. It accepts: ${MODES.join(", ")}.`);
|
|
2498
2780
|
}
|
|
2499
|
-
return
|
|
2781
|
+
return mode;
|
|
2500
2782
|
}
|
|
2501
2783
|
|
|
2502
2784
|
// src/answers-export.ts
|
|
@@ -2536,6 +2818,9 @@ function formatCreateScript(answers, shell, customTemplate) {
|
|
|
2536
2818
|
}
|
|
2537
2819
|
function getExportableKeys(answers) {
|
|
2538
2820
|
const keys = getAnswerableKeys();
|
|
2821
|
+
if (isOfficialSamplePreset(answers.preset)) {
|
|
2822
|
+
return keys.filter((key) => OFFICIAL_SAMPLE_ANSWER_KEYS.includes(key));
|
|
2823
|
+
}
|
|
2539
2824
|
if (answers.preset !== "demo") {
|
|
2540
2825
|
return keys;
|
|
2541
2826
|
}
|
|
@@ -2589,48 +2874,50 @@ function validatePluginIdIsUnlisted(pluginId, listedIds) {
|
|
|
2589
2874
|
return `"${pluginId}" is already the id of a plugin in the Community directory -- the directory requires every id to be unique, and an id can never be changed once the plugin is published`;
|
|
2590
2875
|
}
|
|
2591
2876
|
|
|
2592
|
-
// src/
|
|
2593
|
-
import {
|
|
2594
|
-
existsSync as existsSync4,
|
|
2595
|
-
readdirSync as readdirSync2,
|
|
2596
|
-
readFileSync as readFileSync4,
|
|
2597
|
-
statSync as statSync2
|
|
2598
|
-
} from "node:fs";
|
|
2599
|
-
import {
|
|
2600
|
-
isAbsolute,
|
|
2601
|
-
join as join3,
|
|
2602
|
-
relative,
|
|
2603
|
-
resolve
|
|
2604
|
-
} from "node:path";
|
|
2877
|
+
// src/official-sample.ts
|
|
2878
|
+
import { join as join4 } from "node:path";
|
|
2605
2879
|
|
|
2606
|
-
// src/
|
|
2880
|
+
// src/templates.ts
|
|
2881
|
+
import { log as log4 } from "@clack/prompts";
|
|
2882
|
+
import ejs from "ejs";
|
|
2883
|
+
import { createHash } from "node:crypto";
|
|
2607
2884
|
import {
|
|
2608
2885
|
existsSync as existsSync3,
|
|
2609
|
-
|
|
2886
|
+
mkdirSync,
|
|
2610
2887
|
readFileSync as readFileSync3,
|
|
2611
|
-
|
|
2888
|
+
writeFileSync
|
|
2612
2889
|
} from "node:fs";
|
|
2613
2890
|
import {
|
|
2614
|
-
|
|
2891
|
+
dirname,
|
|
2892
|
+
extname,
|
|
2615
2893
|
join as join2
|
|
2616
2894
|
} from "node:path";
|
|
2895
|
+
import { fileURLToPath } from "node:url";
|
|
2617
2896
|
|
|
2618
|
-
// src/
|
|
2619
|
-
import { log as log3 } from "@clack/prompts";
|
|
2620
|
-
import ejs from "ejs";
|
|
2621
|
-
import { createHash } from "node:crypto";
|
|
2897
|
+
// src/docs-showcase/docs-showcase-files.ts
|
|
2622
2898
|
import {
|
|
2623
2899
|
existsSync as existsSync2,
|
|
2624
|
-
|
|
2625
|
-
readFileSync as readFileSync2
|
|
2626
|
-
writeFileSync
|
|
2900
|
+
readdirSync,
|
|
2901
|
+
readFileSync as readFileSync2
|
|
2627
2902
|
} from "node:fs";
|
|
2628
2903
|
import {
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
join
|
|
2904
|
+
join,
|
|
2905
|
+
relative
|
|
2632
2906
|
} from "node:path";
|
|
2633
|
-
|
|
2907
|
+
var DOCS_SHOWCASE_TREE_DIR = join("src", "docs");
|
|
2908
|
+
var DOCS_SHOWCASE_FILES_DIR = join("templates", "docs-showcase", "files");
|
|
2909
|
+
var DOCS_SHOWCASE_HOST_DIR = join("templates", "docs-showcase", "host");
|
|
2910
|
+
var DOCS_SHOWCASE_REPORT_PATH = join("templates", "docs-showcase", "snippets.json");
|
|
2911
|
+
function readDocsShowcaseFiles(packageRoot) {
|
|
2912
|
+
const filesDir = join(packageRoot, DOCS_SHOWCASE_FILES_DIR);
|
|
2913
|
+
if (!existsSync2(filesDir)) {
|
|
2914
|
+
return [];
|
|
2915
|
+
}
|
|
2916
|
+
return readdirSync(filesDir, { recursive: true, withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => join(entry.parentPath, entry.name)).sort((a, b) => a.localeCompare(b)).map((fullPath) => ({
|
|
2917
|
+
content: readFileSync2(fullPath, "utf-8"),
|
|
2918
|
+
destinationPath: relative(filesDir, fullPath).replaceAll("\\", "/")
|
|
2919
|
+
}));
|
|
2920
|
+
}
|
|
2634
2921
|
|
|
2635
2922
|
// src/template-builder.ts
|
|
2636
2923
|
var PARTIAL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
@@ -2647,10 +2934,31 @@ var Dependency = class {
|
|
|
2647
2934
|
this.version = version;
|
|
2648
2935
|
}
|
|
2649
2936
|
};
|
|
2937
|
+
var FRAMEWORKS_ESBUILD_COMPILES_UNASKED = /* @__PURE__ */ new Set(["preact", "react", "svelte"]);
|
|
2650
2938
|
var TemplateBuilder = class {
|
|
2651
2939
|
get badges() {
|
|
2652
2940
|
return [...this._badges];
|
|
2653
2941
|
}
|
|
2942
|
+
/**
|
|
2943
|
+
* The options every obsidian-dev-toolkit bundler adapter takes, as `key: <TypeScript literal>` source, sorted by key.
|
|
2944
|
+
*
|
|
2945
|
+
* `framework` is a single value, and only `preset: demo` registers more than one, a set it builds only with esbuild.
|
|
2946
|
+
* There the toolkit compiles Svelte, React and Preact unasked, so the framework that needs the option is the one
|
|
2947
|
+
* passed.
|
|
2948
|
+
*/
|
|
2949
|
+
get buildOptions() {
|
|
2950
|
+
const options = new Map(this._buildOptions);
|
|
2951
|
+
const frameworks = [...this._buildFrameworks];
|
|
2952
|
+
const framework = frameworks.length > 1 ? frameworks.find((name) => !FRAMEWORKS_ESBUILD_COMPILES_UNASKED.has(name)) : frameworks[0];
|
|
2953
|
+
if (framework !== void 0) {
|
|
2954
|
+
options.set("framework", `'${framework}'`);
|
|
2955
|
+
}
|
|
2956
|
+
if (this._buildStyles !== null) {
|
|
2957
|
+
const flags = [...this._buildStyles].sort((a, b) => a.localeCompare(b));
|
|
2958
|
+
options.set("styles", flags.length === 0 ? "{}" : `{ ${flags.map((flag) => `${flag}: true`).join(", ")} }`);
|
|
2959
|
+
}
|
|
2960
|
+
return [...options.entries()].map(([key, value]) => ({ key, value })).sort((a, b) => a.key.localeCompare(b.key));
|
|
2961
|
+
}
|
|
2654
2962
|
get depcheckIgnores() {
|
|
2655
2963
|
return [...this._depcheckIgnores.entries()].map(([packageName, reason]) => ({ packageName, reason })).sort((a, b) => a.packageName.localeCompare(b.packageName));
|
|
2656
2964
|
}
|
|
@@ -2658,7 +2966,7 @@ var TemplateBuilder = class {
|
|
|
2658
2966
|
return [...this._dependencies.values()].sort((a, b) => a.packageName.localeCompare(b.packageName));
|
|
2659
2967
|
}
|
|
2660
2968
|
get lintStagedPatterns() {
|
|
2661
|
-
return [...this._lintStagedPatterns.entries()].map(([pattern, commands]) => ({ commands: [...commands], pattern }));
|
|
2969
|
+
return [...this._lintStagedPatterns.entries()].map(([pattern, commands]) => ({ commands: [...commands], pattern })).sort((a, b) => a.pattern.localeCompare(b.pattern));
|
|
2662
2970
|
}
|
|
2663
2971
|
get partials() {
|
|
2664
2972
|
return new Set(this._partials);
|
|
@@ -2672,7 +2980,16 @@ var TemplateBuilder = class {
|
|
|
2672
2980
|
get templateFiles() {
|
|
2673
2981
|
return new Set(this._templateFiles);
|
|
2674
2982
|
}
|
|
2983
|
+
/**
|
|
2984
|
+
* The configs the emitted `tsconfig.json` extends after its base, in registration order.
|
|
2985
|
+
*/
|
|
2986
|
+
get tsconfigExtends() {
|
|
2987
|
+
return [...this._tsconfigExtends];
|
|
2988
|
+
}
|
|
2675
2989
|
_badges = [];
|
|
2990
|
+
_buildFrameworks = /* @__PURE__ */ new Set();
|
|
2991
|
+
_buildOptions = /* @__PURE__ */ new Map();
|
|
2992
|
+
_buildStyles = null;
|
|
2676
2993
|
_depcheckIgnores = /* @__PURE__ */ new Map();
|
|
2677
2994
|
_dependencies = /* @__PURE__ */ new Map();
|
|
2678
2995
|
_lintStagedPatterns = /* @__PURE__ */ new Map();
|
|
@@ -2680,6 +2997,7 @@ var TemplateBuilder = class {
|
|
|
2680
2997
|
_scripts = {};
|
|
2681
2998
|
_sentenceCaseBrands = /* @__PURE__ */ new Set();
|
|
2682
2999
|
_templateFiles = /* @__PURE__ */ new Set();
|
|
3000
|
+
_tsconfigExtends = /* @__PURE__ */ new Set();
|
|
2683
3001
|
/**
|
|
2684
3002
|
* Registers a README badge, rendered in registration order on the line under the title.
|
|
2685
3003
|
*
|
|
@@ -2691,6 +3009,35 @@ var TemplateBuilder = class {
|
|
|
2691
3009
|
this._badges.push(markdown);
|
|
2692
3010
|
return this;
|
|
2693
3011
|
}
|
|
3012
|
+
/**
|
|
3013
|
+
* Registers a UI framework the obsidian-dev-toolkit bundler adapters compile, through their `framework` option.
|
|
3014
|
+
*/
|
|
3015
|
+
addBuildFramework(framework) {
|
|
3016
|
+
this._buildFrameworks.add(framework);
|
|
3017
|
+
return this;
|
|
3018
|
+
}
|
|
3019
|
+
/**
|
|
3020
|
+
* Registers an obsidian-dev-toolkit bundler adapter option other than `framework` and `styles`.
|
|
3021
|
+
*
|
|
3022
|
+
* @param key - The option name.
|
|
3023
|
+
* @param value - The option's value, as TypeScript source.
|
|
3024
|
+
*/
|
|
3025
|
+
addBuildOption(key, value) {
|
|
3026
|
+
this._buildOptions.set(key, value);
|
|
3027
|
+
return this;
|
|
3028
|
+
}
|
|
3029
|
+
/**
|
|
3030
|
+
* Turns on the adapters' `styles` option, which compiles the project's plain stylesheets, with a flag of it if given.
|
|
3031
|
+
*
|
|
3032
|
+
* @param flag - `postcss`, `tailwind` or `cssModules`; omitted, the stylesheets are compiled as plain CSS.
|
|
3033
|
+
*/
|
|
3034
|
+
addBuildStyles(flag) {
|
|
3035
|
+
this._buildStyles ??= /* @__PURE__ */ new Set();
|
|
3036
|
+
if (flag !== void 0) {
|
|
3037
|
+
this._buildStyles.add(flag);
|
|
3038
|
+
}
|
|
3039
|
+
return this;
|
|
3040
|
+
}
|
|
2694
3041
|
/**
|
|
2695
3042
|
* Registers a declared package that depcheck reports as unused although it is not -- one only ever
|
|
2696
3043
|
* invoked as a CLI, named as a string in a config, or reached by a compiler option.
|
|
@@ -2718,6 +3065,11 @@ var TemplateBuilder = class {
|
|
|
2718
3065
|
* The commands are collected here rather than concatenated from template partials because a partial can
|
|
2719
3066
|
* only ever emit `'<command>',` -- and the trailing comma the last one leaves behind is exactly what the
|
|
2720
3067
|
* generated formatter config strips, so the file failed its own `format:check`.
|
|
3068
|
+
*
|
|
3069
|
+
* The patterns are rendered sorted, not in registration order: they become the keys of the emitted
|
|
3070
|
+
* `nano-staged-config.ts` object, which the shared ESLint config's `perfectionist/sort-objects` checks,
|
|
3071
|
+
* and answers register them in question order (markdownlint's `*.md` before the `*.{ts,tsx,mts}` that
|
|
3072
|
+
* `preset: demo` forces in). Commands under one pattern keep their order, since nano-staged runs them so.
|
|
2721
3073
|
*/
|
|
2722
3074
|
addLintStagedCommand(pattern, command) {
|
|
2723
3075
|
const commands = this._lintStagedPatterns.get(pattern) ?? [];
|
|
@@ -2755,13 +3107,23 @@ var TemplateBuilder = class {
|
|
|
2755
3107
|
this._sentenceCaseBrands.add(brand);
|
|
2756
3108
|
return this;
|
|
2757
3109
|
}
|
|
3110
|
+
/**
|
|
3111
|
+
* Registers a config the emitted `tsconfig.json` extends after its base, such as a framework's JSX preset.
|
|
3112
|
+
*
|
|
3113
|
+
* Collected here rather than composed from partials for the same reason as {@link addLintStagedCommand}: the
|
|
3114
|
+
* `extends` value is a list whose last entry must not carry a comma, and a single entry is written as a plain string.
|
|
3115
|
+
*/
|
|
3116
|
+
addTsconfigExtends(config) {
|
|
3117
|
+
this._tsconfigExtends.add(config);
|
|
3118
|
+
return this;
|
|
3119
|
+
}
|
|
2758
3120
|
};
|
|
2759
3121
|
|
|
2760
3122
|
// src/versions.ts
|
|
2761
|
-
import { log as
|
|
3123
|
+
import { log as log3 } from "@clack/prompts";
|
|
2762
3124
|
var PINNED_VERSIONS = {
|
|
2763
3125
|
"@babel/core": {
|
|
2764
|
-
check: `node -e "process.stdout.write(
|
|
3126
|
+
check: `node -e "const fs=require('node:fs');process.stdout.write(JSON.parse(fs.readFileSync('node_modules/@rollup/plugin-babel/package.json','utf8')).peerDependencies['@babel/core'])"`,
|
|
2765
3127
|
checkRequires: "@rollup/plugin-babel",
|
|
2766
3128
|
expect: "^7.0.0",
|
|
2767
3129
|
manualCheck: null,
|
|
@@ -2771,7 +3133,7 @@ var PINNED_VERSIONS = {
|
|
|
2771
3133
|
why: "@babel/core is only ever added alongside @rollup/plugin-babel, whose newest release still peers on `^7.0.0` while the registry tags 8.x as latest. Resolving latest therefore produced an `npm install` that fails outright with ERESOLVE for rollup with preact, react or solid. The check reads the peer range @rollup/plugin-babel itself declares, so the pin retires itself when that widens to ^8."
|
|
2772
3134
|
},
|
|
2773
3135
|
"@babel/plugin-transform-react-jsx": {
|
|
2774
|
-
check: `node -e "process.stdout.write(
|
|
3136
|
+
check: `node -e "const fs=require('node:fs');process.stdout.write(JSON.parse(fs.readFileSync('node_modules/@rollup/plugin-babel/package.json','utf8')).peerDependencies['@babel/core'])"`,
|
|
2775
3137
|
checkRequires: "@rollup/plugin-babel",
|
|
2776
3138
|
expect: "^7.0.0",
|
|
2777
3139
|
manualCheck: null,
|
|
@@ -2781,7 +3143,7 @@ var PINNED_VERSIONS = {
|
|
|
2781
3143
|
why: "Held on 7.x for the same reason as @babel/core, and it has to move as one set: 8.0.1 peers on `@babel/core@^8.0.0`, so pinning core to 7 without pinning this one just moves the ERESOLVE. Only ever added for rollup + preact, which is exactly where @rollup/plugin-babel forces 7."
|
|
2782
3144
|
},
|
|
2783
3145
|
"@babel/preset-react": {
|
|
2784
|
-
check: `node -e "process.stdout.write(
|
|
3146
|
+
check: `node -e "const fs=require('node:fs');process.stdout.write(JSON.parse(fs.readFileSync('node_modules/@rollup/plugin-babel/package.json','utf8')).peerDependencies['@babel/core'])"`,
|
|
2785
3147
|
checkRequires: "@rollup/plugin-babel",
|
|
2786
3148
|
expect: "^7.0.0",
|
|
2787
3149
|
manualCheck: null,
|
|
@@ -2791,7 +3153,7 @@ var PINNED_VERSIONS = {
|
|
|
2791
3153
|
why: "Held on 7.x for the same reason as @babel/core, and it has to move as one set: 8.0.1 peers on `@babel/core@^8.0.0`. Only ever added for rollup + react, which is exactly where @rollup/plugin-babel forces 7."
|
|
2792
3154
|
},
|
|
2793
3155
|
"@babel/preset-typescript": {
|
|
2794
|
-
check: `node -e "process.stdout.write(
|
|
3156
|
+
check: `node -e "const fs=require('node:fs');process.stdout.write(JSON.parse(fs.readFileSync('node_modules/@rollup/plugin-babel/package.json','utf8')).peerDependencies['@babel/core'])"`,
|
|
2795
3157
|
checkRequires: "@rollup/plugin-babel",
|
|
2796
3158
|
expect: "^7.0.0",
|
|
2797
3159
|
manualCheck: null,
|
|
@@ -2813,23 +3175,73 @@ var PINNED_VERSIONS = {
|
|
|
2813
3175
|
"@codemirror/state": {
|
|
2814
3176
|
check: `node -e "process.stdout.write(require('obsidian/package.json').peerDependencies['@codemirror/state'])"`,
|
|
2815
3177
|
checkRequires: "obsidian",
|
|
2816
|
-
expect: "6.
|
|
3178
|
+
expect: "6.7.6",
|
|
2817
3179
|
manualCheck: null,
|
|
2818
3180
|
needsOverride: true,
|
|
2819
3181
|
section: "devDependencies",
|
|
2820
|
-
version: "6.
|
|
3182
|
+
version: "6.7.6",
|
|
2821
3183
|
why: "obsidian peers on this exact version. Anything else fails npm install with ERESOLVE, and a second copy in the tree breaks editor extensions at runtime."
|
|
2822
3184
|
},
|
|
2823
3185
|
"@codemirror/view": {
|
|
2824
3186
|
check: `node -e "process.stdout.write(require('obsidian/package.json').peerDependencies['@codemirror/view'])"`,
|
|
2825
3187
|
checkRequires: "obsidian",
|
|
2826
|
-
expect: "6.
|
|
3188
|
+
expect: "6.43.13",
|
|
2827
3189
|
manualCheck: null,
|
|
2828
3190
|
needsOverride: true,
|
|
2829
3191
|
section: "devDependencies",
|
|
2830
|
-
version: "6.
|
|
3192
|
+
version: "6.43.13",
|
|
2831
3193
|
why: "obsidian peers on this exact version. Anything else fails npm install with ERESOLVE, and a second copy in the tree breaks editor extensions at runtime."
|
|
2832
3194
|
},
|
|
3195
|
+
"@wdio/cli": {
|
|
3196
|
+
check: `node -e "const fs=require('node:fs');process.stdout.write(JSON.parse(fs.readFileSync('node_modules/wdio-obsidian-service/package.json','utf8')).peerDependencies.webdriverio)"`,
|
|
3197
|
+
checkRequires: "wdio-obsidian-service",
|
|
3198
|
+
expect: "^9.18.1",
|
|
3199
|
+
manualCheck: null,
|
|
3200
|
+
needsOverride: false,
|
|
3201
|
+
section: "devDependencies",
|
|
3202
|
+
version: "^9.32.0",
|
|
3203
|
+
why: "wdio-obsidian-service peers on `webdriverio ^9.18.1`, while the registry tags wdio 10 as latest. Resolving latest installed a webdriverio 10 tree beside the service and failed `npm install` with ERESOLVE. The wdio packages move as one set, and the check reads the service's own peer range, so the pin retires itself when that moves to ^10."
|
|
3204
|
+
},
|
|
3205
|
+
"@wdio/globals": {
|
|
3206
|
+
check: `node -e "const fs=require('node:fs');process.stdout.write(JSON.parse(fs.readFileSync('node_modules/wdio-obsidian-service/package.json','utf8')).peerDependencies.webdriverio)"`,
|
|
3207
|
+
checkRequires: "wdio-obsidian-service",
|
|
3208
|
+
expect: "^9.18.1",
|
|
3209
|
+
manualCheck: null,
|
|
3210
|
+
needsOverride: false,
|
|
3211
|
+
section: "devDependencies",
|
|
3212
|
+
version: "^9.31.3",
|
|
3213
|
+
why: "wdio-obsidian-service peers on `webdriverio ^9.18.1`, while the registry tags wdio 10 as latest. Resolving latest installed a webdriverio 10 tree beside the service and failed `npm install` with ERESOLVE. The wdio packages move as one set, and the check reads the service's own peer range, so the pin retires itself when that moves to ^10."
|
|
3214
|
+
},
|
|
3215
|
+
"@wdio/local-runner": {
|
|
3216
|
+
check: `node -e "const fs=require('node:fs');process.stdout.write(JSON.parse(fs.readFileSync('node_modules/wdio-obsidian-service/package.json','utf8')).peerDependencies.webdriverio)"`,
|
|
3217
|
+
checkRequires: "wdio-obsidian-service",
|
|
3218
|
+
expect: "^9.18.1",
|
|
3219
|
+
manualCheck: null,
|
|
3220
|
+
needsOverride: false,
|
|
3221
|
+
section: "devDependencies",
|
|
3222
|
+
version: "^9.32.0",
|
|
3223
|
+
why: "wdio-obsidian-service peers on `webdriverio ^9.18.1`, while the registry tags wdio 10 as latest. Resolving latest installed a webdriverio 10 tree beside the service and failed `npm install` with ERESOLVE. The wdio packages move as one set, and the check reads the service's own peer range, so the pin retires itself when that moves to ^10."
|
|
3224
|
+
},
|
|
3225
|
+
"@wdio/mocha-framework": {
|
|
3226
|
+
check: `node -e "const fs=require('node:fs');process.stdout.write(JSON.parse(fs.readFileSync('node_modules/wdio-obsidian-service/package.json','utf8')).peerDependencies.webdriverio)"`,
|
|
3227
|
+
checkRequires: "wdio-obsidian-service",
|
|
3228
|
+
expect: "^9.18.1",
|
|
3229
|
+
manualCheck: null,
|
|
3230
|
+
needsOverride: false,
|
|
3231
|
+
section: "devDependencies",
|
|
3232
|
+
version: "^9.32.0",
|
|
3233
|
+
why: "wdio-obsidian-service peers on `webdriverio ^9.18.1`, while the registry tags wdio 10 as latest. Resolving latest installed a webdriverio 10 tree beside the service and failed `npm install` with ERESOLVE. The wdio packages move as one set, and the check reads the service's own peer range, so the pin retires itself when that moves to ^10."
|
|
3234
|
+
},
|
|
3235
|
+
"expect-webdriverio": {
|
|
3236
|
+
check: `node -e "const fs=require('node:fs');process.stdout.write(JSON.parse(fs.readFileSync('node_modules/wdio-obsidian-service/package.json','utf8')).peerDependencies.webdriverio)"`,
|
|
3237
|
+
checkRequires: "wdio-obsidian-service",
|
|
3238
|
+
expect: "^9.18.1",
|
|
3239
|
+
manualCheck: null,
|
|
3240
|
+
needsOverride: false,
|
|
3241
|
+
section: "devDependencies",
|
|
3242
|
+
version: "^6.1.0",
|
|
3243
|
+
why: "Held on 6.x with the wdio packages: expect-webdriverio 7 and later peer on `webdriverio ^10`, and @wdio/globals 9 peers on `expect-webdriverio ^6`. wdio-obsidian-service peers on `webdriverio ^9.18.1`, while the registry tags wdio 10 as latest. Resolving latest installed a webdriverio 10 tree beside the service and failed `npm install` with ERESOLVE. The wdio packages move as one set, and the check reads the service's own peer range, so the pin retires itself when that moves to ^10."
|
|
3244
|
+
},
|
|
2833
3245
|
"moment": {
|
|
2834
3246
|
check: null,
|
|
2835
3247
|
checkRequires: null,
|
|
@@ -2856,17 +3268,17 @@ var ADVISORY_OVERRIDES = {
|
|
|
2856
3268
|
check: `node -e "const fs=require('node:fs');process.stdout.write(JSON.parse(fs.readFileSync('node_modules/@wdio/utils/package.json','utf8')).dependencies['@puppeteer/browsers'])"`,
|
|
2857
3269
|
expect: "^2.2.0",
|
|
2858
3270
|
manualCheck: "The check reads @wdio/utils's own declared range, not a version, because that range is what makes the override necessary. When it moves to ^3 or later, @wdio/utils no longer pulls extract-zip in and both this override and this entry can go.",
|
|
2859
|
-
requires: ["obsidian-
|
|
3271
|
+
requires: ["obsidian-integration-testing", "wdio-obsidian-service"],
|
|
2860
3272
|
spec: "^3.2.1",
|
|
2861
3273
|
why: "Clears GHSA-jmr9-qjv8-65gv (extract-zip unvalidated symlink path traversal). extract-zip is vulnerable at every published version, so there is nothing to override it to, and the direct dependency cannot be bumped either: even the newest webdriverio reaches extract-zip through @wdio/utils -> @puppeteer/browsers ^2.x. @puppeteer/browsers@3 replaced extract-zip with modern-tar, so forcing 3.x on @wdio/utils, the only consumer left on 2.x, removes the subtree. @wdio/utils imports only install, canDownload, resolveBuildId, detectBrowserPlatform, Browser, ChromeReleaseChannel, computeExecutablePath and the InstallOptions type, all still exported by 3.x, and both packages are ESM-only. Never take the `npm audit fix --force` remedy: it downgrades obsidian-integration-testing to 1.1.2."
|
|
2862
3274
|
},
|
|
2863
3275
|
"deepmerge-ts": {
|
|
2864
|
-
check: `node -e "const fs=require('node:fs');process.stdout.write(JSON.parse(fs.readFileSync(
|
|
3276
|
+
check: `node -e "const fs=require('node:fs');const path=['node_modules/obsidian-integration-testing/node_modules/@wdio/utils/package.json','node_modules/@wdio/utils/package.json'].find((candidate)=>fs.existsSync(candidate));process.stdout.write(JSON.parse(fs.readFileSync(path,'utf8')).dependencies['deepmerge-ts'])"`,
|
|
2865
3277
|
expect: "^7.0.3",
|
|
2866
|
-
manualCheck: "The check reads the range @wdio/utils
|
|
2867
|
-
requires: ["obsidian-
|
|
3278
|
+
manualCheck: "The check reads the range declared by the @wdio/utils that obsidian-integration-testing reaches, nested under it when the project also has a newer wdio, which is what forces the override. When it moves to ^8 or later the override and this entry can go. Before lifting it, re-run the deepmergeCustom probe: @wdio/config passes a `mergeArrays` handler that reads `meta.key`, and that is the API 8.0.0 renamed.",
|
|
3279
|
+
requires: ["obsidian-integration-testing"],
|
|
2868
3280
|
spec: "^8.0.2",
|
|
2869
|
-
why: "Clears GHSA-ggr8-5vv4-36mx (stack exhaustion merging recursive object graphs), patched in 8.0.0.
|
|
3281
|
+
why: "Clears GHSA-ggr8-5vv4-36mx (stack exhaustion merging recursive object graphs), patched in 8.0.0. @wdio/utils declares ^7.0.3 up to 9.30, and obsidian-integration-testing pins webdriverio 9.27.0, so no direct bump reaches it and `npm audit fix --force` only offers a downgrade of obsidian-integration-testing to 1.1.2. The forced major is safe for these consumers: 8.0.0 breaks by renaming the mergeInfo system and aligning the customization shorthand, and both surfaces were measured to behave identically on 7.1.6 and 8.0.1 in the exact shapes the tree uses -- @wdio/config's `deepmergeCustom` with a `mergeArrays` handler reading `meta.key` and returning `utils.actions.defaultMerge`, and webdriver's `deepmergeCustom({ mergeArrays: false })`. A scan of the whole installed tree found no other binding than `deepmerge` and `deepmergeCustom`."
|
|
2870
3282
|
},
|
|
2871
3283
|
"serialize-javascript": {
|
|
2872
3284
|
check: `node -e "const fs=require('node:fs');process.stdout.write(JSON.parse(fs.readFileSync('node_modules/mocha/package.json','utf8')).dependencies['serialize-javascript'])"`,
|
|
@@ -2875,6 +3287,14 @@ var ADVISORY_OVERRIDES = {
|
|
|
2875
3287
|
requires: ["@wdio/mocha-framework"],
|
|
2876
3288
|
spec: "^7.1.1",
|
|
2877
3289
|
why: "Clears GHSA-5c6j-r48x-rmvq (RCE via RegExp.flags and Date.prototype.toISOString) and GHSA-qj8w-gfj5-8c6v (CPU-exhaustion denial of service via crafted array-likes), both fixed in 7.0.5. No direct bump reaches it: mocha declares `serialize-javascript@^6.0.2` at every published version including 11.8.0, and the only consumer here is @wdio/mocha-framework -> mocha. `npm audit fix --force` offers a DOWNGRADE to @wdio/mocha-framework@7.7.3 instead. The forced major is safe for the one call site that exists: mocha's `buffered-worker-pool.js` calls `serializeJavascript(opts, { unsafe: true, ignoreFunction: true })`, and 6.0.2 and 7.1.1 were measured to return byte-identical output for that exact option pair across RegExp, Date, Map, Set, undefined, BigInt, functions and a script-tag string. Note the call is on mocha's parallel-run path, which wdio does not take."
|
|
3290
|
+
},
|
|
3291
|
+
"smol-toml": {
|
|
3292
|
+
check: `node -e "const fs=require('node:fs');const path=['node_modules/@mnaoumov/typescript-dev-toolkit/node_modules/markdownlint-cli2/package.json','node_modules/markdownlint-cli2/package.json'].find((candidate)=>fs.existsSync(candidate));process.stdout.write(JSON.parse(fs.readFileSync(path,'utf8')).dependencies['smol-toml'])"`,
|
|
3293
|
+
expect: "1.8.0",
|
|
3294
|
+
manualCheck: "The check reads the exact version pinned by the markdownlint-cli2 that @mnaoumov/typescript-dev-toolkit reaches, nested under it when the project also declares a newer markdownlint-cli2, which is what makes the override necessary. When the toolkit moves to markdownlint-cli2 ^0.24.0 or later, that copy pins 1.9.1 and the override and this entry can go.",
|
|
3295
|
+
requires: ["@mnaoumov/obsidian-dev-toolkit", "@mnaoumov/typescript-dev-toolkit"],
|
|
3296
|
+
spec: "^1.9.1",
|
|
3297
|
+
why: "Clears GHSA-r4xh-jqrq-34v2 (quadratic-time parse() from parseKey rescanning to the end of the document), patched in 1.9.0. markdownlint-cli2 pinned `smol-toml` to exactly 1.8.0 up to 0.23.3, and @mnaoumov/typescript-dev-toolkit declares markdownlint-cli2 `^0.23.2`, which on a 0.x package stops below 0.24.0, the first release pinning 1.9.1. So the toolkit presets still reach 1.8.0 through the toolkit, and `npm audit fix --force` offers only a DOWNGRADE of markdownlint-cli2 to 0.21.0. The markdownlint answer's own markdownlint-cli2 resolves to 0.24.0 or later, so `standalone` needs no override. The spec stays inside the 1.x major, and markdownlint-cli2 imports only `parse`, to read a `.markdownlint-cli2.toml` config."
|
|
2878
3298
|
}
|
|
2879
3299
|
};
|
|
2880
3300
|
var DESKTOP_RELEASES_JSON_URL = "https://raw.githubusercontent.com/obsidianmd/obsidian-releases/master/desktop-releases.json";
|
|
@@ -2997,7 +3417,7 @@ async function resolveVersions(dependencies) {
|
|
|
2997
3417
|
resolved.set(packageName, `^${version}`);
|
|
2998
3418
|
}
|
|
2999
3419
|
if (failed.length > 0) {
|
|
3000
|
-
|
|
3420
|
+
log3.warn(`Could not look up the latest version of ${failed.join(", ")}. Falling back to "${FALLBACK_VERSION}".`);
|
|
3001
3421
|
}
|
|
3002
3422
|
return resolved;
|
|
3003
3423
|
}
|
|
@@ -3015,6 +3435,7 @@ function hasPackage(dependencies, packageName) {
|
|
|
3015
3435
|
var ASSET_EXTENSIONS = /* @__PURE__ */ new Set([".wasm"]);
|
|
3016
3436
|
var JSON_INDENT_SPACES3 = 2;
|
|
3017
3437
|
var UNRESOLVED_VERSION = "latest";
|
|
3438
|
+
var TOOLKIT_WORKFLOW_REF = "3.0.0";
|
|
3018
3439
|
var BASE_TEMPLATE_FILES = [
|
|
3019
3440
|
// Never empty: `tslib` and `typescript` below are false positives on every answer set.
|
|
3020
3441
|
".depcheckrc.json",
|
|
@@ -3023,6 +3444,9 @@ var BASE_TEMPLATE_FILES = [
|
|
|
3023
3444
|
".gitattributes",
|
|
3024
3445
|
".gitignore",
|
|
3025
3446
|
".npmrc",
|
|
3447
|
+
// The same Node major as this repo's own `.nvmrc`. Every CI workflow reads it, the toolkit's reusable ones by
|
|
3448
|
+
// Default, and without it they fall back to the latest LTS, which is not the version the project is developed on.
|
|
3449
|
+
".nvmrc",
|
|
3026
3450
|
"CONTRIBUTING.md",
|
|
3027
3451
|
"LICENSE",
|
|
3028
3452
|
"README.md",
|
|
@@ -3080,7 +3504,9 @@ var DEMO_OVERRIDES = [
|
|
|
3080
3504
|
{ answerKey: "spellChecker", demoValue: "cspell", options: SPELL_CHECKER_OPTIONS },
|
|
3081
3505
|
{ answerKey: "styling", demoValue: "scss", options: STYLING_OPTIONS }
|
|
3082
3506
|
];
|
|
3083
|
-
|
|
3507
|
+
var DEMO_PINNED_ANSWERS = { bundler: "esbuild", uiFramework: "none" };
|
|
3508
|
+
function buildTemplate(givenAnswers, overlay = null) {
|
|
3509
|
+
const answers = pinPresetAnswers(givenAnswers);
|
|
3084
3510
|
const builder = new TemplateBuilder();
|
|
3085
3511
|
builder.addFiles(BASE_TEMPLATE_FILES).addPackage("@types/node").addPackage("jiti").addPackage("obsidian").addPackage("tslib").addDepcheckIgnore("tslib", "never imported by name: `importHelpers: true` in `tsconfig.json` makes the compiled output import it.").addPackage("typescript").addDepcheckIgnore("typescript", "the compiler `tsconfig.json` configures, reached by `tsc`, by the TypeScript step of the bundler and by the editor rather than by an import.").addSentenceCaseBrand(answers.pluginName).addPartial("common");
|
|
3086
3512
|
const funding = resolveFunding(answers);
|
|
@@ -3114,40 +3540,45 @@ function buildTemplate(answers, overlay = null) {
|
|
|
3114
3540
|
builder.addPartial(option.partialName);
|
|
3115
3541
|
}
|
|
3116
3542
|
}
|
|
3543
|
+
if (builder.lintStagedPatterns.length > 0) {
|
|
3544
|
+
addStagedFilesHook(builder, answers.preset);
|
|
3545
|
+
}
|
|
3546
|
+
if (isFrameworkPreset(answers.preset) && builder.buildOptions.length > 0) {
|
|
3547
|
+
builder.addFiles(["scripts/build-options.ts"]);
|
|
3548
|
+
}
|
|
3117
3549
|
if (overlay) {
|
|
3118
3550
|
applyOverlay(builder, overlay);
|
|
3119
3551
|
}
|
|
3120
|
-
if (builder.lintStagedPatterns.length > 0) {
|
|
3121
|
-
addStagedFilesHook(builder);
|
|
3122
|
-
}
|
|
3123
3552
|
return builder;
|
|
3124
3553
|
}
|
|
3125
|
-
function copyTemplates(
|
|
3126
|
-
const
|
|
3554
|
+
function copyTemplates(givenAnswers, targetDir, currentVersion, existingConfig, resolvedVersions = /* @__PURE__ */ new Map(), minAppVersion = FALLBACK_MIN_APP_VERSION, overlay = null, projectFormatter) {
|
|
3555
|
+
const answers = pinPresetAnswers(givenAnswers);
|
|
3556
|
+
const templatesDir = join2(getScriptDir(), "..", "templates", "default");
|
|
3127
3557
|
function findTemplate(relativePath) {
|
|
3128
3558
|
if (overlay) {
|
|
3129
|
-
const overlayPath =
|
|
3130
|
-
if (
|
|
3559
|
+
const overlayPath = join2(overlay.dir, relativePath);
|
|
3560
|
+
if (existsSync3(overlayPath)) {
|
|
3131
3561
|
return overlayPath;
|
|
3132
3562
|
}
|
|
3133
3563
|
}
|
|
3134
|
-
const builtInPath =
|
|
3135
|
-
return
|
|
3564
|
+
const builtInPath = join2(templatesDir, relativePath);
|
|
3565
|
+
return existsSync3(builtInPath) ? builtInPath : null;
|
|
3136
3566
|
}
|
|
3137
|
-
const newConfig = {
|
|
3138
|
-
fileHashes: {},
|
|
3139
|
-
generatorVersion: currentVersion
|
|
3140
|
-
};
|
|
3141
3567
|
const builder = buildTemplate(answers, overlay);
|
|
3142
3568
|
const templateFiles = builder.templateFiles;
|
|
3143
3569
|
const partials = builder.partials;
|
|
3144
3570
|
const dependencies = builder.dependencies;
|
|
3571
|
+
const hasBuildOptions = templateFiles.has("scripts/build-options.ts");
|
|
3145
3572
|
let currentTemplatePath = "";
|
|
3146
3573
|
let renderRoot = "";
|
|
3147
3574
|
const templateContext = {
|
|
3148
3575
|
...answers,
|
|
3149
3576
|
...getFundingTemplateContext(answers),
|
|
3150
3577
|
_badges: builder.badges,
|
|
3578
|
+
_buildOptionsArgument: hasBuildOptions ? "buildOptions" : "",
|
|
3579
|
+
_buildOptionsImport: hasBuildOptions ? "\nimport { buildOptions } from './build-options.ts';\n" : "",
|
|
3580
|
+
_buildOptionsLiteral: toObjectLiteral(builder.buildOptions),
|
|
3581
|
+
_cspellIdentityWords: getCspellIdentityWords(answers),
|
|
3151
3582
|
_depcheckIgnores: builder.depcheckIgnores,
|
|
3152
3583
|
_dependencies: dependencies.map((dependency) => ({
|
|
3153
3584
|
packageName: dependency.packageName,
|
|
@@ -3161,6 +3592,8 @@ function copyTemplates(answers, targetDir, currentVersion, existingConfig, resol
|
|
|
3161
3592
|
_resolutions: Object.entries(buildResolutions(dependencies)).map(([packageName, spec]) => ({ packageName, spec })),
|
|
3162
3593
|
_scripts: builder.scripts,
|
|
3163
3594
|
_sentenceCaseBrands: builder.sentenceCaseBrands,
|
|
3595
|
+
_toolkitWorkflowRef: TOOLKIT_WORKFLOW_REF,
|
|
3596
|
+
_tsconfigExtendsJson: toTsconfigExtendsJson(builder.tsconfigExtends),
|
|
3164
3597
|
pluginShortName: getPluginShortName(answers.pluginId),
|
|
3165
3598
|
render(options) {
|
|
3166
3599
|
const { indentLevel, section } = typeof options === "string" ? { indentLevel: 0, section: options } : { indentLevel: 0, section: void 0, ...options };
|
|
@@ -3176,7 +3609,7 @@ function copyTemplates(answers, targetDir, currentVersion, existingConfig, resol
|
|
|
3176
3609
|
}
|
|
3177
3610
|
currentTemplatePath = partialPath;
|
|
3178
3611
|
renderRoot = previousRenderRoot || partialPath;
|
|
3179
|
-
let rendered = ejs.render(
|
|
3612
|
+
let rendered = ejs.render(readFileSync3(fullPath, "utf-8"), templateContext);
|
|
3180
3613
|
if (indentLevel > 0) {
|
|
3181
3614
|
const indent = " ".repeat(indentLevel);
|
|
3182
3615
|
rendered = rendered.replaceAll(/^(?<Content>.+)$/gm, `${indent}$<Content>`);
|
|
@@ -3192,7 +3625,7 @@ function copyTemplates(answers, targetDir, currentVersion, existingConfig, resol
|
|
|
3192
3625
|
*
|
|
3193
3626
|
* A section that contributes imports emits them in PARTIAL order, which is the order the answers were
|
|
3194
3627
|
* registered in {@link FEATURE_REGISTRIES} -- and that has nothing to do with the order an
|
|
3195
|
-
* import-sorting lint rule wants. The
|
|
3628
|
+
* import-sorting lint rule wants. The toolkit presets now adopt obsidian-dev-toolkit's shared
|
|
3196
3629
|
* ESLint config, which sorts imports as an ERROR, so `uiFramework=lit editorExtensions=codemirror`
|
|
3197
3630
|
* emitted a `src/plugin.ts` that was red the moment it was generated. The sorting cannot be pushed
|
|
3198
3631
|
* into the partials: each one knows only itself, and which others are beside it is the answer set.
|
|
@@ -3201,71 +3634,35 @@ function copyTemplates(answers, targetDir, currentVersion, existingConfig, resol
|
|
|
3201
3634
|
return sortImportStatements(text3);
|
|
3202
3635
|
}
|
|
3203
3636
|
};
|
|
3204
|
-
const
|
|
3205
|
-
const updated = [];
|
|
3206
|
-
const created = [];
|
|
3207
|
-
const written = [];
|
|
3637
|
+
const renderedFiles = [];
|
|
3208
3638
|
for (const registeredPath of templateFiles) {
|
|
3209
3639
|
const destinationPath = getDestinationPath(registeredPath, answers);
|
|
3210
|
-
const fullDestinationPath = join(targetDir, destinationPath);
|
|
3211
3640
|
const isAsset = ASSET_EXTENSIONS.has(extname(registeredPath));
|
|
3212
3641
|
const ejsPath = findTemplate(`${registeredPath}.ejs`);
|
|
3213
3642
|
let rendered;
|
|
3214
3643
|
if (isAsset) {
|
|
3215
3644
|
currentTemplatePath = registeredPath;
|
|
3216
|
-
rendered =
|
|
3645
|
+
rendered = readFileSync3(findTemplate(registeredPath) ?? join2(templatesDir, registeredPath));
|
|
3217
3646
|
} else if (ejsPath === null) {
|
|
3218
3647
|
currentTemplatePath = `${registeredPath}.ejs`;
|
|
3219
3648
|
rendered = templateContext["render"]();
|
|
3220
3649
|
} else {
|
|
3221
3650
|
currentTemplatePath = `${registeredPath}.ejs`;
|
|
3222
3651
|
try {
|
|
3223
|
-
rendered = ejs.render(
|
|
3652
|
+
rendered = ejs.render(readFileSync3(ejsPath, "utf-8"), templateContext);
|
|
3224
3653
|
} catch (error) {
|
|
3225
3654
|
if (overlay && ejsPath.startsWith(overlay.dir)) {
|
|
3226
3655
|
throw new Error(`${ejsPath} failed to render: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
3227
3656
|
}
|
|
3228
|
-
rendered =
|
|
3229
|
-
}
|
|
3230
|
-
}
|
|
3231
|
-
const newHash = sha256(rendered);
|
|
3232
|
-
if (existingConfig && existsSync2(fullDestinationPath)) {
|
|
3233
|
-
const currentContent = isAsset ? readFileSync2(fullDestinationPath) : readFileSync2(fullDestinationPath, "utf-8");
|
|
3234
|
-
const currentHash = sha256(currentContent);
|
|
3235
|
-
const originalHash = existingConfig.fileHashes[destinationPath];
|
|
3236
|
-
if (matchesRender(currentHash, newHash, projectFormatter, destinationPath, rendered)) {
|
|
3237
|
-
newConfig.fileHashes[destinationPath] = currentHash;
|
|
3238
|
-
continue;
|
|
3657
|
+
rendered = readFileSync3(ejsPath, "utf-8");
|
|
3239
3658
|
}
|
|
3240
|
-
if (originalHash === void 0) {
|
|
3241
|
-
skipped.push(destinationPath);
|
|
3242
|
-
continue;
|
|
3243
|
-
}
|
|
3244
|
-
if (currentHash !== originalHash) {
|
|
3245
|
-
skipped.push(destinationPath);
|
|
3246
|
-
newConfig.fileHashes[destinationPath] = originalHash;
|
|
3247
|
-
continue;
|
|
3248
|
-
}
|
|
3249
|
-
updated.push(destinationPath);
|
|
3250
|
-
} else {
|
|
3251
|
-
created.push(destinationPath);
|
|
3252
|
-
}
|
|
3253
|
-
newConfig.fileHashes[destinationPath] = newHash;
|
|
3254
|
-
const destDir = dirname(fullDestinationPath);
|
|
3255
|
-
if (!existsSync2(destDir)) {
|
|
3256
|
-
mkdirSync(destDir, { recursive: true });
|
|
3257
3659
|
}
|
|
3258
|
-
|
|
3259
|
-
written.push(destinationPath);
|
|
3660
|
+
renderedFiles.push({ content: rendered, destinationPath });
|
|
3260
3661
|
}
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
writeFileSync(configPath, `${JSON.stringify(newConfig, null, JSON_INDENT_SPACES3)}
|
|
3264
|
-
`);
|
|
3265
|
-
if (existingConfig) {
|
|
3266
|
-
logUpdateSummary(updated, created, skipped);
|
|
3662
|
+
if (answers.preset === DOCS_SHOWCASE_PRESET) {
|
|
3663
|
+
renderedFiles.push(...readDocsShowcaseFiles(join2(getScriptDir(), "..")));
|
|
3267
3664
|
}
|
|
3268
|
-
return
|
|
3665
|
+
return writeGeneratedFiles(renderedFiles, targetDir, currentVersion, existingConfig, projectFormatter);
|
|
3269
3666
|
}
|
|
3270
3667
|
function getDestinationPath(templatePath, answers) {
|
|
3271
3668
|
return templatePath.replace(/%= (?<AnswerKey>.+?) %/g, (_match, ...args) => String(answers[String(args[0])]));
|
|
@@ -3279,20 +3676,23 @@ function isPartialTemplatePath(templatePath) {
|
|
|
3279
3676
|
return markerIndex > 0 && PARTIAL_NAME_PATTERN.test(fileName.slice(markerIndex + 1));
|
|
3280
3677
|
}
|
|
3281
3678
|
function loadConfig(dir) {
|
|
3282
|
-
const configPath =
|
|
3283
|
-
if (!
|
|
3679
|
+
const configPath = join2(dir, CONFIG_FILE_NAME);
|
|
3680
|
+
if (!existsSync3(configPath)) {
|
|
3284
3681
|
return null;
|
|
3285
3682
|
}
|
|
3286
|
-
const parsed = JSON.parse(
|
|
3683
|
+
const parsed = JSON.parse(readFileSync3(configPath, "utf-8"));
|
|
3287
3684
|
const raw = parsed;
|
|
3288
3685
|
migrateAnswers(raw);
|
|
3289
3686
|
return parsed;
|
|
3290
3687
|
}
|
|
3688
|
+
function pinPresetAnswers(answers) {
|
|
3689
|
+
return answers.preset === "demo" ? { ...answers, ...DEMO_PINNED_ANSWERS } : answers;
|
|
3690
|
+
}
|
|
3291
3691
|
function recordHashesOnDisk(targetDir, config) {
|
|
3292
3692
|
const fileHashes = {};
|
|
3293
3693
|
for (const [destinationPath, hash] of Object.entries(config.fileHashes)) {
|
|
3294
|
-
const fullPath =
|
|
3295
|
-
fileHashes[destinationPath] =
|
|
3694
|
+
const fullPath = join2(targetDir, destinationPath);
|
|
3695
|
+
fileHashes[destinationPath] = existsSync3(fullPath) ? sha256(readFileSync3(fullPath)) : hash;
|
|
3296
3696
|
}
|
|
3297
3697
|
return { ...config, fileHashes };
|
|
3298
3698
|
}
|
|
@@ -3321,6 +3721,56 @@ function sortImportStatements(text3) {
|
|
|
3321
3721
|
return `${statements.join("\n")}
|
|
3322
3722
|
`;
|
|
3323
3723
|
}
|
|
3724
|
+
function writeGeneratedFiles(files, targetDir, currentVersion, existingConfig, projectFormatter) {
|
|
3725
|
+
const newConfig = {
|
|
3726
|
+
fileHashes: {},
|
|
3727
|
+
generatorVersion: currentVersion
|
|
3728
|
+
};
|
|
3729
|
+
const skipped = [];
|
|
3730
|
+
const updated = [];
|
|
3731
|
+
const created = [];
|
|
3732
|
+
const written = [];
|
|
3733
|
+
for (const { content: rendered, destinationPath } of files) {
|
|
3734
|
+
const fullDestinationPath = join2(targetDir, destinationPath);
|
|
3735
|
+
const newHash = sha256(rendered);
|
|
3736
|
+
if (existingConfig && existsSync3(fullDestinationPath)) {
|
|
3737
|
+
const currentContent = Buffer.isBuffer(rendered) ? readFileSync3(fullDestinationPath) : readFileSync3(fullDestinationPath, "utf-8");
|
|
3738
|
+
const currentHash = sha256(currentContent);
|
|
3739
|
+
const originalHash = existingConfig.fileHashes[destinationPath];
|
|
3740
|
+
if (matchesRender(currentHash, newHash, projectFormatter, destinationPath, rendered)) {
|
|
3741
|
+
newConfig.fileHashes[destinationPath] = currentHash;
|
|
3742
|
+
continue;
|
|
3743
|
+
}
|
|
3744
|
+
if (originalHash === void 0) {
|
|
3745
|
+
skipped.push(destinationPath);
|
|
3746
|
+
continue;
|
|
3747
|
+
}
|
|
3748
|
+
if (currentHash !== originalHash) {
|
|
3749
|
+
skipped.push(destinationPath);
|
|
3750
|
+
newConfig.fileHashes[destinationPath] = originalHash;
|
|
3751
|
+
continue;
|
|
3752
|
+
}
|
|
3753
|
+
updated.push(destinationPath);
|
|
3754
|
+
} else {
|
|
3755
|
+
created.push(destinationPath);
|
|
3756
|
+
}
|
|
3757
|
+
newConfig.fileHashes[destinationPath] = newHash;
|
|
3758
|
+
const destDir = dirname(fullDestinationPath);
|
|
3759
|
+
if (!existsSync3(destDir)) {
|
|
3760
|
+
mkdirSync(destDir, { recursive: true });
|
|
3761
|
+
}
|
|
3762
|
+
writeFileSync(fullDestinationPath, rendered);
|
|
3763
|
+
written.push(destinationPath);
|
|
3764
|
+
}
|
|
3765
|
+
formatWrittenFiles(projectFormatter, targetDir, written, newConfig);
|
|
3766
|
+
const configPath = join2(targetDir, CONFIG_FILE_NAME);
|
|
3767
|
+
writeFileSync(configPath, `${JSON.stringify(newConfig, null, JSON_INDENT_SPACES3)}
|
|
3768
|
+
`);
|
|
3769
|
+
if (existingConfig) {
|
|
3770
|
+
logUpdateSummary(updated, created, skipped);
|
|
3771
|
+
}
|
|
3772
|
+
return newConfig;
|
|
3773
|
+
}
|
|
3324
3774
|
function applyOverlay(builder, overlay) {
|
|
3325
3775
|
builder.addFiles([...overlay.files]);
|
|
3326
3776
|
for (const packageName of overlay.packages) {
|
|
@@ -3343,9 +3793,13 @@ function formatWrittenFiles(projectFormatter, targetDir, written, config) {
|
|
|
3343
3793
|
}
|
|
3344
3794
|
projectFormatter.formatFiles(textFiles);
|
|
3345
3795
|
for (const destinationPath of textFiles) {
|
|
3346
|
-
config.fileHashes[destinationPath] = sha256(
|
|
3796
|
+
config.fileHashes[destinationPath] = sha256(readFileSync3(join2(targetDir, destinationPath)));
|
|
3347
3797
|
}
|
|
3348
3798
|
}
|
|
3799
|
+
function getCspellIdentityWords(answers) {
|
|
3800
|
+
const words = [answers.authorGitHubName, "mnaoumov"];
|
|
3801
|
+
return words.filter((word, index) => words.findIndex((other) => other.toLowerCase() === word.toLowerCase()) === index);
|
|
3802
|
+
}
|
|
3349
3803
|
function getFundingTemplateContext(answers) {
|
|
3350
3804
|
const funding = resolveFunding(answers);
|
|
3351
3805
|
return {
|
|
@@ -3363,25 +3817,25 @@ function importedModule(block) {
|
|
|
3363
3817
|
}
|
|
3364
3818
|
function logUpdateSummary(updated, created, skipped) {
|
|
3365
3819
|
if (updated.length > 0) {
|
|
3366
|
-
|
|
3820
|
+
log4.success(`Updated ${String(updated.length)} file(s):`);
|
|
3367
3821
|
for (const f of updated) {
|
|
3368
|
-
|
|
3822
|
+
log4.info(` ${f}`);
|
|
3369
3823
|
}
|
|
3370
3824
|
}
|
|
3371
3825
|
if (created.length > 0) {
|
|
3372
|
-
|
|
3826
|
+
log4.success(`Created ${String(created.length)} new file(s):`);
|
|
3373
3827
|
for (const f of created) {
|
|
3374
|
-
|
|
3828
|
+
log4.info(` ${f}`);
|
|
3375
3829
|
}
|
|
3376
3830
|
}
|
|
3377
3831
|
if (skipped.length > 0) {
|
|
3378
|
-
|
|
3832
|
+
log4.warn(`Skipped ${String(skipped.length)} file(s) with local modifications:`);
|
|
3379
3833
|
for (const f of skipped) {
|
|
3380
|
-
|
|
3834
|
+
log4.info(` ${f}`);
|
|
3381
3835
|
}
|
|
3382
3836
|
}
|
|
3383
3837
|
if (updated.length === 0 && created.length === 0) {
|
|
3384
|
-
|
|
3838
|
+
log4.info("Everything is already up to date.");
|
|
3385
3839
|
}
|
|
3386
3840
|
}
|
|
3387
3841
|
function matchesRender(currentHash, newHash, projectFormatter, destinationPath, rendered) {
|
|
@@ -3416,6 +3870,11 @@ function migrateAnswers(raw) {
|
|
|
3416
3870
|
answers["fundingUsername"] ??= answers["authorGitHubName"];
|
|
3417
3871
|
answers["coverageBadge"] ??= "none";
|
|
3418
3872
|
delete answers["pluginShortName"];
|
|
3873
|
+
for (const [key, value] of Object.entries(answers)) {
|
|
3874
|
+
if (typeof value === "string") {
|
|
3875
|
+
answers[key] = resolveDeprecatedAnswer(key, value, CONFIG_FILE_NAME);
|
|
3876
|
+
}
|
|
3877
|
+
}
|
|
3419
3878
|
}
|
|
3420
3879
|
function migrateFundingAnswers(answers) {
|
|
3421
3880
|
if (answers["fundingPlatform"] !== void 0) {
|
|
@@ -3450,8 +3909,215 @@ function migrateFundingAnswers(answers) {
|
|
|
3450
3909
|
function sha256(content) {
|
|
3451
3910
|
return createHash("sha256").update(content).digest("hex");
|
|
3452
3911
|
}
|
|
3912
|
+
function toObjectLiteral(options) {
|
|
3913
|
+
return options.length === 0 ? "{}" : `{
|
|
3914
|
+
${options.map((option) => ` ${option.key}: ${option.value}`).join(",\n")}
|
|
3915
|
+
}`;
|
|
3916
|
+
}
|
|
3917
|
+
function toTsconfigExtendsJson(extraConfigs) {
|
|
3918
|
+
const base = JSON.stringify("@tsconfig/strictest/tsconfig.json");
|
|
3919
|
+
return extraConfigs.length === 0 ? base : `[
|
|
3920
|
+
${[base, ...extraConfigs.map((config) => JSON.stringify(config))].map((config) => ` ${config}`).join(",\n")}
|
|
3921
|
+
]`;
|
|
3922
|
+
}
|
|
3923
|
+
|
|
3924
|
+
// src/upstream-snapshot.ts
|
|
3925
|
+
import {
|
|
3926
|
+
existsSync as existsSync4,
|
|
3927
|
+
readdirSync as readdirSync2,
|
|
3928
|
+
readFileSync as readFileSync4
|
|
3929
|
+
} from "node:fs";
|
|
3930
|
+
import {
|
|
3931
|
+
join as join3,
|
|
3932
|
+
relative as relative2
|
|
3933
|
+
} from "node:path";
|
|
3934
|
+
var VENDORED_SUFFIX = ".vendored";
|
|
3935
|
+
var REGULAR_FILE_MODES = /* @__PURE__ */ new Set(["100644", "100755"]);
|
|
3936
|
+
async function fetchUpstreamSnapshot(repo, ref) {
|
|
3937
|
+
const headers = { Accept: "application/vnd.github+json" };
|
|
3938
|
+
const token = process.env["GITHUB_TOKEN"];
|
|
3939
|
+
if (token) {
|
|
3940
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
3941
|
+
}
|
|
3942
|
+
const commit = await fetchJson(`https://api.github.com/repos/${repo}/commits/${encodeURIComponent(ref)}`, headers);
|
|
3943
|
+
const tree = await fetchJson(`https://api.github.com/repos/${repo}/git/trees/${commit.sha}?recursive=1`, headers);
|
|
3944
|
+
if (tree.truncated) {
|
|
3945
|
+
throw new Error(`The tree of ${repo}@${commit.sha} is too large for one API response.`);
|
|
3946
|
+
}
|
|
3947
|
+
const paths = tree.tree.filter((entry) => entry.type === "blob" && REGULAR_FILE_MODES.has(entry.mode)).map((entry) => entry.path);
|
|
3948
|
+
const contents = await Promise.all(paths.map(async (path) => {
|
|
3949
|
+
const response = await fetch(`https://raw.githubusercontent.com/${repo}/${commit.sha}/${path.split("/").map(encodeURIComponent).join("/")}`);
|
|
3950
|
+
if (!response.ok) {
|
|
3951
|
+
throw new Error(`Could not download ${path} from ${repo}@${commit.sha}: HTTP ${String(response.status)}.`);
|
|
3952
|
+
}
|
|
3953
|
+
return Buffer.from(await response.arrayBuffer());
|
|
3954
|
+
}));
|
|
3955
|
+
return {
|
|
3956
|
+
commit: commit.sha,
|
|
3957
|
+
files: new Map(paths.map((path, index) => [path, contents[index] ?? Buffer.alloc(0)]))
|
|
3958
|
+
};
|
|
3959
|
+
}
|
|
3960
|
+
function readUpstream(upstreamsPath, name) {
|
|
3961
|
+
const parsed = JSON.parse(readFileSync4(upstreamsPath, "utf-8"));
|
|
3962
|
+
const upstream = parsed.upstreams.find((candidate) => candidate.name === name);
|
|
3963
|
+
if (!upstream) {
|
|
3964
|
+
throw new Error(`${upstreamsPath} has no upstream named "${name}".`);
|
|
3965
|
+
}
|
|
3966
|
+
return upstream;
|
|
3967
|
+
}
|
|
3968
|
+
function readVendoredFiles(dir) {
|
|
3969
|
+
const files = /* @__PURE__ */ new Map();
|
|
3970
|
+
if (!existsSync4(dir)) {
|
|
3971
|
+
return files;
|
|
3972
|
+
}
|
|
3973
|
+
const paths = readdirSync2(dir, { recursive: true, withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(VENDORED_SUFFIX)).map((entry) => join3(entry.parentPath, entry.name)).sort();
|
|
3974
|
+
for (const fullPath of paths) {
|
|
3975
|
+
const upstreamPath = relative2(dir, fullPath).replaceAll("\\", "/").slice(0, -VENDORED_SUFFIX.length);
|
|
3976
|
+
files.set(upstreamPath, readFileSync4(fullPath));
|
|
3977
|
+
}
|
|
3978
|
+
return files;
|
|
3979
|
+
}
|
|
3980
|
+
async function fetchJson(url, headers) {
|
|
3981
|
+
const response = await fetch(url, { headers });
|
|
3982
|
+
if (!response.ok) {
|
|
3983
|
+
throw new Error(`GET ${url} failed: HTTP ${String(response.status)}.`);
|
|
3984
|
+
}
|
|
3985
|
+
return await response.json();
|
|
3986
|
+
}
|
|
3987
|
+
|
|
3988
|
+
// src/official-sample.ts
|
|
3989
|
+
var OFFICIAL_SAMPLE_UPSTREAM_NAME = "obsidian-sample-plugin";
|
|
3990
|
+
var OFFICIAL_SAMPLE_FILES_DIR = join4("templates", "official-sample", "files");
|
|
3991
|
+
var OFFICIAL_SAMPLE_PINNED_ANSWERS = {
|
|
3992
|
+
formatter: "none",
|
|
3993
|
+
packageManager: "npm"
|
|
3994
|
+
};
|
|
3995
|
+
function applyOfficialSampleIdentity(files, answers) {
|
|
3996
|
+
const packageName = `obsidian-${answers.pluginId}`;
|
|
3997
|
+
const result = new Map(files);
|
|
3998
|
+
editJson(result, "manifest.json", (manifest) => {
|
|
3999
|
+
const fundingUrl = resolveFunding(answers)?.getUrl(answers);
|
|
4000
|
+
const edited = {};
|
|
4001
|
+
for (const [key, value] of Object.entries(manifest)) {
|
|
4002
|
+
switch (key) {
|
|
4003
|
+
case "author":
|
|
4004
|
+
edited[key] = answers.authorName;
|
|
4005
|
+
break;
|
|
4006
|
+
case "authorUrl":
|
|
4007
|
+
edited[key] = `https://github.com/${answers.authorGitHubName}`;
|
|
4008
|
+
break;
|
|
4009
|
+
case "description":
|
|
4010
|
+
edited[key] = answers.pluginDescription;
|
|
4011
|
+
break;
|
|
4012
|
+
case "fundingUrl":
|
|
4013
|
+
if (fundingUrl) {
|
|
4014
|
+
edited[key] = fundingUrl;
|
|
4015
|
+
}
|
|
4016
|
+
break;
|
|
4017
|
+
case "id":
|
|
4018
|
+
edited[key] = answers.pluginId;
|
|
4019
|
+
break;
|
|
4020
|
+
case "name":
|
|
4021
|
+
edited[key] = answers.pluginName;
|
|
4022
|
+
break;
|
|
4023
|
+
default:
|
|
4024
|
+
edited[key] = value;
|
|
4025
|
+
}
|
|
4026
|
+
}
|
|
4027
|
+
return edited;
|
|
4028
|
+
});
|
|
4029
|
+
const upstreamPackageName = readUpstreamPackageName(files);
|
|
4030
|
+
editJson(result, "package.json", (packageJson) => ({ ...packageJson, name: packageName }));
|
|
4031
|
+
editJson(result, "package-lock.json", (lock) => renamePackageInLock(lock, upstreamPackageName, packageName));
|
|
4032
|
+
const readme = result.get("README.md");
|
|
4033
|
+
if (readme) {
|
|
4034
|
+
result.set("README.md", Buffer.from(readme.toString("utf-8").replace(/^# .*$/m, `# ${answers.pluginName}`), "utf-8"));
|
|
4035
|
+
}
|
|
4036
|
+
return result;
|
|
4037
|
+
}
|
|
4038
|
+
function copyOfficialSample(answers, targetDir, currentVersion, existingConfig, snapshot) {
|
|
4039
|
+
const files = applyOfficialSampleIdentity(snapshot.files, answers);
|
|
4040
|
+
const config = writeGeneratedFiles(
|
|
4041
|
+
[...files].map(([destinationPath, content]) => ({ content, destinationPath })),
|
|
4042
|
+
targetDir,
|
|
4043
|
+
currentVersion,
|
|
4044
|
+
existingConfig
|
|
4045
|
+
);
|
|
4046
|
+
return { ...config, upstreamCommit: snapshot.commit };
|
|
4047
|
+
}
|
|
4048
|
+
function getPackageRoot() {
|
|
4049
|
+
return join4(getScriptDir(), "..");
|
|
4050
|
+
}
|
|
4051
|
+
function getUpstreamsPath() {
|
|
4052
|
+
return join4(getPackageRoot(), "upstreams.json");
|
|
4053
|
+
}
|
|
4054
|
+
function loadOfficialSampleSnapshot() {
|
|
4055
|
+
const upstream = readUpstream(getUpstreamsPath(), OFFICIAL_SAMPLE_UPSTREAM_NAME);
|
|
4056
|
+
const files = readVendoredFiles(join4(getPackageRoot(), OFFICIAL_SAMPLE_FILES_DIR));
|
|
4057
|
+
if (files.size === 0) {
|
|
4058
|
+
throw new Error(`The vendored snapshot of ${upstream.repo} is missing from ${OFFICIAL_SAMPLE_FILES_DIR}.`);
|
|
4059
|
+
}
|
|
4060
|
+
return { commit: upstream.commit, files };
|
|
4061
|
+
}
|
|
4062
|
+
function editJson(files, path, edit) {
|
|
4063
|
+
const content = files.get(path);
|
|
4064
|
+
if (!content) {
|
|
4065
|
+
return;
|
|
4066
|
+
}
|
|
4067
|
+
const text3 = content.toString("utf-8");
|
|
4068
|
+
const indent = /^\{\r?\n(?<Indent>[ \t]+)/.exec(text3)?.groups?.["Indent"] ?? " ";
|
|
4069
|
+
const finalNewline = /\r?\n$/.exec(text3)?.[0] ?? "";
|
|
4070
|
+
const edited = edit(JSON.parse(text3));
|
|
4071
|
+
files.set(path, Buffer.from(`${JSON.stringify(edited, null, indent)}${finalNewline}`, "utf-8"));
|
|
4072
|
+
}
|
|
4073
|
+
function readUpstreamPackageName(files) {
|
|
4074
|
+
const content = files.get("package.json");
|
|
4075
|
+
if (!content) {
|
|
4076
|
+
return void 0;
|
|
4077
|
+
}
|
|
4078
|
+
const name = JSON.parse(content.toString("utf-8"))["name"];
|
|
4079
|
+
return typeof name === "string" ? name : void 0;
|
|
4080
|
+
}
|
|
4081
|
+
function renamePackageInLock(lock, upstreamName, packageName) {
|
|
4082
|
+
const renamed = { ...lock };
|
|
4083
|
+
if (renamed["name"] === upstreamName) {
|
|
4084
|
+
renamed["name"] = packageName;
|
|
4085
|
+
}
|
|
4086
|
+
const packages = renamed["packages"];
|
|
4087
|
+
if (typeof packages === "object" && packages !== null) {
|
|
4088
|
+
const root = packages[""];
|
|
4089
|
+
if (typeof root === "object" && root !== null && root["name"] === upstreamName) {
|
|
4090
|
+
renamed["packages"] = { ...packages, "": { ...root, name: packageName } };
|
|
4091
|
+
}
|
|
4092
|
+
}
|
|
4093
|
+
return renamed;
|
|
4094
|
+
}
|
|
4095
|
+
|
|
4096
|
+
// src/overlay.ts
|
|
4097
|
+
import {
|
|
4098
|
+
existsSync as existsSync6,
|
|
4099
|
+
readdirSync as readdirSync4,
|
|
4100
|
+
readFileSync as readFileSync6,
|
|
4101
|
+
statSync as statSync2
|
|
4102
|
+
} from "node:fs";
|
|
4103
|
+
import {
|
|
4104
|
+
isAbsolute,
|
|
4105
|
+
join as join6,
|
|
4106
|
+
relative as relative3,
|
|
4107
|
+
resolve
|
|
4108
|
+
} from "node:path";
|
|
3453
4109
|
|
|
3454
4110
|
// src/plan-checks.ts
|
|
4111
|
+
import {
|
|
4112
|
+
existsSync as existsSync5,
|
|
4113
|
+
readdirSync as readdirSync3,
|
|
4114
|
+
readFileSync as readFileSync5,
|
|
4115
|
+
statSync
|
|
4116
|
+
} from "node:fs";
|
|
4117
|
+
import {
|
|
4118
|
+
extname as extname2,
|
|
4119
|
+
join as join5
|
|
4120
|
+
} from "node:path";
|
|
3455
4121
|
var EJS_SUFFIX = ".ejs";
|
|
3456
4122
|
var RENDER_SITE_PATTERN = /(?:<%[-=]?|\$\{)\s*render\(\s*(?:'(?<Section>[^']*)'|\{(?<Options>[^}]*)\})/g;
|
|
3457
4123
|
var SECTION_OPTION_PATTERN = /section\s*:\s*'(?<Section>[^']*)'/;
|
|
@@ -3485,7 +4151,7 @@ function loadTemplateInventory(templatesDir = defaultTemplatesDir()) {
|
|
|
3485
4151
|
continue;
|
|
3486
4152
|
}
|
|
3487
4153
|
const withoutSuffix = relativePath.slice(0, -EJS_SUFFIX.length);
|
|
3488
|
-
const body =
|
|
4154
|
+
const body = readFileSync5(join5(templatesDir, relativePath), "utf-8");
|
|
3489
4155
|
if (isPartialTemplatePath(relativePath)) {
|
|
3490
4156
|
partials.push(parsePartialPath(relativePath));
|
|
3491
4157
|
} else {
|
|
@@ -3538,7 +4204,7 @@ function parsePartialPath(relativePath) {
|
|
|
3538
4204
|
};
|
|
3539
4205
|
}
|
|
3540
4206
|
function defaultTemplatesDir() {
|
|
3541
|
-
return
|
|
4207
|
+
return join5(getScriptDir(), "..", "templates", "default");
|
|
3542
4208
|
}
|
|
3543
4209
|
function getRenderBase(templatePath) {
|
|
3544
4210
|
if (!isPartialTemplatePath(templatePath)) {
|
|
@@ -3548,14 +4214,14 @@ function getRenderBase(templatePath) {
|
|
|
3548
4214
|
return isPartialTemplatePath(basePath) ? getRenderBase(basePath) : templatePath;
|
|
3549
4215
|
}
|
|
3550
4216
|
function walkTemplates(templatesDir, relativeDir) {
|
|
3551
|
-
const absoluteDir =
|
|
3552
|
-
if (!
|
|
4217
|
+
const absoluteDir = join5(templatesDir, relativeDir);
|
|
4218
|
+
if (!existsSync5(absoluteDir)) {
|
|
3553
4219
|
return [];
|
|
3554
4220
|
}
|
|
3555
4221
|
const found = [];
|
|
3556
|
-
for (const entry of
|
|
4222
|
+
for (const entry of readdirSync3(absoluteDir)) {
|
|
3557
4223
|
const relativePath = relativeDir === "" ? entry : `${relativeDir}/${entry}`;
|
|
3558
|
-
if (statSync(
|
|
4224
|
+
if (statSync(join5(templatesDir, relativePath)).isDirectory()) {
|
|
3559
4225
|
found.push(...walkTemplates(templatesDir, relativePath));
|
|
3560
4226
|
} else {
|
|
3561
4227
|
found.push(relativePath);
|
|
@@ -3572,11 +4238,11 @@ var MANIFEST_KEYS = ["badges", "files", "packages", "partials"];
|
|
|
3572
4238
|
var PACKAGE_NAME_PATTERN = /^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
|
|
3573
4239
|
function loadOverlay(dir, builtIn = loadTemplateInventory()) {
|
|
3574
4240
|
const absoluteDir = resolve(dir);
|
|
3575
|
-
if (!
|
|
4241
|
+
if (!existsSync6(absoluteDir) || !statSync2(absoluteDir).isDirectory()) {
|
|
3576
4242
|
throw new Error(`Custom template directory not found: ${absoluteDir}`);
|
|
3577
4243
|
}
|
|
3578
|
-
const manifestPath =
|
|
3579
|
-
if (!
|
|
4244
|
+
const manifestPath = join6(absoluteDir, OVERLAY_MANIFEST_FILE_NAME);
|
|
4245
|
+
if (!existsSync6(manifestPath)) {
|
|
3580
4246
|
throw new Error(`Custom template directory has no ${OVERLAY_MANIFEST_FILE_NAME}: ${absoluteDir}`);
|
|
3581
4247
|
}
|
|
3582
4248
|
const manifest = readManifest(manifestPath);
|
|
@@ -3589,7 +4255,7 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
3589
4255
|
return overlay;
|
|
3590
4256
|
}
|
|
3591
4257
|
function toRecordedOverlayPath(overlayDir, projectDir) {
|
|
3592
|
-
const relativePath =
|
|
4258
|
+
const relativePath = relative3(projectDir, overlayDir);
|
|
3593
4259
|
return isAbsolute(relativePath) ? relativePath : relativePath.replaceAll("\\", "/");
|
|
3594
4260
|
}
|
|
3595
4261
|
function findManifestProblems(overlay, own, builtIn) {
|
|
@@ -3688,7 +4354,7 @@ function listStrayFiles(dir, own) {
|
|
|
3688
4354
|
function readManifest(manifestPath) {
|
|
3689
4355
|
let parsed;
|
|
3690
4356
|
try {
|
|
3691
|
-
parsed = JSON.parse(
|
|
4357
|
+
parsed = JSON.parse(readFileSync6(manifestPath, "utf-8"));
|
|
3692
4358
|
} catch {
|
|
3693
4359
|
throw new Error(`${manifestPath} is not valid JSON.`);
|
|
3694
4360
|
}
|
|
@@ -3717,9 +4383,9 @@ function readManifest(manifestPath) {
|
|
|
3717
4383
|
}
|
|
3718
4384
|
function walkFiles(root, relativeDir) {
|
|
3719
4385
|
const found = [];
|
|
3720
|
-
for (const entry of
|
|
4386
|
+
for (const entry of readdirSync4(join6(root, relativeDir))) {
|
|
3721
4387
|
const relativePath = relativeDir === "" ? entry : `${relativeDir}/${entry}`;
|
|
3722
|
-
if (statSync2(
|
|
4388
|
+
if (statSync2(join6(root, relativePath)).isDirectory()) {
|
|
3723
4389
|
found.push(...walkFiles(root, relativePath));
|
|
3724
4390
|
} else {
|
|
3725
4391
|
found.push(relativePath);
|
|
@@ -3731,10 +4397,10 @@ function walkFiles(root, relativeDir) {
|
|
|
3731
4397
|
// src/project-formatter.ts
|
|
3732
4398
|
import { spawnSync } from "node:child_process";
|
|
3733
4399
|
import {
|
|
3734
|
-
existsSync as
|
|
3735
|
-
readFileSync as
|
|
4400
|
+
existsSync as existsSync7,
|
|
4401
|
+
readFileSync as readFileSync7
|
|
3736
4402
|
} from "node:fs";
|
|
3737
|
-
import { join as
|
|
4403
|
+
import { join as join7 } from "node:path";
|
|
3738
4404
|
import process2 from "node:process";
|
|
3739
4405
|
var FORMATTER_COMMANDS = {
|
|
3740
4406
|
biome: {
|
|
@@ -3769,14 +4435,14 @@ function createProjectFormatter(targetDir, formatter) {
|
|
|
3769
4435
|
};
|
|
3770
4436
|
}
|
|
3771
4437
|
function resolveBin(targetDir, packageName) {
|
|
3772
|
-
const packageDir =
|
|
3773
|
-
const packageJsonPath =
|
|
3774
|
-
if (!
|
|
4438
|
+
const packageDir = join7(targetDir, "node_modules", packageName);
|
|
4439
|
+
const packageJsonPath = join7(packageDir, "package.json");
|
|
4440
|
+
if (!existsSync7(packageJsonPath)) {
|
|
3775
4441
|
return null;
|
|
3776
4442
|
}
|
|
3777
|
-
const { bin } = JSON.parse(
|
|
4443
|
+
const { bin } = JSON.parse(readFileSync7(packageJsonPath, "utf-8"));
|
|
3778
4444
|
const relativeBin = typeof bin === "string" ? bin : Object.values(bin ?? {})[0];
|
|
3779
|
-
return relativeBin === void 0 ? null :
|
|
4445
|
+
return relativeBin === void 0 ? null : join7(packageDir, relativeBin);
|
|
3780
4446
|
}
|
|
3781
4447
|
function runCli(binPath, targetDir, args, input) {
|
|
3782
4448
|
const result = spawnSync(process2.execPath, [binPath, ...args], { cwd: targetDir, encoding: "utf-8", input });
|
|
@@ -3786,7 +4452,22 @@ function runCli(binPath, targetDir, args, input) {
|
|
|
3786
4452
|
// src/main.ts
|
|
3787
4453
|
var ARGV_OFFSET = 2;
|
|
3788
4454
|
var JSON_INDENT_SPACES4 = 2;
|
|
4455
|
+
var SHORT_SHA_LENGTH = 7;
|
|
3789
4456
|
var SCRIPT_MODE = 493;
|
|
4457
|
+
function applyPresetFlags(answers, cliArgs, hasOverlay) {
|
|
4458
|
+
if (!isOfficialSamplePreset(answers.preset)) {
|
|
4459
|
+
if (cliArgs.latest) {
|
|
4460
|
+
exitWithUsageError(`--latest picks which upstream tree preset=official-sample copies, and the preset is ${answers.preset}.
|
|
4461
|
+
Drop --latest, or pass --preset=official-sample.`);
|
|
4462
|
+
}
|
|
4463
|
+
return answers;
|
|
4464
|
+
}
|
|
4465
|
+
if (hasOverlay) {
|
|
4466
|
+
exitWithUsageError(`--customTemplate layers over the built-in templates, and preset=official-sample renders none: it copies obsidianmd/obsidian-sample-plugin as it is.
|
|
4467
|
+
Drop --customTemplate, or choose another preset.`);
|
|
4468
|
+
}
|
|
4469
|
+
return { ...answers, ...OFFICIAL_SAMPLE_PINNED_ANSWERS };
|
|
4470
|
+
}
|
|
3790
4471
|
function assertManifestAnswersAreListable(answers) {
|
|
3791
4472
|
const problems = findUnlistableManifestAnswers(answers);
|
|
3792
4473
|
if (problems.length === 0) {
|
|
@@ -3802,7 +4483,7 @@ function buildSavedConfig(newConfig, answers, overlay, targetDir) {
|
|
|
3802
4483
|
async function checkForUpdates(currentVersion) {
|
|
3803
4484
|
const latestVer = await fetchLatestVersion("@mnaoumov/create-obsidian-plugin");
|
|
3804
4485
|
if (latestVer !== null && compare(currentVersion, latestVer) < 0) {
|
|
3805
|
-
|
|
4486
|
+
log5.warn(`Your version is outdated. Latest: ${latestVer}. Update with:
|
|
3806
4487
|
npm install -g @mnaoumov/create-obsidian-plugin`);
|
|
3807
4488
|
}
|
|
3808
4489
|
}
|
|
@@ -3810,8 +4491,8 @@ async function detectMode(cliArgs) {
|
|
|
3810
4491
|
if (cliArgs.mode) {
|
|
3811
4492
|
return cliArgs.mode;
|
|
3812
4493
|
}
|
|
3813
|
-
const configPath =
|
|
3814
|
-
if (
|
|
4494
|
+
const configPath = join8(process.cwd(), CONFIG_FILE_NAME);
|
|
4495
|
+
if (existsSync8(configPath)) {
|
|
3815
4496
|
if (cliArgs.useDefaults) {
|
|
3816
4497
|
exitWithUsageError(`Existing project detected (${CONFIG_FILE_NAME}), and --yes cannot ask whether to update it.
|
|
3817
4498
|
Pass --mode=update to update it, or --mode=create to scaffold a new plugin beside it.`);
|
|
@@ -3830,7 +4511,7 @@ async function ensurePluginIdIsUnlisted(answers, useDefaults) {
|
|
|
3830
4511
|
const listedIds = await fetchCommunityPluginIds();
|
|
3831
4512
|
if (listedIds === null) {
|
|
3832
4513
|
s.stop("Could not check the plugin id against the Community directory.");
|
|
3833
|
-
|
|
4514
|
+
log5.warn(`Could not fetch community-plugins.json, so "${answers.pluginId}" was not checked for a collision with a published plugin. The directory rejects a duplicate id, and an id can never be changed once published: check it by hand before submitting.`);
|
|
3834
4515
|
return answers;
|
|
3835
4516
|
}
|
|
3836
4517
|
const collision = validatePluginIdIsUnlisted(answers.pluginId, listedIds);
|
|
@@ -3843,7 +4524,7 @@ async function ensurePluginIdIsUnlisted(answers, useDefaults) {
|
|
|
3843
4524
|
exitWithUsageError(`${collision}.
|
|
3844
4525
|
Pass --pluginId=<value> to choose another.`);
|
|
3845
4526
|
}
|
|
3846
|
-
|
|
4527
|
+
log5.warn(collision);
|
|
3847
4528
|
const choice = await select2({
|
|
3848
4529
|
initialValue: "reenter",
|
|
3849
4530
|
message: `What should happen to "${answers.pluginId}"?`,
|
|
@@ -3901,6 +4582,10 @@ function exitWithUsageError(message) {
|
|
|
3901
4582
|
`);
|
|
3902
4583
|
process.exit(1);
|
|
3903
4584
|
}
|
|
4585
|
+
function hasPrepareScript(targetDir) {
|
|
4586
|
+
const packageJson = JSON.parse(readFileSync8(join8(targetDir, "package.json"), "utf-8"));
|
|
4587
|
+
return Object.hasOwn(packageJson.scripts ?? {}, "prepare");
|
|
4588
|
+
}
|
|
3904
4589
|
function loadOverlayOrExit(dir, hint = "") {
|
|
3905
4590
|
try {
|
|
3906
4591
|
return loadOverlay(dir);
|
|
@@ -3909,8 +4594,8 @@ function loadOverlayOrExit(dir, hint = "") {
|
|
|
3909
4594
|
}
|
|
3910
4595
|
}
|
|
3911
4596
|
async function main() {
|
|
3912
|
-
const packageJsonPath =
|
|
3913
|
-
const packageJson = JSON.parse(
|
|
4597
|
+
const packageJsonPath = join8(getScriptDir(), "..", "package.json");
|
|
4598
|
+
const packageJson = JSON.parse(readFileSync8(packageJsonPath, "utf-8"));
|
|
3914
4599
|
const currentVersion = packageJson.version ?? "0.0.0";
|
|
3915
4600
|
const m = "\x1B[38;5;135m";
|
|
3916
4601
|
const r = "\x1B[0m";
|
|
@@ -3965,16 +4650,16 @@ async function offerAnswersExport(answers, customTemplate) {
|
|
|
3965
4650
|
let choice = await ask();
|
|
3966
4651
|
while (choice !== "generate") {
|
|
3967
4652
|
if (choice === "script") {
|
|
3968
|
-
const scriptPath =
|
|
4653
|
+
const scriptPath = join8(process.cwd(), scriptName);
|
|
3969
4654
|
writeFileSync2(scriptPath, formatCreateScript(answers, shell, customTemplate));
|
|
3970
4655
|
if (shell === "sh") {
|
|
3971
4656
|
chmodSync(scriptPath, SCRIPT_MODE);
|
|
3972
4657
|
}
|
|
3973
|
-
|
|
4658
|
+
log5.success(`Wrote ${scriptName}`);
|
|
3974
4659
|
note(formatCreateCommand(answers, shell, customTemplate), "Non-interactive command");
|
|
3975
4660
|
} else {
|
|
3976
|
-
writeFileSync2(
|
|
3977
|
-
|
|
4661
|
+
writeFileSync2(join8(process.cwd(), answersFileName), formatAnswersJson(answers));
|
|
4662
|
+
log5.success(`Wrote ${answersFileName}`);
|
|
3978
4663
|
const overlayFlag = customTemplate ? ` --customTemplate=${customTemplate}` : "";
|
|
3979
4664
|
note(`npm create @mnaoumov/obsidian-plugin -- --yes --mode=create --answersFile=${answersFileName}${overlayFlag}`, "Non-interactive command");
|
|
3980
4665
|
}
|
|
@@ -3991,18 +4676,41 @@ async function resolveExternalVersions(answers, overlay) {
|
|
|
3991
4676
|
s.stop("Versions resolved.");
|
|
3992
4677
|
return { minAppVersion, resolvedVersions };
|
|
3993
4678
|
}
|
|
4679
|
+
async function resolveOfficialSampleSnapshot(latest) {
|
|
4680
|
+
const vendored = loadOfficialSampleSnapshot();
|
|
4681
|
+
if (!latest) {
|
|
4682
|
+
return vendored;
|
|
4683
|
+
}
|
|
4684
|
+
const upstream = readUpstream(getUpstreamsPath(), OFFICIAL_SAMPLE_UPSTREAM_NAME);
|
|
4685
|
+
const s = spinner();
|
|
4686
|
+
s.start(`Fetching ${upstream.repo}@${upstream.ref}...`);
|
|
4687
|
+
try {
|
|
4688
|
+
const snapshot = await fetchUpstreamSnapshot(upstream.repo, upstream.ref);
|
|
4689
|
+
s.stop(`Fetched ${upstream.repo} at ${snapshot.commit.slice(0, SHORT_SHA_LENGTH)}.`);
|
|
4690
|
+
return snapshot;
|
|
4691
|
+
} catch (error) {
|
|
4692
|
+
s.stop(`Could not fetch ${upstream.repo}.`);
|
|
4693
|
+
log5.warn(`${error instanceof Error ? error.message : String(error)}
|
|
4694
|
+
Using the snapshot this release vendored, ${vendored.commit.slice(0, SHORT_SHA_LENGTH)}.`);
|
|
4695
|
+
return vendored;
|
|
4696
|
+
}
|
|
4697
|
+
}
|
|
3994
4698
|
async function runCreate(currentVersion, cliArgs) {
|
|
3995
4699
|
const { answers: suppliedAnswers, customTemplate, useDefaults } = cliArgs;
|
|
3996
4700
|
const overlay = customTemplate ? loadOverlayOrExit(resolvePath(customTemplate)) : null;
|
|
3997
|
-
const answers =
|
|
3998
|
-
|
|
3999
|
-
|
|
4701
|
+
const answers = applyPresetFlags(
|
|
4702
|
+
await ensurePluginIdIsUnlisted(
|
|
4703
|
+
assertManifestAnswersAreListable(useDefaults ? getDefaultAnswers(suppliedAnswers) : await promptAnswers(suppliedAnswers)),
|
|
4704
|
+
useDefaults
|
|
4705
|
+
),
|
|
4706
|
+
cliArgs,
|
|
4707
|
+
overlay !== null
|
|
4000
4708
|
);
|
|
4001
4709
|
if (!useDefaults) {
|
|
4002
4710
|
await offerAnswersExport(answers, customTemplate);
|
|
4003
4711
|
}
|
|
4004
|
-
const targetDir =
|
|
4005
|
-
if (
|
|
4712
|
+
const targetDir = join8(process.cwd(), `obsidian-${answers.pluginId}`);
|
|
4713
|
+
if (existsSync8(targetDir) && !cliArgs.force) {
|
|
4006
4714
|
if (useDefaults) {
|
|
4007
4715
|
exitWithUsageError(`Directory obsidian-${answers.pluginId} already exists, and --yes cannot ask whether to scaffold into it.
|
|
4008
4716
|
Pass --force to scaffold into it anyway.`);
|
|
@@ -4017,19 +4725,28 @@ Pass --force to scaffold into it anyway.`);
|
|
|
4017
4725
|
process.exit(0);
|
|
4018
4726
|
}
|
|
4019
4727
|
}
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4728
|
+
let newConfig;
|
|
4729
|
+
if (isOfficialSamplePreset(answers.preset)) {
|
|
4730
|
+
const snapshot = await resolveOfficialSampleSnapshot(cliArgs.latest);
|
|
4731
|
+
const s = spinner();
|
|
4732
|
+
s.start("Copying the official sample plugin...");
|
|
4733
|
+
newConfig = copyOfficialSample(answers, targetDir, currentVersion, null, snapshot);
|
|
4734
|
+
s.stop(`Copied obsidianmd/obsidian-sample-plugin at ${snapshot.commit.slice(0, SHORT_SHA_LENGTH)}.`);
|
|
4735
|
+
} else {
|
|
4736
|
+
const { minAppVersion, resolvedVersions } = await resolveExternalVersions(answers, overlay);
|
|
4737
|
+
const s = spinner();
|
|
4738
|
+
s.start("Scaffolding plugin...");
|
|
4739
|
+
newConfig = copyTemplates(answers, targetDir, currentVersion, null, resolvedVersions, minAppVersion, overlay);
|
|
4740
|
+
s.stop("Plugin scaffolded.");
|
|
4741
|
+
}
|
|
4742
|
+
const configPath = join8(targetDir, CONFIG_FILE_NAME);
|
|
4025
4743
|
const configWithAnswers = buildSavedConfig(newConfig, answers, overlay, targetDir);
|
|
4026
4744
|
writeFileSync2(configPath, `${JSON.stringify(configWithAnswers, null, JSON_INDENT_SPACES4)}
|
|
4027
4745
|
`);
|
|
4028
|
-
s.stop("Plugin scaffolded.");
|
|
4029
4746
|
const isFormatted = useDefaults ? false : await runPostScaffold(targetDir, answers);
|
|
4030
4747
|
const pm = answers.packageManager;
|
|
4031
4748
|
const dirName = `obsidian-${answers.pluginId}`;
|
|
4032
|
-
const needsInstall = !
|
|
4749
|
+
const needsInstall = !existsSync8(join8(targetDir, "node_modules"));
|
|
4033
4750
|
const needsFormat = needsInitialFormat(answers.formatter) && !isFormatted;
|
|
4034
4751
|
const steps = [
|
|
4035
4752
|
...needsInstall ? [getInstallCommand(pm)] : [],
|
|
@@ -4047,8 +4764,8 @@ async function runInitialFormat(targetDir, answers, isInstalled) {
|
|
|
4047
4764
|
s.start("Formatting...");
|
|
4048
4765
|
try {
|
|
4049
4766
|
await execAsync(getRunCommand(answers.packageManager, "format"), targetDir);
|
|
4050
|
-
const configPath =
|
|
4051
|
-
const config = JSON.parse(
|
|
4767
|
+
const configPath = join8(targetDir, CONFIG_FILE_NAME);
|
|
4768
|
+
const config = JSON.parse(readFileSync8(configPath, "utf-8"));
|
|
4052
4769
|
writeFileSync2(configPath, `${JSON.stringify(recordHashesOnDisk(targetDir, config), null, JSON_INDENT_SPACES4)}
|
|
4053
4770
|
`);
|
|
4054
4771
|
s.stop("Formatted.");
|
|
@@ -4077,7 +4794,7 @@ async function runPostScaffold(targetDir, answers) {
|
|
|
4077
4794
|
} catch (error) {
|
|
4078
4795
|
s.stop(`Failed to install dependencies. Run \`${installCmd}\` manually.`);
|
|
4079
4796
|
if (error instanceof Error && "stderr" in error) {
|
|
4080
|
-
|
|
4797
|
+
log5.error(String(error.stderr));
|
|
4081
4798
|
}
|
|
4082
4799
|
}
|
|
4083
4800
|
}
|
|
@@ -4092,11 +4809,17 @@ async function runPostScaffold(targetDir, answers) {
|
|
|
4092
4809
|
s.start("Initializing git repository...");
|
|
4093
4810
|
try {
|
|
4094
4811
|
await execAsync(`git init -b ${answers.defaultBranch}`, targetDir);
|
|
4812
|
+
if (isInstalled && hasPrepareScript(targetDir)) {
|
|
4813
|
+
await execAsync(getRunCommand(pm, "prepare"), targetDir);
|
|
4814
|
+
}
|
|
4095
4815
|
await execAsync("git add -A", targetDir);
|
|
4096
|
-
await execAsync(
|
|
4816
|
+
await execAsync(`git commit -m "${INITIAL_COMMIT_MESSAGE}"`, targetDir);
|
|
4097
4817
|
s.stop("Git repository initialized with initial commit.");
|
|
4098
|
-
} catch {
|
|
4818
|
+
} catch (error) {
|
|
4099
4819
|
s.stop("Failed to initialize git. Run `git init` manually.");
|
|
4820
|
+
if (error instanceof Error && "stderr" in error) {
|
|
4821
|
+
log5.error(String(error.stderr));
|
|
4822
|
+
}
|
|
4100
4823
|
}
|
|
4101
4824
|
}
|
|
4102
4825
|
const shouldCreateGitHubRepo = await confirm({
|
|
@@ -4121,10 +4844,10 @@ async function runUpdate(currentVersion, cliArgs) {
|
|
|
4121
4844
|
const targetDir = process.cwd();
|
|
4122
4845
|
const existingConfig = loadConfig(targetDir);
|
|
4123
4846
|
if (!existingConfig) {
|
|
4124
|
-
|
|
4847
|
+
log5.error("No config file found. Cannot update.");
|
|
4125
4848
|
process.exit(1);
|
|
4126
4849
|
}
|
|
4127
|
-
|
|
4850
|
+
log5.info(`Current project was generated with v${existingConfig.generatorVersion}`);
|
|
4128
4851
|
let overlay = null;
|
|
4129
4852
|
if (customTemplate !== void 0) {
|
|
4130
4853
|
overlay = customTemplate ? loadOverlayOrExit(resolvePath(customTemplate)) : null;
|
|
@@ -4134,21 +4857,21 @@ async function runUpdate(currentVersion, cliArgs) {
|
|
|
4134
4857
|
`
|
|
4135
4858
|
This project records it in ${CONFIG_FILE_NAME}. Pass --customTemplate=<dir> to point at where it is now, or --customTemplate= to stop using it.`
|
|
4136
4859
|
);
|
|
4137
|
-
|
|
4860
|
+
log5.info(`Applying the custom template recorded for this project: ${existingConfig.customTemplate}`);
|
|
4138
4861
|
}
|
|
4139
|
-
const configPath =
|
|
4140
|
-
const savedConfig = JSON.parse(
|
|
4862
|
+
const configPath = join8(targetDir, CONFIG_FILE_NAME);
|
|
4863
|
+
const savedConfig = JSON.parse(readFileSync8(configPath, "utf-8"));
|
|
4141
4864
|
let answers;
|
|
4142
4865
|
if (savedConfig.answers) {
|
|
4143
4866
|
const saved = { ...savedConfig.answers, ...suppliedAnswers };
|
|
4144
|
-
|
|
4867
|
+
log5.info("Using saved answers from previous generation.");
|
|
4145
4868
|
const shouldRePrompt = useDefaults ? false : await confirm({
|
|
4146
4869
|
initialValue: false,
|
|
4147
4870
|
message: "Would you like to change any settings?"
|
|
4148
4871
|
});
|
|
4149
4872
|
assertNotCancelled(shouldRePrompt);
|
|
4150
4873
|
if (shouldRePrompt) {
|
|
4151
|
-
answers = await promptAnswers(saved);
|
|
4874
|
+
answers = await promptAnswers(saved, suppliedAnswers);
|
|
4152
4875
|
} else {
|
|
4153
4876
|
answers = saved;
|
|
4154
4877
|
}
|
|
@@ -4157,17 +4880,29 @@ This project records it in ${CONFIG_FILE_NAME}. Pass --customTemplate=<dir> to p
|
|
|
4157
4880
|
exitWithUsageError(`${CONFIG_FILE_NAME} records no answers, so --yes has none to reuse.
|
|
4158
4881
|
Run without --yes to answer them again.`);
|
|
4159
4882
|
}
|
|
4160
|
-
|
|
4883
|
+
log5.warn("No saved answers found. Please provide the settings again.");
|
|
4161
4884
|
answers = await promptAnswers(suppliedAnswers);
|
|
4162
4885
|
}
|
|
4163
4886
|
const savedPluginId = savedConfig.answers?.pluginId;
|
|
4164
4887
|
if (savedPluginId !== void 0 && answers.pluginId !== savedPluginId) {
|
|
4165
4888
|
answers = await ensurePluginIdIsUnlisted(answers, useDefaults);
|
|
4166
4889
|
}
|
|
4890
|
+
answers = applyPresetFlags(answers, cliArgs, overlay !== null);
|
|
4891
|
+
if (isOfficialSamplePreset(answers.preset)) {
|
|
4892
|
+
const snapshot = await resolveOfficialSampleSnapshot(cliArgs.latest);
|
|
4893
|
+
const s2 = spinner();
|
|
4894
|
+
s2.start("Updating project files...");
|
|
4895
|
+
const newConfig2 = copyOfficialSample(answers, targetDir, currentVersion, existingConfig, snapshot);
|
|
4896
|
+
writeFileSync2(configPath, `${JSON.stringify({ ...newConfig2, answers }, null, JSON_INDENT_SPACES4)}
|
|
4897
|
+
`);
|
|
4898
|
+
s2.stop(`Update complete: obsidianmd/obsidian-sample-plugin at ${snapshot.commit.slice(0, SHORT_SHA_LENGTH)}.`);
|
|
4899
|
+
outro("Project updated successfully!");
|
|
4900
|
+
return;
|
|
4901
|
+
}
|
|
4167
4902
|
const { minAppVersion, resolvedVersions } = await resolveExternalVersions(answers, overlay);
|
|
4168
4903
|
const projectFormatter = createProjectFormatter(targetDir, answers.formatter);
|
|
4169
4904
|
if (projectFormatter === null && needsInitialFormat(answers.formatter)) {
|
|
4170
|
-
|
|
4905
|
+
log5.warn(`${answers.formatter} is not installed, so the update cannot tell the files it formatted from hand edits and skips them. Install the dependencies and update again to have them updated.`);
|
|
4171
4906
|
}
|
|
4172
4907
|
const s = spinner();
|
|
4173
4908
|
s.start("Updating project files...");
|