@open-mercato/cli 0.6.1-develop.3276.1.1fcd145078 → 0.6.1-develop.3287.1.450f4ffb56

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.
@@ -68,13 +68,35 @@ Complete reference of all available UI components in `@open-mercato/ui`.
68
68
 
69
69
  ### Input Components (`@open-mercato/ui/backend/inputs/*`)
70
70
 
71
+ Specialized inputs that ship with the framework. For each, the full props table, MUST rules, and anti-patterns live in `.ai/ui-components.md` under the section linked from the component name.
72
+
73
+ | Component | Import Path | Purpose | Key Props |
74
+ |-----------|-------------|---------|-----------|
75
+ | **ComboboxInput** | `@open-mercato/ui/backend/inputs/ComboboxInput` | Single-value typeahead with sync/async suggestions; allows free-form custom values by default | `value`, `onChange`, `suggestions`, `loadSuggestions`, `resolveLabel`, `allowCustomValues` |
76
+ | **TagsInput** | `@open-mercato/ui/backend/inputs/TagsInput` | Multi-value (`string[]`) version of `ComboboxInput` with rich `{ value, label, description }` triples | `value`, `onChange`, `suggestions`, `loadSuggestions`, `selectedOptions`, `resolveLabel` |
77
+ | **LookupSelect** | `@open-mercato/ui/backend/inputs/LookupSelect` | Rich card-list search/select with title/subtitle/icon/badge per row; returns selected id | `value`, `onChange`, `fetchItems`, `options`, `minQuery`, `actionSlot` |
78
+ | **PhoneNumberField** | `@open-mercato/ui/backend/inputs/PhoneNumberField` | Compound country-picker + national-number input matching Figma `Text Input [1.1]` Phone variant. Validates + normalizes on blur, optional duplicate lookup | `value`, `onValueChange`, `onDigitsChange`, `countries`, `defaultCountryIso2`, `onDuplicateLookup` |
79
+ | **EventSelect** | `@open-mercato/ui/backend/inputs/EventSelect` | Strict select for declared platform events, grouped by module. **Mandated by `packages/ui/AGENTS.md`** for event selection | `value`, `onChange`, `categories`, `modules`, `excludeTriggerExcluded`, `size` |
80
+ | **EventPatternInput** | `@open-mercato/ui/backend/inputs/EventPatternInput` | `ComboboxInput` preloaded with declared events that allows wildcard patterns (e.g. `sales.orders.*`) | `value`, `onChange`, `categories`, `modules` |
81
+ | **TimeInput** | `@open-mercato/ui/backend/inputs/TimeInput` | Bare `HH:MM` editor (two `<input type="number">` cells, no popover). Low-level atom — most flows want `TimePicker` | `value`, `onChange`, `minuteStep`, `hourLabel`, `minuteLabel` |
82
+ | **DatePicker** *(@deprecated shim — import from `primitives/date-picker`)* | `@open-mercato/ui/backend/inputs/DatePicker` | Backward-compat re-export of the `DatePicker` primitive. New code MUST import from `@open-mercato/ui/primitives/date-picker`. | — |
83
+ | **DateTimePicker** *(@deprecated shim — use `DatePicker withTime`)* | `@open-mercato/ui/backend/inputs/DateTimePicker` | Thin wrapper that always sets `withTime` on the primitive. New code: `<DatePicker withTime />` | — |
84
+ | **TimePicker** *(@deprecated shim — import from `primitives/time-picker`)* | `@open-mercato/ui/backend/inputs/TimePicker` | Legacy popover-anchored time picker wrapping the new `TimePicker` primitive. New code: `@open-mercato/ui/primitives/time-picker`. | — |
85
+ | **SwitchableMarkdownInput** *(@deprecated — use `RichEditor`)* | `@open-mercato/ui/backend/inputs/SwitchableMarkdownInput` | Markdown ⇄ plain textarea toggle. Kept only for backward compatibility with Markdown-backed surfaces. New rich-text fields MUST use `RichEditor` from `@open-mercato/ui/primitives/rich-editor` (sanitized HTML). | `value`, `onChange`, `isMarkdownEnabled` |
86
+
87
+ ### Input Variants (Figma `Text Input [1.1]` — `@open-mercato/ui/primitives/*`)
88
+
89
+ Foundation-level input variants matching Figma type-specific designs. Use these instead of raw `<Input type="email">`, `<Input type="password">`, etc. — they ship correct visual chrome (leading icons, prefix boxes, trailing buttons, brand badges) and i18n-resolved labels.
90
+
71
91
  | Component | Import Path | Purpose | Key Props |
