mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-25 08:08:39 +00:00
800 lines
19 KiB
JavaScript
800 lines
19 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* @termix-ssh/plugin-sdk/ui is public API, implemented by
|
|
* src/ui/plugin-host/sdk-ui.ts. Adding to it is a contract change and
|
|
* removing from it is a breaking one, so neither should happen by accident.
|
|
*
|
|
* Resolves every name the module exports (through its `export *` lines too)
|
|
* and fails when that differs from ALLOWED. A new export goes on the list in
|
|
* the same change, which is what makes it a deliberate one. Only generic
|
|
* shell pieces belong here: anything one feature needs lives in its plugin.
|
|
*
|
|
* --list prints what the module exports now.
|
|
*/
|
|
|
|
const path = require("node:path");
|
|
|
|
const ROOT = path.resolve(__dirname, "..");
|
|
const SDK_UI = path.join(ROOT, "src", "ui", "plugin-host", "sdk-ui.ts");
|
|
const TSCONFIG = path.join(ROOT, "tsconfig.app.json");
|
|
|
|
const ALLOWED = [
|
|
"ACCENT_PRESET_COLORS",
|
|
"APP_VERSION",
|
|
"AccessRecord",
|
|
"ActionSlot",
|
|
"ActiveSessionInfo",
|
|
"AddButton",
|
|
"AdminSection",
|
|
"Alert",
|
|
"AlertDescription",
|
|
"AlertDialog",
|
|
"AlertDialogAction",
|
|
"AlertDialogCancel",
|
|
"AlertDialogContent",
|
|
"AlertDialogDescription",
|
|
"AlertDialogFooter",
|
|
"AlertDialogHeader",
|
|
"AlertDialogOverlay",
|
|
"AlertDialogPortal",
|
|
"AlertDialogTitle",
|
|
"AlertDialogTrigger",
|
|
"AlertTitle",
|
|
"ApiKey",
|
|
"AuditLog",
|
|
"AuditLogFilters",
|
|
"AuthEnrollmentSections",
|
|
"AuthOverrideProtocol",
|
|
"BackButton",
|
|
"Badge",
|
|
"BarSeries",
|
|
"BarSeriesItem",
|
|
"BarSeriesProps",
|
|
"BrandingSettings",
|
|
"BrowserSignInDialog",
|
|
"Button",
|
|
"ButtonProps",
|
|
"CORE_HOST_DEFAULTS",
|
|
"CORE_NAMESPACE",
|
|
"CREDENTIAL_ROW_FIELD_KEYS",
|
|
"Card",
|
|
"CardAction",
|
|
"CardContent",
|
|
"CardDescription",
|
|
"CardFooter",
|
|
"CardGridCanvas",
|
|
"CardHeader",
|
|
"CardMasonry",
|
|
"CardTitle",
|
|
"Checkbox",
|
|
"ColumnCountStepper",
|
|
"Command",
|
|
"CommandEmpty",
|
|
"CommandGroup",
|
|
"CommandItem",
|
|
"CommandList",
|
|
"CommandPrimitive",
|
|
"ComponentSlot",
|
|
"ConfirmOptions",
|
|
"ConnectionGate",
|
|
"ConnectionGateController",
|
|
"ConnectionGateProps",
|
|
"ConnectionLogPanel",
|
|
"ConnectionLogProvider",
|
|
"ConnectionOrigin",
|
|
"ConnectionScreen",
|
|
"ConnectionStage",
|
|
"ConnectionStatus",
|
|
"ConnectionUnavailable",
|
|
"CreatedApiKey",
|
|
"Credential",
|
|
"CredentialDensity",
|
|
"CredentialPermissionLevel",
|
|
"CredentialRowFields",
|
|
"CredentialSidebarFilterState",
|
|
"CredentialSidebarPreferences",
|
|
"CredentialSortKey",
|
|
"CredentialTrayTrigger",
|
|
"CustomKeybinding",
|
|
"DASHBOARD_CARDS",
|
|
"DEFAULT_FOLDER_COLOR",
|
|
"DEFAULT_FOLDER_ICON",
|
|
"DashboardCardId",
|
|
"DataColumn",
|
|
"DataView",
|
|
"DefaultOverrides",
|
|
"DefaultsOnly",
|
|
"DesktopUpdateMode",
|
|
"DesktopUpdateState",
|
|
"Dialog",
|
|
"DialogClose",
|
|
"DialogContent",
|
|
"DialogDescription",
|
|
"DialogFooter",
|
|
"DialogHeader",
|
|
"DialogOverlay",
|
|
"DialogPortal",
|
|
"DialogTitle",
|
|
"DialogTrigger",
|
|
"DocsLink",
|
|
"DocsLinkProps",
|
|
"DocsPage",
|
|
"DropdownMenu",
|
|
"DropdownMenuCheckboxItem",
|
|
"DropdownMenuContent",
|
|
"DropdownMenuGroup",
|
|
"DropdownMenuItem",
|
|
"DropdownMenuLabel",
|
|
"DropdownMenuPortal",
|
|
"DropdownMenuRadioGroup",
|
|
"DropdownMenuRadioItem",
|
|
"DropdownMenuSeparator",
|
|
"DropdownMenuShortcut",
|
|
"DropdownMenuSub",
|
|
"DropdownMenuSubContent",
|
|
"DropdownMenuSubTrigger",
|
|
"DropdownMenuTrigger",
|
|
"EditingWidth",
|
|
"EmptyState",
|
|
"FOLDER_COLORS",
|
|
"FONT_SIZES",
|
|
"Facts",
|
|
"FakeSwitch",
|
|
"Field",
|
|
"FieldPair",
|
|
"FolderAccessRule",
|
|
"FolderIconEl",
|
|
"FontSizeId",
|
|
"FormFooter",
|
|
"FullScreenAppPhase",
|
|
"FullScreenAppWrapper",
|
|
"GridCardCatalogEntry",
|
|
"GridColSpan",
|
|
"GridColumns",
|
|
"GridLayout",
|
|
"GridSlot",
|
|
"GroupHeading",
|
|
"HexColorPicker",
|
|
"Host",
|
|
"HostActionDef",
|
|
"HostClickBehavior",
|
|
"HostData",
|
|
"HostDefaultBadge",
|
|
"HostDefaultField",
|
|
"HostDefaultsChange",
|
|
"HostDefaultsContext",
|
|
"HostDefaultsContextValue",
|
|
"HostDefaultsLevel",
|
|
"HostDefaultsTarget",
|
|
"HostDensity",
|
|
"HostFeatureFields",
|
|
"HostFeatureFieldsProps",
|
|
"HostFolder",
|
|
"HostGroupKey",
|
|
"HostKeyVerificationDialog",
|
|
"HostOnly",
|
|
"HostProtocolAuthInput",
|
|
"HostProtocolDef",
|
|
"HostProtocols",
|
|
"HostRowFields",
|
|
"HostSidebarFilterState",
|
|
"HostSidebarPreferences",
|
|
"HostTrayTrigger",
|
|
"IconPicker",
|
|
"InlineView",
|
|
"Input",
|
|
"Kbd",
|
|
"KbdKey",
|
|
"KbdSeparator",
|
|
"KeyCombo",
|
|
"KeybindingAction",
|
|
"KeybindingActionDef",
|
|
"KeybindingActionType",
|
|
"LANGUAGES",
|
|
"Label",
|
|
"LineChart",
|
|
"LineChartSeries",
|
|
"LinkServerDialog",
|
|
"LinkedAccountInfo",
|
|
"ListBadge",
|
|
"ListRow",
|
|
"ListRowAction",
|
|
"ListRowFolder",
|
|
"ListRowTone",
|
|
"LogContext",
|
|
"LogEntry",
|
|
"LookSettings",
|
|
"MANAGE_REQUEST_EVENT",
|
|
"MAX_PANES",
|
|
"MFAPromptMode",
|
|
"ManageMode",
|
|
"ManageRequest",
|
|
"ManagerCardError",
|
|
"ManagerCardShell",
|
|
"ManagerSearch",
|
|
"Meter",
|
|
"MetricCard",
|
|
"MiniStat",
|
|
"NumberField",
|
|
"OPEN_PLUGINS_EVENT",
|
|
"OpenTabRecord",
|
|
"PANEL",
|
|
"PROMPT_BUTTON",
|
|
"PROMPT_DESTRUCTIVE_BUTTON",
|
|
"PROMPT_PRIMARY_BUTTON",
|
|
"PaletteItemDef",
|
|
"PanePrompt",
|
|
"PanelDensity",
|
|
"PanelList",
|
|
"PanelSearch",
|
|
"PanelShell",
|
|
"PanelViewMode",
|
|
"PassphraseDialog",
|
|
"PasswordInput",
|
|
"PermissionCatalogEntry",
|
|
"PluginComponent",
|
|
"PRESETS",
|
|
"PluginIcon",
|
|
"PluginSettingsErrors",
|
|
"PluginSettingsField",
|
|
"PluginSettingsValidationError",
|
|
"PluginSummary",
|
|
"PluginViewPlaceholder",
|
|
"Popover",
|
|
"PopoverAnchor",
|
|
"PopoverContent",
|
|
"PopoverTrigger",
|
|
"ProxyNode",
|
|
"ProxySettingsFields",
|
|
"RadialGauge",
|
|
"RadialGaugeProps",
|
|
"RailGroup",
|
|
"RailItemDef",
|
|
"RecentActivityItem",
|
|
"ReleaseInfo",
|
|
"Repeater",
|
|
"ResolvedHostDefault",
|
|
"RobustClipboardProvider",
|
|
"Role",
|
|
"SSHAuthDialog",
|
|
"SSHHost",
|
|
"SSHHostData",
|
|
"SSHHostWithStatus",
|
|
"SSH_AUTH_PROTOCOL",
|
|
"ScrollArea",
|
|
"ScrollBar",
|
|
"SecretField",
|
|
"SectionCard",
|
|
"Segmented",
|
|
"Select",
|
|
"Select2",
|
|
"SelectContent",
|
|
"SelectField",
|
|
"SelectGroup",
|
|
"SelectItem",
|
|
"SelectLabel",
|
|
"SelectScrollDownButton",
|
|
"SelectScrollUpButton",
|
|
"SelectSeparator",
|
|
"SelectTrigger",
|
|
"SelectValue",
|
|
"Separator",
|
|
"SettingRow",
|
|
"SettingsFieldRow",
|
|
"SharePermissionLevel",
|
|
"ShareTarget",
|
|
"Sheet",
|
|
"SheetClose",
|
|
"SheetContent",
|
|
"SheetDescription",
|
|
"SheetFooter",
|
|
"SheetHeader",
|
|
"SheetTitle",
|
|
"SheetTrigger",
|
|
"ShellConfirmCapture",
|
|
"Skeleton",
|
|
"Slider",
|
|
"SortKey",
|
|
"Sparkline",
|
|
"SparklineProps",
|
|
"SplitLayoutMenu",
|
|
"SplitOpenTarget",
|
|
"SplitSummary",
|
|
"StatRow",
|
|
"StatusValue",
|
|
"SurfaceKind",
|
|
"SurfaceScope",
|
|
"Switch",
|
|
"SwitchRow",
|
|
"SyncBasicAuth",
|
|
"SyncConflictItem",
|
|
"SyncEntityInfo",
|
|
"SyncErrorItem",
|
|
"SyncProxyHeader",
|
|
"SyncStatus",
|
|
"TOTPDialog",
|
|
"Tab",
|
|
"TabShellCallbacks",
|
|
"TabSplitAction",
|
|
"TabStage",
|
|
"TabStrip",
|
|
"TabStripItem",
|
|
"TabType",
|
|
"TagInput",
|
|
"TextAreaField",
|
|
"TextField",
|
|
"Textarea",
|
|
"TextareaProps",
|
|
"ThemeId",
|
|
"TlsStatus",
|
|
"ToolsTab",
|
|
"Tooltip",
|
|
"TooltipContent",
|
|
"TooltipProvider",
|
|
"TooltipTrigger",
|
|
"UI_AREA_KEYS",
|
|
"UI_FONTS",
|
|
"UiAreaKey",
|
|
"UiFontId",
|
|
"UiPreset",
|
|
"UpdateChannelState",
|
|
"UptimeInfo",
|
|
"UsagePair",
|
|
"UserPreferences",
|
|
"UserRole",
|
|
"UserSecondFactorSummary",
|
|
"VersionBadge",
|
|
"VersionInfo",
|
|
"ViewToggle",
|
|
"WebSocketConnectionTarget",
|
|
"WidgetTitle",
|
|
"actionOrder",
|
|
"activityTarget",
|
|
"adminCreateUser",
|
|
"adminCreateUserCredential",
|
|
"adminCreateUserHost",
|
|
"adminDeleteUserCredential",
|
|
"adminDeleteUserHost",
|
|
"adminExportUserData",
|
|
"adminGetHostPassword",
|
|
"adminGetUserCredentials",
|
|
"adminGetUserHosts",
|
|
"adminResetUserPassword",
|
|
"adminUpdateUserCredential",
|
|
"adminUpdateUserHost",
|
|
"applyAccentColor",
|
|
"applyFontSize",
|
|
"applyPresetSideEffects",
|
|
"applyUiFont",
|
|
"assignRoleToUser",
|
|
"beginSplitDrag",
|
|
"buildOriginWsUrl",
|
|
"bulkUpdateSSHHosts",
|
|
"canConfigureUpdates",
|
|
"canJoinSplit",
|
|
"changeAppLanguage",
|
|
"changePassword",
|
|
"clearLocalAdaptivePreferences",
|
|
"cn",
|
|
"copyToClipboard",
|
|
"createApiKey",
|
|
"createCredential",
|
|
"createFrontendLogger",
|
|
"createQuickConnectHost",
|
|
"createRole",
|
|
"createSSHHost",
|
|
"defaultConnectAction",
|
|
"defaultCredentialRowFields",
|
|
"defaultCredentialSidebarPreferences",
|
|
"defaultHostRowFields",
|
|
"defaultHostSidebarPreferences",
|
|
"defaultValuesEqual",
|
|
"deleteAccount",
|
|
"deleteAllHostsInFolder",
|
|
"deleteApiKey",
|
|
"deleteCredential",
|
|
"deleteOpenTab",
|
|
"deleteRole",
|
|
"deleteSSHHost",
|
|
"deleteUser",
|
|
"desktopUpdates",
|
|
"docsUrl",
|
|
"duplicateCredential",
|
|
"enabledHostProtocols",
|
|
"endSplitDrag",
|
|
"filterPaletteItems",
|
|
"findCoreHostDefault",
|
|
"findMatchingKeybinding",
|
|
"getActiveSessions",
|
|
"getAdaptiveResourceBudget",
|
|
"getApiKeys",
|
|
"getAuditLogActions",
|
|
"getAuditLogs",
|
|
"getBasePath",
|
|
"getBranding",
|
|
"getChannelReleases",
|
|
"getConnectedRemoteApi",
|
|
"getCredentialAccess",
|
|
"getCredentialDetails",
|
|
"getCredentialSidebarPreferences",
|
|
"getCredentials",
|
|
"getDatabaseHealth",
|
|
"getDatabaseTransferUrl",
|
|
"getDefaultConnectionTab",
|
|
"getDeveloperMode",
|
|
"getDeviceId",
|
|
"getErrorMessage",
|
|
"getExternalAutoProvision",
|
|
"getFolderAccess",
|
|
"getFolderDefaultsId",
|
|
"getHostAccess",
|
|
"getHostAuthOverride",
|
|
"getHostDefaultsLevel",
|
|
"getHostEditorSection",
|
|
"getHostPassword",
|
|
"getHostSidebarPreferences",
|
|
"getHostTags",
|
|
"getLiveHostStatus",
|
|
"getLogLevel",
|
|
"getNotificationPrivateEndpoints",
|
|
"getPanel",
|
|
"getPasswordLoginAllowed",
|
|
"getPasswordResetAllowed",
|
|
"getPermissionsCatalog",
|
|
"getPluginAdminSettings",
|
|
"getPluginHostSettings",
|
|
"getPluginUserSettings",
|
|
"getPlugins",
|
|
"getPollingEnvironmentMultiplier",
|
|
"getPreferredHostAction",
|
|
"getRecentActivity",
|
|
"getRegisteredDashboardCard",
|
|
"getRegistrationAllowed",
|
|
"getRoles",
|
|
"getSSHFolders",
|
|
"getSSHHosts",
|
|
"getSecondFactorAfterExternalLogin",
|
|
"getSessionTimeout",
|
|
"getSessionTimeoutMinutes",
|
|
"getSessions",
|
|
"getStatusCheckSettings",
|
|
"getStatusClasses",
|
|
"getSyncConflicts",
|
|
"getSyncErrors",
|
|
"getTabType",
|
|
"getTlsStatus",
|
|
"getUpdateChannel",
|
|
"getUptime",
|
|
"getUserInfo",
|
|
"getUserList",
|
|
"getUserPreferences",
|
|
"getUserRoles",
|
|
"getUserSecondFactors",
|
|
"getVersionInfo",
|
|
"globalShortcutHandler",
|
|
"groupRailItems",
|
|
"hasVisibleFields",
|
|
"hostActionsFor",
|
|
"hostBadgesFor",
|
|
"hostEditorToolbarItemsFor",
|
|
"hostMenuItemsFor",
|
|
"hostProtocolFlags",
|
|
"hostStatusIndicatorsFor",
|
|
"hydrateLocalSharedHostAuth",
|
|
"invalidateHostsAndStatusCaches",
|
|
"invalidateServerStatusCache",
|
|
"isCoreRailView",
|
|
"isElectron",
|
|
"isFieldShown",
|
|
"isMacPlatform",
|
|
"isPersistentTabType",
|
|
"isPrerelease",
|
|
"isSessionTabType",
|
|
"isSplitDragging",
|
|
"isSplitTab",
|
|
"isTabJumpHotkey",
|
|
"linkExternalToPasswordAccount",
|
|
"linkedServerUrl",
|
|
"listHostActions",
|
|
"listHostProtocols",
|
|
"loadPaletteGroup",
|
|
"logoutUser",
|
|
"makeHostSshSubTabs",
|
|
"makeHostTabs",
|
|
"makeUserAdmin",
|
|
"mapCredentials",
|
|
"markAdaptiveResourceUsed",
|
|
"markTabSurfaceUsed",
|
|
"moveRailItem",
|
|
"moveSplitDrag",
|
|
"normalizeLanguageCode",
|
|
"notifySyncChanged",
|
|
"openInSplit",
|
|
"paletteEntriesFor",
|
|
"parseCustomKeybindings",
|
|
"parseServerTime",
|
|
"pluginKey",
|
|
"pluginName",
|
|
"pluginWsUrl",
|
|
"preloadTabSurface",
|
|
"previewHostDefaultsLevel",
|
|
"promotableIds",
|
|
"protocolEnabled",
|
|
"protocolPort",
|
|
"quickConnectTargets",
|
|
"railItemLabel",
|
|
"readFromClipboard",
|
|
"recordHostActionPreference",
|
|
"refreshSyncStatus",
|
|
"registerLayout",
|
|
"registerTabCloseGuard",
|
|
"releaseUrlFrom",
|
|
"rem",
|
|
"removeAdminStatus",
|
|
"removeRoleFromUser",
|
|
"renameCredentialFolder",
|
|
"renameFolder",
|
|
"reorderCredentials",
|
|
"reorderFolders",
|
|
"reorderSSHHosts",
|
|
"reportBetaFeedbackUrl",
|
|
"reportCoreIssueUrl",
|
|
"requestFromLegacyEvent",
|
|
"requestManage",
|
|
"resetHostToDefaults",
|
|
"resetRecentActivity",
|
|
"resetUserSecondFactors",
|
|
"resolveConnectionOrigin",
|
|
"resolveHostDefaults",
|
|
"resolveHostTabType",
|
|
"resolveRemoteHostId",
|
|
"retrySyncErrors",
|
|
"revokeAllUserSessions",
|
|
"revokeCredentialAccess",
|
|
"revokeFolderAccess",
|
|
"revokeHostAccess",
|
|
"revokeSession",
|
|
"rightDockableIds",
|
|
"roleLabel",
|
|
"runAdaptiveBackgroundTask",
|
|
"runAdaptivePolling",
|
|
"runHostAction",
|
|
"runVisibleInterval",
|
|
"sanitizeCredentialSidebarPreferences",
|
|
"sanitizeHostSidebarPreferences",
|
|
"saveCredentialSidebarPreferences",
|
|
"saveHostDefaultsLevel",
|
|
"saveHostSidebarPreferences",
|
|
"saveHostTags",
|
|
"saveUserPreferences",
|
|
"setAllPluginChannels",
|
|
"setDeveloperMode",
|
|
"setHostAuthOverride",
|
|
"setNotificationPrivateEndpoints",
|
|
"setPluginOptions",
|
|
"setSyncStatus",
|
|
"setUpdateChannel",
|
|
"settleSyncConflict",
|
|
"shareCredential",
|
|
"shareFolder",
|
|
"shareHost",
|
|
"shell",
|
|
"splitDefaultKey",
|
|
"sshHostToHost",
|
|
"syncNow",
|
|
"tabIcon",
|
|
"tabJumpHotkeyKeys",
|
|
"takePendingManageRequest",
|
|
"unlinkExternalFromPasswordAccount",
|
|
"unlinkServer",
|
|
"updateCredential",
|
|
"updateExternalAutoProvision",
|
|
"updateFolderMetadata",
|
|
"updateHostAccess",
|
|
"updateLogLevel",
|
|
"updatePasswordLoginAllowed",
|
|
"updatePasswordResetAllowed",
|
|
"updatePluginAdminSettings",
|
|
"updatePluginHostSettings",
|
|
"updatePluginUserSettings",
|
|
"updateRegistrationAllowed",
|
|
"updateRole",
|
|
"updateSSHHost",
|
|
"updateSecondFactorAfterExternalLogin",
|
|
"updateSessionTimeout",
|
|
"updateStatusCheckSettings",
|
|
"updateSyncSettings",
|
|
"uploadTlsCertificate",
|
|
"usageBarColor",
|
|
"usageColor",
|
|
"useActionSlot",
|
|
"useAdaptivePolling",
|
|
"useAppTheme",
|
|
"useAreaPreferences",
|
|
"useBranding",
|
|
"useChooseTheme",
|
|
"useConfirm",
|
|
"useConnectionGate",
|
|
"useConnectionLog",
|
|
"useDesktopUpdate",
|
|
"useEditorDefaultKeys",
|
|
"useHostActions",
|
|
"useHostBadges",
|
|
"useHostContextMenuItems",
|
|
"useHostEditorToolbarItems",
|
|
"useHostStatusIndicators",
|
|
"useHostEditorSections",
|
|
"useHostProtocols",
|
|
"useHostStatus",
|
|
"useInstalledPlugins",
|
|
"useIsDefaultsEditor",
|
|
"useIsMobile",
|
|
"useKeybindingActions",
|
|
"useKeybindingDefaults",
|
|
"useOptionalConnectionLog",
|
|
"usePageVisibleInterval",
|
|
"usePaletteEntries",
|
|
"usePaletteGroups",
|
|
"usePanels",
|
|
"usePermissions",
|
|
"usePluginDocsUrl",
|
|
"usePluginHostSections",
|
|
"usePluginStore",
|
|
"useRailItems",
|
|
"useRegisteredDashboardCards",
|
|
"useServerStatus",
|
|
"useServerStatusMeta",
|
|
"useShellController",
|
|
"useSplitTargets",
|
|
"useSshAuthEditors",
|
|
"useSshAuthProviders",
|
|
"useStatusColorScheme",
|
|
"useSurfaceKind",
|
|
"useSyncStatus",
|
|
"useTabHandlesVersion",
|
|
"useTabs",
|
|
"useTabsSafe",
|
|
"useTheme",
|
|
"useThemeOptions",
|
|
"useUiPreference",
|
|
"useUiPreferencesContext",
|
|
"waitForDefaultsJob",
|
|
"withProtocolSettings",
|
|
];
|
|
|
|
/** Every name a module exports, resolved the way the compiler sees it. */
|
|
function exportedNames(file = SDK_UI, tsconfig = TSCONFIG) {
|
|
const ts = require("typescript");
|
|
const parsed = ts.getParsedCommandLineOfConfigFile(
|
|
tsconfig,
|
|
{},
|
|
{ ...ts.sys, onUnRecoverableConfigFileDiagnostic: () => {} },
|
|
);
|
|
const program = ts.createProgram([file], {
|
|
...(parsed?.options ?? {}),
|
|
noEmit: true,
|
|
});
|
|
const checker = program.getTypeChecker();
|
|
const source = program.getSourceFile(file);
|
|
const symbol = source && checker.getSymbolAtLocation(source);
|
|
if (!symbol) throw new Error(`Cannot read the exports of ${file}`);
|
|
return checker
|
|
.getExportsOfModule(symbol)
|
|
.map((entry) => entry.getName())
|
|
.sort();
|
|
}
|
|
|
|
const SNAPSHOT = path.join(ROOT, "packages", "plugin-sdk", "ui.api.txt");
|
|
|
|
/**
|
|
* One line per export with its type as the compiler prints it. Committed as
|
|
* packages/plugin-sdk/ui.api.txt, so a changed prop or signature shows up as
|
|
* a diff instead of reaching plugins unnoticed.
|
|
*/
|
|
function exportSignatures(file = SDK_UI, tsconfig = TSCONFIG) {
|
|
const ts = require("typescript");
|
|
const parsed = ts.getParsedCommandLineOfConfigFile(
|
|
tsconfig,
|
|
{},
|
|
{ ...ts.sys, onUnRecoverableConfigFileDiagnostic: () => {} },
|
|
);
|
|
const program = ts.createProgram([file], {
|
|
...(parsed?.options ?? {}),
|
|
noEmit: true,
|
|
});
|
|
const checker = program.getTypeChecker();
|
|
const source = program.getSourceFile(file);
|
|
const symbol = source && checker.getSymbolAtLocation(source);
|
|
const flags =
|
|
ts.TypeFormatFlags.NoTruncation |
|
|
ts.TypeFormatFlags.WriteArrowStyleSignature;
|
|
return checker
|
|
.getExportsOfModule(symbol)
|
|
.map((entry) => {
|
|
const target =
|
|
entry.flags & ts.SymbolFlags.Alias
|
|
? checker.getAliasedSymbol(entry)
|
|
: entry;
|
|
const isValue = !!(target.flags & ts.SymbolFlags.Value);
|
|
const declaration = target.declarations?.[0] ?? source;
|
|
const type = isValue
|
|
? checker.getTypeOfSymbolAtLocation(target, declaration)
|
|
: checker.getDeclaredTypeOfSymbol(target);
|
|
const text = checker
|
|
.typeToString(type, undefined, flags)
|
|
.replace(/import\("[^"]*"\)\./g, "")
|
|
.replace(/\s+/g, " ");
|
|
return `${entry.getName()} (${isValue ? "value" : "type"}): ${text}`;
|
|
})
|
|
.sort()
|
|
.join("\n")
|
|
.concat("\n");
|
|
}
|
|
|
|
/** What the module adds to, and drops from, the allowlist. */
|
|
function compare(names, allowed = ALLOWED) {
|
|
const allowedSet = new Set(allowed);
|
|
const nameSet = new Set(names);
|
|
return {
|
|
added: names.filter((name) => !allowedSet.has(name)),
|
|
removed: allowed.filter((name) => !nameSet.has(name)),
|
|
};
|
|
}
|
|
|
|
function main() {
|
|
const fs = require("node:fs");
|
|
if (/^export (type )?\*/m.test(fs.readFileSync(SDK_UI, "utf8"))) {
|
|
console.error(
|
|
"sdk-ui.ts uses export *; name each export so nothing becomes public API by accident.",
|
|
);
|
|
process.exit(1);
|
|
}
|
|
if (process.argv.includes("--update-snapshot")) {
|
|
fs.writeFileSync(SNAPSHOT, exportSignatures());
|
|
console.log(`Wrote ${path.relative(ROOT, SNAPSHOT)}`);
|
|
return;
|
|
}
|
|
const saved = fs.existsSync(SNAPSHOT)
|
|
? fs.readFileSync(SNAPSHOT, "utf8")
|
|
: "";
|
|
const current = exportSignatures();
|
|
if (current !== saved) {
|
|
const before = new Set(saved.split("\n"));
|
|
const after = new Set(current.split("\n"));
|
|
console.error(
|
|
"@termix-ssh/plugin-sdk/ui changed shape. If that is deliberate, run: node scripts/check-sdk-ui-exports.cjs --update-snapshot",
|
|
);
|
|
for (const line of saved.split("\n")) {
|
|
if (line && !after.has(line)) console.error(` - ${line.slice(0, 200)}`);
|
|
}
|
|
for (const line of current.split("\n")) {
|
|
if (line && !before.has(line)) console.error(` + ${line.slice(0, 200)}`);
|
|
}
|
|
process.exitCode = 1;
|
|
}
|
|
const names = exportedNames();
|
|
if (process.argv.includes("--list")) {
|
|
console.log(names.join("\n"));
|
|
return;
|
|
}
|
|
const { added, removed } = compare(names);
|
|
if (added.length === 0 && removed.length === 0) return;
|
|
if (added.length > 0) {
|
|
console.error(
|
|
"@termix-ssh/plugin-sdk/ui exports names that are not on the allowlist in scripts/check-sdk-ui-exports.cjs:",
|
|
);
|
|
for (const name of added) console.error(` + ${name}`);
|
|
}
|
|
if (removed.length > 0) {
|
|
console.error(
|
|
"@termix-ssh/plugin-sdk/ui no longer exports these allowlisted names (a breaking change for plugins):",
|
|
);
|
|
for (const name of removed) console.error(` - ${name}`);
|
|
}
|
|
process.exit(1);
|
|
}
|
|
|
|
if (require.main === module) main();
|
|
|
|
module.exports = { ALLOWED, compare, exportedNames, exportSignatures };
|