@meith/plugin-kit 0.17.0 → 0.17.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meith/plugin-kit",
3
- "version": "0.17.0",
3
+ "version": "0.17.2",
4
4
  "description": "The SDK for writing a Meith plugin: typed manifests, hooks, routes, pages and migrations.",
5
5
  "license": "LGPL-3.0-or-later",
6
6
  "repository": {
@@ -20,8 +20,8 @@
20
20
  "access": "public"
21
21
  },
22
22
  "dependencies": {
23
- "@meith/core": "^0.17.0",
24
- "@meith/theme-kit": "^0.17.0"
23
+ "@meith/core": "^0.17.2",
24
+ "@meith/theme-kit": "^0.17.2"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "react": "^19.2.0"
package/src/plugin.ts CHANGED
@@ -231,7 +231,13 @@ export interface PluginDefinition {
231
231
  readonly onUninstall?: ((context: PluginRuntimeContext) => Promise<void> | void) | undefined
232
232
  }
233
233
 
234
- const KEY_PATTERN = /^[a-z][a-z0-9-]{1,39}$/
234
+ /**
235
+ * The rule a plugin key (and, by marketplace-gen.mjs's own mirrored copy, a
236
+ * marketplace listing key) has to satisfy. Exported so
237
+ * scripts/marketplace-gen.test.ts can pin its own copy directly against
238
+ * this one rather than trusting the two stay in sync by comment alone.
239
+ */
240
+ export const KEY_PATTERN = /^[a-z][a-z0-9-]{1,39}$/
235
241
  const SETTING_KEY_PATTERN = /^[a-z][a-z0-9_]{1,39}$/
236
242
  const MIGRATION_ID_PATTERN = /^\d{4}_[a-z0-9_]{1,60}$/
237
243
  const TASK_ID_PATTERN = /^[a-z][a-z0-9-]{1,39}$/
package/src/settings.ts CHANGED
@@ -47,6 +47,20 @@ export function parsePluginSetting(setting: PluginSetting, raw: string): PluginS
47
47
  return raw
48
48
  }
49
49
 
50
+ /**
51
+ * Matches a candidate select value against a setting's declared options —
52
+ * trimmed and case-insensitively — and returns the *option's own* casing.
53
+ * See "Settings" in docs/plugin-api.md.
54
+ */
55
+ function matchSelectOption(
56
+ options: readonly { readonly value: string }[],
57
+ candidate: PluginSettingValue | null,
58
+ ): string | undefined {
59
+ if (typeof candidate !== 'string') return undefined
60
+ const normalised = candidate.trim().toLowerCase()
61
+ return options.find((option) => option.value.toLowerCase() === normalised)?.value
62
+ }
63
+
50
64
  function resolveOne(
51
65
  plugin: PluginDefinition,
52
66
  setting: PluginSetting,
@@ -74,9 +88,14 @@ function resolveOne(
74
88
  source = 'default'
75
89
  }
76
90
 
77
- if (type === 'select' && !(setting.options ?? []).some((option) => option.value === value)) {
78
- value = setting.default
79
- source = 'default'
91
+ if (type === 'select') {
92
+ const matched = matchSelectOption(setting.options ?? [], value)
93
+ if (matched === undefined) {
94
+ value = setting.default
95
+ source = 'default'
96
+ } else {
97
+ value = matched
98
+ }
80
99
  }
81
100
 
82
101
  const problem =