72
92
  |-----------|-------------|---------|-----------|
73
- | **TagsInput** | `@open-mercato/ui/backend/inputs/TagsInput` | Multi-tag input with suggestions | `value`, `onChange`, `placeholder`, `suggestions` |
74
- | **ComboboxInput** | `@open-mercato/ui/backend/inputs/ComboboxInput` | Searchable dropdown (single value) | `value`, `onChange`, `options`, `placeholder` |
75
- | **PhoneNumberField** | `@open-mercato/ui/backend/inputs/PhoneNumberField` | Phone input with formatting | `value`, `onChange`, `checkDuplicate` |
76
- | **LookupSelect** | `@open-mercato/ui/backend/inputs/LookupSelect` | Async lookup/search select | `value`, `onChange`, `onSearch`, `renderItem` |
77
- | **SwitchableMarkdownInput** | `@open-mercato/ui/backend/inputs/SwitchableMarkdownInput` | Text/markdown toggle input | `value`, `onChange`, `placeholder` |
93
+ | **EmailInput** | `@open-mercato/ui/primitives/email-input` | `Input` wrapper with leading Mail icon, `type="email"`, `autoComplete="email"` | `value`, `onChange`, `showIcon` |
94
+ | **SearchInput** | `@open-mercato/ui/primitives/search-input` | Leading Search icon + trailing × clear button (when value non-empty). Use for DataTable global filter, command palette, list-view live filter | `value`, `onChange`, `onClear`, `clearable` |
95
+ | **PasswordInput** | `@open-mercato/ui/primitives/password-input` | Leading Lock icon + trailing Eye/EyeOff reveal toggle. Controlled or uncontrolled reveal state | `value`, `onChange`, `revealable`, `revealed`, `onRevealedChange`, `showLockIcon` |
96
+ | **WebsiteInput** | `@open-mercato/ui/primitives/website-input` | Left "https://" prefix box + divider + URL input. `type="url"` | `value`, `onChange`, `prefix`, `showPrefix` |
97
+ | **AmountInput** | `@open-mercato/ui/primitives/amount-input` | Leading currency symbol + numeric input + trailing ISO currency picker (10 markets default) | `value: { amount, currency }`, `onChange`, `currencies`, `showCurrency` |
98
+ | **ButtonInput** | `@open-mercato/ui/primitives/button-input` | Input with optional `leftIcon` + divider + required `trailingAction` slot for interactive button (copy URL, send, regenerate) | `leftIcon`, `trailingAction` (required) |
99
+ | **CardInput** | `@open-mercato/ui/primitives/card-input` | Credit-card-number input with regex-based brand auto-detection (Visa/MC/Amex/Discover/Diners/JCB/UnionPay), format masking, brand badge | `value` (digits-only), `onChange`, `onBrandChange`, `brands` |
78
100
 
79
101
  ### Detail Page Components (`@open-mercato/ui/backend/detail/*`)
80
102
 
@@ -11,7 +11,7 @@ import { ensureModuleRegistration } from "./modules-config.js";
11
11
  import { resolveSpawnCommand } from "./spawn.js";
12
12
  const SAFE_PACKAGE_SPEC_PATTERN = /^@open-mercato\/[a-z0-9][a-z0-9-]*(?:@.+)?$/i;
13
13
  const SAFE_PACKAGE_TAG_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
14
- const SAFE_PACKAGE_FILE_LOCATOR_PATTERN = /^file:[A-Za-z0-9_./:\\-]+$/;
14
+ const SAFE_PACKAGE_FILE_LOCATOR_PATTERN = /^file:[A-Za-z0-9_./: \\-]+$/;
15
15
  function resolveYarnBinary() {
16
16
  return process.platform === "win32" ? "yarn.cmd" : "yarn";
17
17
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/module-install.ts"],
4
- "sourcesContent": ["import fs from 'node:fs'\nimport path from 'node:path'\nimport spawn from 'cross-spawn'\nimport { copyDirRecursive, rewriteCrossModuleImports } from './eject'\nimport {\n parsePackageNameFromSpec,\n resolveInstalledOfficialModulePackage,\n validateEjectBoundaries,\n type ValidatedOfficialModulePackage,\n} from './module-package'\nimport { ensureModuleRegistration } from './modules-config'\nimport type { PackageResolver } from './resolver'\nimport { resolveSpawnCommand } from './spawn'\n\ntype ModuleCommandResult = {\n moduleId: string\n packageName: string\n from: string\n registrationChanged: boolean\n}\n\ntype InstallTarget = {\n cwd: string\n args: string[]\n}\n\nconst SAFE_PACKAGE_SPEC_PATTERN = /^@open-mercato\\/[a-z0-9][a-z0-9-]*(?:@.+)?$/i\nconst SAFE_PACKAGE_TAG_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/\nconst SAFE_PACKAGE_FILE_LOCATOR_PATTERN = /^file:[A-Za-z0-9_./:\\\\-]+$/\n\nfunction resolveYarnBinary(): string {\n return process.platform === 'win32' ? 'yarn.cmd' : 'yarn'\n}\n\nfunction readAppPackageName(appDir: string): string {\n const packageJsonPath = path.join(appDir, 'package.json')\n if (!fs.existsSync(packageJsonPath)) {\n throw new Error(`App package.json not found at ${packageJsonPath}.`)\n }\n\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) as { name?: string }\n if (!packageJson.name) {\n throw new Error(`App package.json at ${packageJsonPath} is missing the \"name\" field.`)\n }\n\n return packageJson.name\n}\n\nfunction resolveInstallTarget(resolver: PackageResolver): InstallTarget {\n if (!resolver.isMonorepo()) {\n return {\n cwd: resolver.getAppDir(),\n args: ['add'],\n }\n }\n\n return {\n cwd: resolver.getRootDir(),\n args: ['workspace', readAppPackageName(resolver.getAppDir()), 'add'],\n }\n}\n\nfunction runCommand(\n command: string,\n args: string[],\n cwd: string,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const resolvedSpawn = resolveSpawnCommand(command, args)\n const child = spawn(resolvedSpawn.command, resolvedSpawn.args, {\n cwd,\n env: process.env,\n stdio: 'inherit',\n ...resolvedSpawn.spawnOptions,\n })\n\n child.on('error', reject)\n child.on('exit', (code) => {\n if (code === 0) {\n resolve()\n return\n }\n\n reject(new Error(`Command failed: ${command} ${args.join(' ')} (exit ${code ?? 'unknown'}).`))\n })\n })\n}\n\nasync function installPackageSpec(\n resolver: PackageResolver,\n packageSpec: string,\n): Promise<void> {\n const target = resolveInstallTarget(resolver)\n await runCommand(resolveYarnBinary(), [...target.args, packageSpec], target.cwd)\n}\n\nexport async function runModuleGenerators(\n resolver: PackageResolver,\n quiet = true,\n): Promise<void> {\n const {\n generateEntityIds,\n generateModuleDi,\n generateModuleEntities,\n generateModulePackageSources,\n generateModuleRegistry,\n generateModuleRegistryApp,\n generateModuleRegistryCli,\n generateOpenApi,\n } = await import('./generators')\n\n await generateEntityIds({ resolver, quiet })\n await generateModuleRegistry({ resolver, quiet })\n await generateModuleRegistryApp({ resolver, quiet })\n await generateModuleRegistryCli({ resolver, quiet })\n await generateModuleEntities({ resolver, quiet })\n await generateModuleDi({ resolver, quiet })\n await generateModulePackageSources({ resolver, quiet })\n await generateOpenApi({ resolver, quiet })\n}\n\nasync function runGeneratorsWithRegistrationNotice(\n resolver: PackageResolver,\n moduleId: string,\n): Promise<void> {\n try {\n await runModuleGenerators(resolver)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new Error(\n `Module \"${moduleId}\" is enabled, but generated artifacts are stale because generation failed. Rerun \"yarn mercato generate\" after fixing the underlying error. ${message}`,\n )\n }\n}\n\nfunction assertPackageName(packageName: string | null): asserts packageName is string {\n if (!packageName || !packageName.startsWith('@open-mercato/')) {\n throw new Error('Only @open-mercato/* package specs are supported by \"mercato module add\".')\n }\n}\n\nfunction assertSupportedPackageSpec(packageSpec: string): string {\n const trimmed = packageSpec.trim()\n\n if (!SAFE_PACKAGE_SPEC_PATTERN.test(trimmed)) {\n throw new Error('Unsupported package spec. Only direct @open-mercato/* package specs are allowed.')\n }\n\n const packageName = parsePackageNameFromSpec(trimmed)\n assertPackageName(packageName)\n\n if (trimmed === packageName) {\n return trimmed\n }\n\n const suffix = trimmed.slice(packageName.length + 1)\n if (SAFE_PACKAGE_TAG_PATTERN.test(suffix) || SAFE_PACKAGE_FILE_LOCATOR_PATTERN.test(suffix)) {\n return trimmed\n }\n\n throw new Error('Unsupported package spec suffix. Use a tag/version token or a file: locator.')\n}\n\nfunction validateBeforeRegistration(\n modulePackage: ValidatedOfficialModulePackage,\n resolver: PackageResolver,\n eject: boolean,\n): string {\n const appModuleDir = path.join(resolver.getAppDir(), 'src', 'modules', modulePackage.metadata.moduleId)\n\n if (eject && fs.existsSync(appModuleDir)) {\n throw new Error(`Destination directory already exists: ${appModuleDir}. Remove it first or rerun without --eject.`)\n }\n\n return appModuleDir\n}\n\nfunction prepareRegistrationSource(\n modulePackage: ValidatedOfficialModulePackage,\n resolver: PackageResolver,\n packageName: string,\n eject: boolean,\n): string {\n const appModuleDir = validateBeforeRegistration(modulePackage, resolver, eject)\n\n if (!eject) {\n return packageName\n }\n\n if (!modulePackage.metadata.ejectable) {\n throw new Error(`Package \"${packageName}\" is not ejectable. --eject requires open-mercato.ejectable === true.`)\n }\n\n validateEjectBoundaries(modulePackage)\n copyDirRecursive(modulePackage.sourceModuleDir, appModuleDir)\n rewriteCrossModuleImports(\n modulePackage.sourceModuleDir,\n appModuleDir,\n modulePackage.metadata.moduleId,\n packageName,\n )\n\n return '@app'\n}\n\nasync function registerResolvedOfficialModule(\n resolver: PackageResolver,\n modulePackage: ValidatedOfficialModulePackage,\n packageName: string,\n eject: boolean,\n): Promise<ModuleCommandResult> {\n const from = prepareRegistrationSource(modulePackage, resolver, packageName, eject)\n\n const registration = ensureModuleRegistration(\n resolver.getModulesConfigPath(),\n {\n id: modulePackage.metadata.moduleId,\n from,\n },\n )\n\n if (!registration.changed) {\n throw new Error(\n `Module \"${modulePackage.metadata.moduleId}\" from \"${from}\" is already enabled in modules.ts.`,\n )\n }\n\n await runGeneratorsWithRegistrationNotice(resolver, modulePackage.metadata.moduleId)\n\n return {\n moduleId: modulePackage.metadata.moduleId,\n packageName,\n from,\n registrationChanged: registration.changed,\n }\n}\n\nexport async function addOfficialModule(\n resolver: PackageResolver,\n packageSpec: string,\n eject: boolean,\n moduleId?: string,\n): Promise<ModuleCommandResult> {\n const safePackageSpec = assertSupportedPackageSpec(packageSpec)\n const packageName = parsePackageNameFromSpec(safePackageSpec)\n assertPackageName(packageName)\n\n await installPackageSpec(resolver, safePackageSpec)\n\n const modulePackage = resolveInstalledOfficialModulePackage(resolver, packageName, moduleId)\n return registerResolvedOfficialModule(resolver, modulePackage, packageName, eject)\n}\n\nexport async function enableOfficialModule(\n resolver: PackageResolver,\n packageName: string,\n moduleId?: string,\n eject = false,\n): Promise<ModuleCommandResult> {\n if (!packageName.startsWith('@open-mercato/')) {\n throw new Error('Only @open-mercato/* packages can be enabled with \"mercato module enable\".')\n }\n\n const modulePackage = resolveInstalledOfficialModulePackage(resolver, packageName, moduleId)\n return registerResolvedOfficialModule(resolver, modulePackage, packageName, eject)\n}\n"],
4
+ "sourcesContent": ["import fs from 'node:fs'\nimport path from 'node:path'\nimport spawn from 'cross-spawn'\nimport { copyDirRecursive, rewriteCrossModuleImports } from './eject'\nimport {\n parsePackageNameFromSpec,\n resolveInstalledOfficialModulePackage,\n validateEjectBoundaries,\n type ValidatedOfficialModulePackage,\n} from './module-package'\nimport { ensureModuleRegistration } from './modules-config'\nimport type { PackageResolver } from './resolver'\nimport { resolveSpawnCommand } from './spawn'\n\ntype ModuleCommandResult = {\n moduleId: string\n packageName: string\n from: string\n registrationChanged: boolean\n}\n\ntype InstallTarget = {\n cwd: string\n args: string[]\n}\n\nconst SAFE_PACKAGE_SPEC_PATTERN = /^@open-mercato\\/[a-z0-9][a-z0-9-]*(?:@.+)?$/i\nconst SAFE_PACKAGE_TAG_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/\nconst SAFE_PACKAGE_FILE_LOCATOR_PATTERN = /^file:[A-Za-z0-9_./: \\\\-]+$/\n\nfunction resolveYarnBinary(): string {\n return process.platform === 'win32' ? 'yarn.cmd' : 'yarn'\n}\n\nfunction readAppPackageName(appDir: string): string {\n const packageJsonPath = path.join(appDir, 'package.json')\n if (!fs.existsSync(packageJsonPath)) {\n throw new Error(`App package.json not found at ${packageJsonPath}.`)\n }\n\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) as { name?: string }\n if (!packageJson.name) {\n throw new Error(`App package.json at ${packageJsonPath} is missing the \"name\" field.`)\n }\n\n return packageJson.name\n}\n\nfunction resolveInstallTarget(resolver: PackageResolver): InstallTarget {\n if (!resolver.isMonorepo()) {\n return {\n cwd: resolver.getAppDir(),\n args: ['add'],\n }\n }\n\n return {\n cwd: resolver.getRootDir(),\n args: ['workspace', readAppPackageName(resolver.getAppDir()), 'add'],\n }\n}\n\nfunction runCommand(\n command: string,\n args: string[],\n cwd: string,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const resolvedSpawn = resolveSpawnCommand(command, args)\n const child = spawn(resolvedSpawn.command, resolvedSpawn.args, {\n cwd,\n env: process.env,\n stdio: 'inherit',\n ...resolvedSpawn.spawnOptions,\n })\n\n child.on('error', reject)\n child.on('exit', (code) => {\n if (code === 0) {\n resolve()\n return\n }\n\n reject(new Error(`Command failed: ${command} ${args.join(' ')} (exit ${code ?? 'unknown'}).`))\n })\n })\n}\n\nasync function installPackageSpec(\n resolver: PackageResolver,\n packageSpec: string,\n): Promise<void> {\n const target = resolveInstallTarget(resolver)\n await runCommand(resolveYarnBinary(), [...target.args, packageSpec], target.cwd)\n}\n\nexport async function runModuleGenerators(\n resolver: PackageResolver,\n quiet = true,\n): Promise<void> {\n const {\n generateEntityIds,\n generateModuleDi,\n generateModuleEntities,\n generateModulePackageSources,\n generateModuleRegistry,\n generateModuleRegistryApp,\n generateModuleRegistryCli,\n generateOpenApi,\n } = await import('./generators')\n\n await generateEntityIds({ resolver, quiet })\n await generateModuleRegistry({ resolver, quiet })\n await generateModuleRegistryApp({ resolver, quiet })\n await generateModuleRegistryCli({ resolver, quiet })\n await generateModuleEntities({ resolver, quiet })\n await generateModuleDi({ resolver, quiet })\n await generateModulePackageSources({ resolver, quiet })\n await generateOpenApi({ resolver, quiet })\n}\n\nasync function runGeneratorsWithRegistrationNotice(\n resolver: PackageResolver,\n moduleId: string,\n): Promise<void> {\n try {\n await runModuleGenerators(resolver)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new Error(\n `Module \"${moduleId}\" is enabled, but generated artifacts are stale because generation failed. Rerun \"yarn mercato generate\" after fixing the underlying error. ${message}`,\n )\n }\n}\n\nfunction assertPackageName(packageName: string | null): asserts packageName is string {\n if (!packageName || !packageName.startsWith('@open-mercato/')) {\n throw new Error('Only @open-mercato/* package specs are supported by \"mercato module add\".')\n }\n}\n\nfunction assertSupportedPackageSpec(packageSpec: string): string {\n const trimmed = packageSpec.trim()\n\n if (!SAFE_PACKAGE_SPEC_PATTERN.test(trimmed)) {\n throw new Error('Unsupported package spec. Only direct @open-mercato/* package specs are allowed.')\n }\n\n const packageName = parsePackageNameFromSpec(trimmed)\n assertPackageName(packageName)\n\n if (trimmed === packageName) {\n return trimmed\n }\n\n const suffix = trimmed.slice(packageName.length + 1)\n if (SAFE_PACKAGE_TAG_PATTERN.test(suffix) || SAFE_PACKAGE_FILE_LOCATOR_PATTERN.test(suffix)) {\n return trimmed\n }\n\n throw new Error('Unsupported package spec suffix. Use a tag/version token or a file: locator.')\n}\n\nfunction validateBeforeRegistration(\n modulePackage: ValidatedOfficialModulePackage,\n resolver: PackageResolver,\n eject: boolean,\n): string {\n const appModuleDir = path.join(resolver.getAppDir(), 'src', 'modules', modulePackage.metadata.moduleId)\n\n if (eject && fs.existsSync(appModuleDir)) {\n throw new Error(`Destination directory already exists: ${appModuleDir}. Remove it first or rerun without --eject.`)\n }\n\n return appModuleDir\n}\n\nfunction prepareRegistrationSource(\n modulePackage: ValidatedOfficialModulePackage,\n resolver: PackageResolver,\n packageName: string,\n eject: boolean,\n): string {\n const appModuleDir = validateBeforeRegistration(modulePackage, resolver, eject)\n\n if (!eject) {\n return packageName\n }\n\n if (!modulePackage.metadata.ejectable) {\n throw new Error(`Package \"${packageName}\" is not ejectable. --eject requires open-mercato.ejectable === true.`)\n }\n\n validateEjectBoundaries(modulePackage)\n copyDirRecursive(modulePackage.sourceModuleDir, appModuleDir)\n rewriteCrossModuleImports(\n modulePackage.sourceModuleDir,\n appModuleDir,\n modulePackage.metadata.moduleId,\n packageName,\n )\n\n return '@app'\n}\n\nasync function registerResolvedOfficialModule(\n resolver: PackageResolver,\n modulePackage: ValidatedOfficialModulePackage,\n packageName: string,\n eject: boolean,\n): Promise<ModuleCommandResult> {\n const from = prepareRegistrationSource(modulePackage, resolver, packageName, eject)\n\n const registration = ensureModuleRegistration(\n resolver.getModulesConfigPath(),\n {\n id: modulePackage.metadata.moduleId,\n from,\n },\n )\n\n if (!registration.changed) {\n throw new Error(\n `Module \"${modulePackage.metadata.moduleId}\" from \"${from}\" is already enabled in modules.ts.`,\n )\n }\n\n await runGeneratorsWithRegistrationNotice(resolver, modulePackage.metadata.moduleId)\n\n return {\n moduleId: modulePackage.metadata.moduleId,\n packageName,\n from,\n registrationChanged: registration.changed,\n }\n}\n\nexport async function addOfficialModule(\n resolver: PackageResolver,\n packageSpec: string,\n eject: boolean,\n moduleId?: string,\n): Promise<ModuleCommandResult> {\n const safePackageSpec = assertSupportedPackageSpec(packageSpec)\n const packageName = parsePackageNameFromSpec(safePackageSpec)\n assertPackageName(packageName)\n\n await installPackageSpec(resolver, safePackageSpec)\n\n const modulePackage = resolveInstalledOfficialModulePackage(resolver, packageName, moduleId)\n return registerResolvedOfficialModule(resolver, modulePackage, packageName, eject)\n}\n\nexport async function enableOfficialModule(\n resolver: PackageResolver,\n packageName: string,\n moduleId?: string,\n eject = false,\n): Promise<ModuleCommandResult> {\n if (!packageName.startsWith('@open-mercato/')) {\n throw new Error('Only @open-mercato/* packages can be enabled with \"mercato module enable\".')\n }\n\n const modulePackage = resolveInstalledOfficialModulePackage(resolver, packageName, moduleId)\n return registerResolvedOfficialModule(resolver, modulePackage, packageName, eject)\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/cli",
3
- "version": "0.6.1-develop.3276.1.1fcd145078",
3
+ "version": "0.6.1-develop.3287.1.450f4ffb56",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "exports": {
@@ -59,8 +59,8 @@
59
59
  "@mikro-orm/decorators": "^7.0.15",
60
60
  "@mikro-orm/migrations": "^7.0.15",
61
61
  "@mikro-orm/postgresql": "^7.0.15",
62
- "@open-mercato/queue": "0.6.1-develop.3276.1.1fcd145078",
63
- "@open-mercato/shared": "0.6.1-develop.3276.1.1fcd145078",
62
+ "@open-mercato/queue": "0.6.1-develop.3287.1.450f4ffb56",
63
+ "@open-mercato/shared": "0.6.1-develop.3287.1.450f4ffb56",
64
64
  "cross-spawn": "^7.0.6",
65
65
  "pg": "8.20.0",
66
66
  "semver": "^7.8.0",
@@ -70,10 +70,10 @@
70
70
  "typescript": "^5.9.3"
71
71
  },
72
72
  "peerDependencies": {
73
- "@open-mercato/shared": "0.6.1-develop.3276.1.1fcd145078"
73
+ "@open-mercato/shared": "0.6.1-develop.3287.1.450f4ffb56"
74
74
  },
75
75
  "devDependencies": {
76
- "@open-mercato/shared": "0.6.1-develop.3276.1.1fcd145078",
76
+ "@open-mercato/shared": "0.6.1-develop.3287.1.450f4ffb56",
77
77
  "@types/jest": "^30.0.0",
78
78
  "jest": "^30.4.2",
79
79
  "ts-jest": "^29.4.9"
@@ -26,7 +26,7 @@ type InstallTarget = {
26
26
 
27
27
  const SAFE_PACKAGE_SPEC_PATTERN = /^@open-mercato\/[a-z0-9][a-z0-9-]*(?:@.+)?$/i
28
28
  const SAFE_PACKAGE_TAG_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/
29
- const SAFE_PACKAGE_FILE_LOCATOR_PATTERN = /^file:[A-Za-z0-9_./:\\-]+$/
29
+ const SAFE_PACKAGE_FILE_LOCATOR_PATTERN = /^file:[A-Za-z0-9_./: \\-]+$/
30
30
 
31
31
  function resolveYarnBinary(): string {
32
32
  return process.platform === 'win32' ? 'yarn.cmd' : 'yarn'