@aalis/plugin-webui-server 0.14.1 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/README.md +5 -1
  2. package/dist/admin-channel.d.ts +10 -0
  3. package/dist/admin-channel.d.ts.map +1 -0
  4. package/dist/admin-channel.js +57 -0
  5. package/dist/admin-channel.js.map +1 -0
  6. package/dist/attention.d.ts +36 -0
  7. package/dist/attention.d.ts.map +1 -0
  8. package/dist/attention.js +74 -0
  9. package/dist/attention.js.map +1 -0
  10. package/dist/auth.d.ts +32 -4
  11. package/dist/auth.d.ts.map +1 -1
  12. package/dist/auth.js +253 -79
  13. package/dist/auth.js.map +1 -1
  14. package/dist/client-discovery.d.ts +7 -3
  15. package/dist/client-discovery.d.ts.map +1 -1
  16. package/dist/client-discovery.js +9 -3
  17. package/dist/client-discovery.js.map +1 -1
  18. package/dist/client-switch-page.d.ts +26 -2
  19. package/dist/client-switch-page.d.ts.map +1 -1
  20. package/dist/client-switch-page.js +76 -45
  21. package/dist/client-switch-page.js.map +1 -1
  22. package/dist/gate.d.ts +3 -3
  23. package/dist/gate.d.ts.map +1 -1
  24. package/dist/gate.js +5 -4
  25. package/dist/gate.js.map +1 -1
  26. package/dist/html.d.ts +15 -0
  27. package/dist/html.d.ts.map +1 -0
  28. package/dist/html.js +38 -0
  29. package/dist/html.js.map +1 -0
  30. package/dist/index.d.ts +24 -26
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +627 -1102
  33. package/dist/index.js.map +1 -1
  34. package/dist/layout.d.ts +19 -0
  35. package/dist/layout.d.ts.map +1 -0
  36. package/dist/layout.js +200 -0
  37. package/dist/layout.js.map +1 -0
  38. package/dist/locales/en.d.ts +191 -0
  39. package/dist/locales/en.d.ts.map +1 -0
  40. package/dist/locales/en.js +191 -0
  41. package/dist/locales/en.js.map +1 -0
  42. package/dist/localize.d.ts +24 -0
  43. package/dist/localize.d.ts.map +1 -0
  44. package/dist/localize.js +68 -0
  45. package/dist/localize.js.map +1 -0
  46. package/dist/logs.d.ts +10 -0
  47. package/dist/logs.d.ts.map +1 -0
  48. package/dist/logs.js +50 -0
  49. package/dist/logs.js.map +1 -0
  50. package/dist/page-check.d.ts +56 -0
  51. package/dist/page-check.d.ts.map +1 -0
  52. package/dist/page-check.js +376 -0
  53. package/dist/page-check.js.map +1 -0
  54. package/dist/page-files.d.ts +13 -0
  55. package/dist/page-files.d.ts.map +1 -0
  56. package/dist/page-files.js +39 -0
  57. package/dist/page-files.js.map +1 -0
  58. package/dist/pages.d.ts +62 -0
  59. package/dist/pages.d.ts.map +1 -0
  60. package/dist/pages.js +486 -0
  61. package/dist/pages.js.map +1 -0
  62. package/dist/route.d.ts +14 -0
  63. package/dist/route.d.ts.map +1 -0
  64. package/dist/route.js +16 -0
  65. package/dist/route.js.map +1 -0
  66. package/dist/routes/files.d.ts +8 -9
  67. package/dist/routes/files.d.ts.map +1 -1
  68. package/dist/routes/files.js +33 -119
  69. package/dist/routes/files.js.map +1 -1
  70. package/dist/routes/frames.d.ts +4 -0
  71. package/dist/routes/frames.d.ts.map +1 -0
  72. package/dist/routes/frames.js +103 -0
  73. package/dist/routes/frames.js.map +1 -0
  74. package/dist/routes/i18n.d.ts +20 -0
  75. package/dist/routes/i18n.d.ts.map +1 -0
  76. package/dist/routes/i18n.js +78 -0
  77. package/dist/routes/i18n.js.map +1 -0
  78. package/dist/routes/marketplace.d.ts +46 -129
  79. package/dist/routes/marketplace.d.ts.map +1 -1
  80. package/dist/routes/marketplace.js +156 -106
  81. package/dist/routes/marketplace.js.map +1 -1
  82. package/dist/routes/media.d.ts +10 -0
  83. package/dist/routes/media.d.ts.map +1 -0
  84. package/dist/routes/media.js +66 -0
  85. package/dist/routes/media.js.map +1 -0
  86. package/dist/routes/pages.d.ts +22 -0
  87. package/dist/routes/pages.d.ts.map +1 -0
  88. package/dist/routes/pages.js +104 -0
  89. package/dist/routes/pages.js.map +1 -0
  90. package/dist/routes/pipe-to-response.d.ts +9 -0
  91. package/dist/routes/pipe-to-response.d.ts.map +1 -0
  92. package/dist/routes/pipe-to-response.js +16 -0
  93. package/dist/routes/pipe-to-response.js.map +1 -0
  94. package/dist/routes/plugins.d.ts +22 -28
  95. package/dist/routes/plugins.d.ts.map +1 -1
  96. package/dist/routes/plugins.js +339 -344
  97. package/dist/routes/plugins.js.map +1 -1
  98. package/dist/routes/proxy.d.ts +3 -2
  99. package/dist/routes/proxy.d.ts.map +1 -1
  100. package/dist/routes/proxy.js +64 -42
  101. package/dist/routes/proxy.js.map +1 -1
  102. package/dist/session-transport.d.ts +6 -0
  103. package/dist/session-transport.d.ts.map +1 -0
  104. package/dist/session-transport.js +32 -0
  105. package/dist/session-transport.js.map +1 -0
  106. package/dist/texts.d.ts +381 -0
  107. package/dist/texts.d.ts.map +1 -0
  108. package/dist/texts.js +194 -0
  109. package/dist/texts.js.map +1 -0
  110. package/package.json +38 -32
  111. package/dist/protocol.d.ts +0 -113
  112. package/dist/protocol.d.ts.map +0 -1
  113. package/dist/protocol.js +0 -59
  114. package/dist/protocol.js.map +0 -1
  115. package/dist/routes/uploaded-files.d.ts +0 -20
  116. package/dist/routes/uploaded-files.d.ts.map +0 -1
  117. package/dist/routes/uploaded-files.js +0 -161
  118. package/dist/routes/uploaded-files.js.map +0 -1
@@ -0,0 +1,191 @@
1
+ declare const _default: {
2
+ readonly displayName: "WebUI server";
3
+ readonly portLabel: "Port";
4
+ readonly portDescription: "HTTP port of the web admin interface";
5
+ readonly hostLabel: "Listen address";
6
+ readonly hostDescription: "IP address to bind; 0.0.0.0 makes it reachable from other machines";
7
+ readonly allowedHostsLabel: "Host allowlist";
8
+ readonly allowedHostsDescription: "Host names in the browser address bar when the WebUI is reached through a reverse proxy or a domain name, without scheme or port. IP addresses, localhost and the listen address are always accepted; requests for any other host name get 421, which keeps out DNS rebinding pages";
9
+ readonly badAllowedHost: "{entry} is not a host name: write only the host name, without a scheme, user name or path";
10
+ readonly autoOpenLabel: "Open the browser on startup";
11
+ readonly autoOpenDescription: "Opens the default browser the first time the app starts listening; reloading the plugin with the same token does not open it again, while a newly generated token opens it again so you can sign in. Turn this off over SSH or in headless environments";
12
+ readonly tokenModeLabel: "Token policy";
13
+ readonly tokenEphemeral: "Generate a random token at each start (rotates on restart)";
14
+ readonly tokenPersist: "Persist after the first generation (stays signed in across restarts)";
15
+ readonly tokenFixed: "Use the fixed token below";
16
+ readonly tokenModeDescription: "ephemeral = random at each start; persist = token written to data:/webui/token and reused; fixed = use the fixedToken field. Every mode writes the convenience file data:/webui/access.txt with the access URL.";
17
+ readonly fixedTokenLabel: "Fixed token (only with tokenMode=fixed)";
18
+ readonly fixedTokenDescription: "A random string of at least {min} characters (after trimming whitespace); a shorter one keeps the plugin from starting; empty means persist. Stored in secrets.yaml and never shown in the WebUI.";
19
+ readonly registryLabel: "Plugin market npm registry";
20
+ readonly registryDescription: "Base URL of the npm registry the plugin market searches. Not every mirror supports the npm search API (Taobao and other mainland mirrors do not), so the official registry is the default; in mainland China use a mirror or proxy that supports search. Installation goes through package-manager (following the local npm config), and the latest versions and updates on the cards are checked against the registry used for installing.";
21
+ readonly registryInvalid: "marketplaceRegistry is not a valid URL";
22
+ readonly tokenTooShort: "fixedToken needs at least {min} characters (currently {length})";
23
+ readonly accessTitle: "# Aalis WebUI access credentials (generated)";
24
+ readonly accessGenerated: "# Generated at: {time}";
25
+ readonly accessMode: "# Token mode: {mode}";
26
+ readonly accessLogin: "One-click sign-in: {url}";
27
+ readonly accessHint: "# Tip: paste the one-click sign-in link into a browser and the cookie is set for you";
28
+ readonly pageLanguage: "en";
29
+ readonly loginTitle: "Aalis WebUI sign-in";
30
+ readonly loginHint: "The access token is in state/webui/access.txt under the home directory; the startup log line “Access credentials written” gives its full path. With tokenMode set to fixed it is the config item fixedToken, whose value is stored in secrets.yaml under the home directory after startup (the config file holds a reference).";
31
+ readonly tokenPlaceholder: "Access token";
32
+ readonly loginButton: "Sign in";
33
+ readonly tokenWrong: "Incorrect token";
34
+ readonly networkError: "Network error";
35
+ readonly urlTokenWrong: "The token in the URL is incorrect; please enter it by hand.";
36
+ readonly tooManyFailures: "Too many failed sign-ins; try again in {minutes, plural, one {# minute} other {# minutes}}.";
37
+ readonly crossOrigin: "The request comes from a different origin than this service (behind a reverse proxy, the proxy must forward the original Host)";
38
+ readonly hostNotAllowed: "The host name of the request is not one this service accepts (when accessing through a reverse proxy or a domain name, add it to the Host allowlist in the WebUI server settings)";
39
+ readonly ownerRequired: "Owner permission required";
40
+ readonly unauthenticated: "Not signed in";
41
+ readonly switchTitle: "Switch frontend · Aalis";
42
+ readonly switchHeading: "Switch frontend";
43
+ readonly switchIntro: "This is the frontend recovery page of Aalis, served directly by webui-server and independent of the current frontend, so you can switch back here even when the current frontend has no switcher.";
44
+ readonly switchLabel: "Available frontends (webui-client)";
45
+ readonly switchLoading: "Loading…";
46
+ readonly switchButton: "Switch and reload";
47
+ readonly switchBack: "To switch back to the previous frontend, select it above and click “Switch and reload”.";
48
+ readonly switchListFailed: "Failed to read the service list (HTTP {status})";
49
+ readonly switchNoClients: "No frontend found (webui-client provider). Install an aalis.client package first.";
50
+ readonly switchCurrent: "{name} (current)";
51
+ readonly switching: "Switching…";
52
+ readonly switched: "Switched; redirecting…";
53
+ readonly switchOwnerHint: " (owner permission required: open the WebUI with the one-click sign-in link and try again)";
54
+ readonly switchFailed: "Switch failed: {detail}{hint}";
55
+ readonly switchError: "Switch request failed: {error}";
56
+ readonly unknownApi: "Unknown API: {method} {path}";
57
+ readonly noClient: "The frontend is not ready: install a frontend package marked aalis.client";
58
+ readonly serverError: "Something went wrong handling this request; see the logs for the reason";
59
+ readonly badRequest: "The request is malformed";
60
+ readonly bodyTooLarge: "The request body is too large";
61
+ readonly bodyNotJson: "The request body must be a valid JSON object or array";
62
+ readonly bodyEncoding: "The charset or content encoding of the request body is not supported";
63
+ readonly logFilterInvalid: "Invalid log filter: level accepts only debug, info, warn and error, and each parameter may be given at most once";
64
+ readonly noHostLogs: "The host provides no log service (host-logs), so the logs cannot be read";
65
+ readonly logBeforeRequired: "Paging back through the logs needs the numeric parameter before (entries with a smaller seq)";
66
+ readonly host: "Host";
67
+ readonly noProvider: "Service {service} has no provider with id {id}";
68
+ readonly noHostConfigPreference: "The host provides no config document (host-config), so the preference cannot be saved";
69
+ readonly contextIdRequired: "The request body needs contextId: the id of the preferred provider";
70
+ readonly refreshUnsupported: "Provider {provider} does not support refreshing its model list at runtime (for example, model discovery is off)";
71
+ readonly refreshNoModels: "Provider {provider} has no registered models right now and cannot be refreshed";
72
+ readonly dependencyInvalid: "dependency must be an entry id <provider instance id>/<model id>";
73
+ readonly allGroups: "* (all groups)";
74
+ readonly ungroupedTools: "Tools outside any group";
75
+ readonly pluginMissing: "Plugin {instance} does not exist";
76
+ readonly refused: "Plugin {instance} {action, select, config {can’t take config updates} enable {can’t be enabled} disable {can’t be disabled} other {can’t be reloaded}} right now (shutting down or being unloaded); the config was not changed";
77
+ readonly noHostConfig: "The host provides no config document (host-config), so the config cannot be read or written";
78
+ readonly selfDisable: "Plugin {name} provides this interface and cannot be disabled from it";
79
+ readonly bodyNotObject: "The request body must be an object";
80
+ readonly foreignKeys: "Only the core keys ({allowed, list}) can be changed; not accepted: {foreign, list}";
81
+ readonly configNotSaved: "Not written to the config file ({error}); this change was rolled back";
82
+ readonly savedRestart: "Global config saved; it takes effect after a restart";
83
+ readonly saved: "Global config updated and saved";
84
+ readonly noApp: "The app is unavailable";
85
+ readonly restartFailed: "Restart failed ({error}); the changes take effect at the next start";
86
+ readonly restarting: "Restarting the app";
87
+ readonly configNotObject: "The config field must be an object";
88
+ readonly noPluginManager: "The plugin manager service is unavailable";
89
+ readonly configInvalid: "Config validation failed: {issues}";
90
+ readonly issue: "{path}: {reason}";
91
+ readonly inputInvalid: "Input failed validation: {issues}";
92
+ readonly inputIssue: "{path}: {reason}";
93
+ readonly stillActivating: "still activating (past the slow-activation threshold, moved to the background); see the plugin list for the result";
94
+ readonly waitingOld: "waiting for the old instance of {instance} to stop";
95
+ readonly notYetActive: "not yet active; see the plugin list for the result";
96
+ readonly notYetActiveBecause: "not yet active: {why}";
97
+ readonly seeLog: "see the logs for details";
98
+ readonly ignoredNote: " (ignored undeclared config fields: {fields})";
99
+ readonly removedNote: " (removed undeclared fields from the config file: {fields})";
100
+ readonly unchanged: "Plugin {name} config unchanged; written back to the config file{ignored}{removed}";
101
+ readonly reactivateFailed: "Plugin {name} failed to reactivate with the new config and is now in the error state ({reason})";
102
+ readonly disabledNewConfig: "the plugin is disabled; it activates with the new config once enabled";
103
+ readonly configWritten: "the config was written to the config file{ignored}{removed}";
104
+ readonly configUpdated: "Plugin {name} config updated{ignored}{removed}";
105
+ readonly activateFailed: "Plugin {name} failed to activate and is now in the error state ({reason})";
106
+ readonly markedEnabled: "marked as enabled in the config file";
107
+ readonly enabled: "Plugin {name} enabled";
108
+ readonly disabledStuck: "Plugin {name} is disabled but has not stopped after the grace period; see the logs for details";
109
+ readonly markedDisabled: "marked as disabled in the config file";
110
+ readonly disabled: "Plugin {name} disabled";
111
+ readonly reloadDisabled: "Plugin {name} is disabled; enable it before reloading";
112
+ readonly reloadFailed: "Plugin {name} failed to reactivate and is now in the error state ({reason})";
113
+ readonly reloaded: "Plugin {name} reloaded";
114
+ readonly noPluginSource: "The host provides no plugin source, so plugins cannot be scanned";
115
+ readonly scanned: "{count, plural, =0 {No new plugins} one {Loaded # new plugin} other {Loaded # new plugins}}";
116
+ readonly suffixRequired: "suffix must be a non-empty string";
117
+ readonly suffixInvalid: "suffix may contain only letters, digits, underscores and hyphens";
118
+ readonly moduleMissing: "Cannot create the instance: module “{module}” not found";
119
+ readonly moduleNotReusable: "Cannot create the instance: module “{module}” does not declare reusable";
120
+ readonly instanceExists: "Cannot create the instance: “{instance}” already exists";
121
+ readonly instanceRefused: "Instance {instance} was not registered (shutting down or refused; see the logs); the config was not written";
122
+ readonly instanceFailed: "Created instance {instance}, but it failed to activate and is now in the error state ({reason})";
123
+ readonly instanceDisabled: "it is listed in disabledPlugins in the config file, so it was registered as disabled and activates once enabled";
124
+ readonly instanceCreated: "Created instance {instance}{ignored}";
125
+ readonly cannotDelete: "Cannot delete (the instance does not exist, or it is the main instance, which cannot be deleted)";
126
+ readonly deleteNotSaved: "Instance {instance} was not deleted: not written to the config file ({error})";
127
+ readonly unloadFailed: "Deleted instance {instance} from the config file, but unloading failed ({error}); it is no longer registered after a restart";
128
+ readonly deletedShuttingDown: "Deleted instance {instance} from the config file; shutting down, so the running instance was not unloaded";
129
+ readonly deleted: "Deleted instance {instance}";
130
+ readonly noAppDir: "The host provides no install directory (host-paths), so installed packages cannot be determined";
131
+ readonly noInstallSource: "Cannot determine the install registry ({error}); latest versions and updates are not shown for now";
132
+ readonly registryStatus: "npm registry returned {status}";
133
+ readonly searchOffline: "Cannot reach the npm registry ({error}); only locally installed plugins can be managed for now";
134
+ readonly packageNameInvalid: "name must be a valid npm package name";
135
+ readonly nameNotString: "The name field must be a string";
136
+ readonly removeConfigNotBoolean: "The removeConfig field must be a boolean";
137
+ readonly targetsRequired: "targets must be a non-empty array";
138
+ readonly noPackageManagerInstall: "No running plugin provides the package-manager service, so the market cannot install plugins: enable it in the plugin area, or run npm install <package> in the project directory and restart";
139
+ readonly noPackageManagerUninstall: "No running plugin provides the package-manager service, so the market cannot uninstall plugins: enable it in the plugin area, or run npm uninstall <package> in the project directory and restart";
140
+ readonly noPackageManagerUpdate: "No running plugin provides the package-manager service, so the market cannot update: enable it in the plugin area";
141
+ readonly urlRequired: "The url parameter is missing";
142
+ readonly upstreamStatus: "Upstream returned {status}";
143
+ readonly notImage: "Upstream did not return a displayable image";
144
+ readonly imageTooLarge: "Image too large ({size} > {max})";
145
+ readonly noUpstreamBody: "Upstream sent no response body";
146
+ readonly proxyFailed: "Proxy failed: {error}";
147
+ readonly invalidHandle: "Invalid file handle";
148
+ readonly fileGone: "The file is gone";
149
+ readonly readFailed: "Failed to read the file";
150
+ readonly notStorageUri: "Not a storage address";
151
+ readonly notMedia: "Only images, video and audio are served";
152
+ readonly fileMissing: "The file does not exist";
153
+ readonly noStorageLayout: "The storage service is absent, so layout records cannot be read or written";
154
+ readonly layoutReadFailed: "Failed to read the layout records";
155
+ readonly layoutOpInvalid: "The operation must be '{ op, page }' or '{ op, tab }': pin, unpin, move-up and move-down take page ('{ instance, pageKey }'); open-tab, close-tab, tab-up and tab-down take tab ('{ host }' or '{ instance, pageKey }'); remove-tab takes only a plugin tab ('{ instance, pageKey }'); host tabs can only be closed, not removed";
156
+ readonly pinPluginOnly: "Only pages placed in plugin details can be pinned";
157
+ readonly openSessionOnly: "Only session panel pages can be opened in the panel";
158
+ readonly layoutSaveFailed: "Failed to save the layout records; they are unchanged";
159
+ readonly pinnedFull: "At most {max} entries; unpin some first";
160
+ readonly tabsFull: "The session panel keeps at most {max} tabs";
161
+ readonly pageMissing: "Page {page} ({instance}) does not exist";
162
+ readonly extraParams: "Unexpected parameters: {keys, list}";
163
+ readonly nameRequired: "{name} must be a non-empty string";
164
+ readonly noSessionManager: "The session manager service is absent, so session panels are unavailable";
165
+ readonly archiveAbsent: "The message archive service is absent, so this message was not saved to the WebUI session history";
166
+ readonly sessionMissing: "Session {session} does not exist";
167
+ readonly inputNotObject: "input must be an object";
168
+ readonly inputExtraKeys: "Unexpected keys in input: {keys, list}";
169
+ readonly inputNotJsonString: "input must be a JSON string";
170
+ readonly inputBadJson: "input is not valid JSON";
171
+ readonly breach: "Data source {source} returned bad data: {problem}";
172
+ readonly notJson: "cannot be converted to JSON: {error}";
173
+ readonly notJsonValue: "cannot be converted to JSON";
174
+ readonly wantRows: "must return an array of rows";
175
+ readonly rowNotObject: "row {row} is not an object";
176
+ readonly rowKeyInvalid: "{key} in row {row} must be a unique non-empty string";
177
+ readonly rowFlagInvalid: "{key} in row {row} must be a boolean";
178
+ readonly rowUriInvalid: "{key} in row {row} must be a storage address";
179
+ readonly wantText: "must return a string or a text object";
180
+ readonly wantInfo: "must return an array of '{ label, value }'";
181
+ readonly wantGraph: "must return '{ nodes, edges }'";
182
+ readonly nodeInvalid: "nodes need a unique id and a label";
183
+ readonly edgeInvalid: "both ends of an edge must be node ids";
184
+ readonly noSource: "Page {page} has no data source {source}";
185
+ readonly noComponent: "Page {page} has no component {component}";
186
+ readonly noAction: "Page {page} has no action {action}";
187
+ readonly requestNotObject: "The request body must be an object";
188
+ readonly notASentence: "Action {action} did not return a sentence";
189
+ };
190
+ export default _default;
191
+ //# sourceMappingURL=en.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/locales/en.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,wBAiNG"}
@@ -0,0 +1,191 @@
1
+ import { defineLocale } from '@aalis/schema-i18n';
2
+ export default defineLocale()({
3
+ displayName: 'WebUI server',
4
+ portLabel: 'Port',
5
+ portDescription: 'HTTP port of the web admin interface',
6
+ hostLabel: 'Listen address',
7
+ hostDescription: 'IP address to bind; 0.0.0.0 makes it reachable from other machines',
8
+ allowedHostsLabel: 'Host allowlist',
9
+ allowedHostsDescription: 'Host names in the browser address bar when the WebUI is reached through a reverse proxy or a domain name, without scheme or port. IP addresses, localhost and the listen address are always accepted; requests for any other host name get 421, which keeps out DNS rebinding pages',
10
+ badAllowedHost: '{entry} is not a host name: write only the host name, without a scheme, user name or path',
11
+ autoOpenLabel: 'Open the browser on startup',
12
+ autoOpenDescription: 'Opens the default browser the first time the app starts listening; reloading the plugin with the same token does not open it again, while a newly generated token opens it again so you can sign in. Turn this off over SSH or in headless environments',
13
+ tokenModeLabel: 'Token policy',
14
+ tokenEphemeral: 'Generate a random token at each start (rotates on restart)',
15
+ tokenPersist: 'Persist after the first generation (stays signed in across restarts)',
16
+ tokenFixed: 'Use the fixed token below',
17
+ tokenModeDescription: 'ephemeral = random at each start; persist = token written to data:/webui/token and reused; fixed = use the fixedToken field. Every mode writes the convenience file data:/webui/access.txt with the access URL.',
18
+ fixedTokenLabel: 'Fixed token (only with tokenMode=fixed)',
19
+ fixedTokenDescription: 'A random string of at least {min} characters (after trimming whitespace); a shorter one keeps the plugin from starting; empty means persist. Stored in secrets.yaml and never shown in the WebUI.',
20
+ registryLabel: 'Plugin market npm registry',
21
+ registryDescription: 'Base URL of the npm registry the plugin market searches. Not every mirror supports the npm search API (Taobao and other mainland mirrors do not), so the official registry is the default; in mainland China use a mirror or proxy that supports search. Installation goes through package-manager (following the local npm config), and the latest versions and updates on the cards are checked against the registry used for installing.',
22
+ registryInvalid: 'marketplaceRegistry is not a valid URL',
23
+ tokenTooShort: 'fixedToken needs at least {min} characters (currently {length})',
24
+ accessTitle: '# Aalis WebUI access credentials (generated)',
25
+ accessGenerated: '# Generated at: {time}',
26
+ accessMode: '# Token mode: {mode}',
27
+ accessLogin: 'One-click sign-in: {url}',
28
+ accessHint: '# Tip: paste the one-click sign-in link into a browser and the cookie is set for you',
29
+ pageLanguage: 'en',
30
+ loginTitle: 'Aalis WebUI sign-in',
31
+ loginHint: 'The access token is in state/webui/access.txt under the home directory; the startup log line “Access credentials written” gives its full path. With tokenMode set to fixed it is the config item fixedToken, whose value is stored in secrets.yaml under the home directory after startup (the config file holds a reference).',
32
+ tokenPlaceholder: 'Access token',
33
+ loginButton: 'Sign in',
34
+ tokenWrong: 'Incorrect token',
35
+ networkError: 'Network error',
36
+ urlTokenWrong: 'The token in the URL is incorrect; please enter it by hand.',
37
+ tooManyFailures: 'Too many failed sign-ins; try again in {minutes, plural, one {# minute} other {# minutes}}.',
38
+ crossOrigin: 'The request comes from a different origin than this service (behind a reverse proxy, the proxy must forward the original Host)',
39
+ hostNotAllowed: 'The host name of the request is not one this service accepts (when accessing through a reverse proxy or a domain name, add it to the Host allowlist in the WebUI server settings)',
40
+ ownerRequired: 'Owner permission required',
41
+ unauthenticated: 'Not signed in',
42
+ switchTitle: 'Switch frontend · Aalis',
43
+ switchHeading: 'Switch frontend',
44
+ switchIntro: 'This is the frontend recovery page of Aalis, served directly by webui-server and independent of the current frontend, so you can switch back here even when the current frontend has no switcher.',
45
+ switchLabel: 'Available frontends (webui-client)',
46
+ switchLoading: 'Loading…',
47
+ switchButton: 'Switch and reload',
48
+ switchBack: 'To switch back to the previous frontend, select it above and click “Switch and reload”.',
49
+ switchListFailed: 'Failed to read the service list (HTTP {status})',
50
+ switchNoClients: 'No frontend found (webui-client provider). Install an aalis.client package first.',
51
+ switchCurrent: '{name} (current)',
52
+ switching: 'Switching…',
53
+ switched: 'Switched; redirecting…',
54
+ switchOwnerHint: ' (owner permission required: open the WebUI with the one-click sign-in link and try again)',
55
+ switchFailed: 'Switch failed: {detail}{hint}',
56
+ switchError: 'Switch request failed: {error}',
57
+ unknownApi: 'Unknown API: {method} {path}',
58
+ noClient: 'The frontend is not ready: install a frontend package marked aalis.client',
59
+ serverError: 'Something went wrong handling this request; see the logs for the reason',
60
+ badRequest: 'The request is malformed',
61
+ bodyTooLarge: 'The request body is too large',
62
+ bodyNotJson: 'The request body must be a valid JSON object or array',
63
+ bodyEncoding: 'The charset or content encoding of the request body is not supported',
64
+ logFilterInvalid: 'Invalid log filter: level accepts only debug, info, warn and error, and each parameter may be given at most once',
65
+ noHostLogs: 'The host provides no log service (host-logs), so the logs cannot be read',
66
+ logBeforeRequired: 'Paging back through the logs needs the numeric parameter before (entries with a smaller seq)',
67
+ host: 'Host',
68
+ noProvider: 'Service {service} has no provider with id {id}',
69
+ noHostConfigPreference: 'The host provides no config document (host-config), so the preference cannot be saved',
70
+ contextIdRequired: 'The request body needs contextId: the id of the preferred provider',
71
+ refreshUnsupported: 'Provider {provider} does not support refreshing its model list at runtime (for example, model discovery is off)',
72
+ refreshNoModels: 'Provider {provider} has no registered models right now and cannot be refreshed',
73
+ dependencyInvalid: 'dependency must be an entry id <provider instance id>/<model id>',
74
+ allGroups: '* (all groups)',
75
+ ungroupedTools: 'Tools outside any group',
76
+ pluginMissing: 'Plugin {instance} does not exist',
77
+ refused: 'Plugin {instance} {action, select, config {can’t take config updates} enable {can’t be enabled} disable {can’t be disabled} other {can’t be reloaded}} right now (shutting down or being unloaded); the config was not changed',
78
+ noHostConfig: 'The host provides no config document (host-config), so the config cannot be read or written',
79
+ selfDisable: 'Plugin {name} provides this interface and cannot be disabled from it',
80
+ bodyNotObject: 'The request body must be an object',
81
+ foreignKeys: 'Only the core keys ({allowed, list}) can be changed; not accepted: {foreign, list}',
82
+ configNotSaved: 'Not written to the config file ({error}); this change was rolled back',
83
+ savedRestart: 'Global config saved; it takes effect after a restart',
84
+ saved: 'Global config updated and saved',
85
+ noApp: 'The app is unavailable',
86
+ restartFailed: 'Restart failed ({error}); the changes take effect at the next start',
87
+ restarting: 'Restarting the app',
88
+ configNotObject: 'The config field must be an object',
89
+ noPluginManager: 'The plugin manager service is unavailable',
90
+ configInvalid: 'Config validation failed: {issues}',
91
+ issue: '{path}: {reason}',
92
+ inputInvalid: 'Input failed validation: {issues}',
93
+ inputIssue: '{path}: {reason}',
94
+ stillActivating: 'still activating (past the slow-activation threshold, moved to the background); see the plugin list for the result',
95
+ waitingOld: 'waiting for the old instance of {instance} to stop',
96
+ notYetActive: 'not yet active; see the plugin list for the result',
97
+ notYetActiveBecause: 'not yet active: {why}',
98
+ seeLog: 'see the logs for details',
99
+ ignoredNote: ' (ignored undeclared config fields: {fields})',
100
+ removedNote: ' (removed undeclared fields from the config file: {fields})',
101
+ unchanged: 'Plugin {name} config unchanged; written back to the config file{ignored}{removed}',
102
+ reactivateFailed: 'Plugin {name} failed to reactivate with the new config and is now in the error state ({reason})',
103
+ disabledNewConfig: 'the plugin is disabled; it activates with the new config once enabled',
104
+ configWritten: 'the config was written to the config file{ignored}{removed}',
105
+ configUpdated: 'Plugin {name} config updated{ignored}{removed}',
106
+ activateFailed: 'Plugin {name} failed to activate and is now in the error state ({reason})',
107
+ markedEnabled: 'marked as enabled in the config file',
108
+ enabled: 'Plugin {name} enabled',
109
+ disabledStuck: 'Plugin {name} is disabled but has not stopped after the grace period; see the logs for details',
110
+ markedDisabled: 'marked as disabled in the config file',
111
+ disabled: 'Plugin {name} disabled',
112
+ reloadDisabled: 'Plugin {name} is disabled; enable it before reloading',
113
+ reloadFailed: 'Plugin {name} failed to reactivate and is now in the error state ({reason})',
114
+ reloaded: 'Plugin {name} reloaded',
115
+ noPluginSource: 'The host provides no plugin source, so plugins cannot be scanned',
116
+ scanned: '{count, plural, =0 {No new plugins} one {Loaded # new plugin} other {Loaded # new plugins}}',
117
+ suffixRequired: 'suffix must be a non-empty string',
118
+ suffixInvalid: 'suffix may contain only letters, digits, underscores and hyphens',
119
+ moduleMissing: 'Cannot create the instance: module “{module}” not found',
120
+ moduleNotReusable: 'Cannot create the instance: module “{module}” does not declare reusable',
121
+ instanceExists: 'Cannot create the instance: “{instance}” already exists',
122
+ instanceRefused: 'Instance {instance} was not registered (shutting down or refused; see the logs); the config was not written',
123
+ instanceFailed: 'Created instance {instance}, but it failed to activate and is now in the error state ({reason})',
124
+ instanceDisabled: 'it is listed in disabledPlugins in the config file, so it was registered as disabled and activates once enabled',
125
+ instanceCreated: 'Created instance {instance}{ignored}',
126
+ cannotDelete: 'Cannot delete (the instance does not exist, or it is the main instance, which cannot be deleted)',
127
+ deleteNotSaved: 'Instance {instance} was not deleted: not written to the config file ({error})',
128
+ unloadFailed: 'Deleted instance {instance} from the config file, but unloading failed ({error}); it is no longer registered after a restart',
129
+ deletedShuttingDown: 'Deleted instance {instance} from the config file; shutting down, so the running instance was not unloaded',
130
+ deleted: 'Deleted instance {instance}',
131
+ noAppDir: 'The host provides no install directory (host-paths), so installed packages cannot be determined',
132
+ noInstallSource: 'Cannot determine the install registry ({error}); latest versions and updates are not shown for now',
133
+ registryStatus: 'npm registry returned {status}',
134
+ searchOffline: 'Cannot reach the npm registry ({error}); only locally installed plugins can be managed for now',
135
+ packageNameInvalid: 'name must be a valid npm package name',
136
+ nameNotString: 'The name field must be a string',
137
+ removeConfigNotBoolean: 'The removeConfig field must be a boolean',
138
+ targetsRequired: 'targets must be a non-empty array',
139
+ noPackageManagerInstall: 'No running plugin provides the package-manager service, so the market cannot install plugins: enable it in the plugin area, or run npm install <package> in the project directory and restart',
140
+ noPackageManagerUninstall: 'No running plugin provides the package-manager service, so the market cannot uninstall plugins: enable it in the plugin area, or run npm uninstall <package> in the project directory and restart',
141
+ noPackageManagerUpdate: 'No running plugin provides the package-manager service, so the market cannot update: enable it in the plugin area',
142
+ urlRequired: 'The url parameter is missing',
143
+ upstreamStatus: 'Upstream returned {status}',
144
+ notImage: 'Upstream did not return a displayable image',
145
+ imageTooLarge: 'Image too large ({size} > {max})',
146
+ noUpstreamBody: 'Upstream sent no response body',
147
+ proxyFailed: 'Proxy failed: {error}',
148
+ invalidHandle: 'Invalid file handle',
149
+ fileGone: 'The file is gone',
150
+ readFailed: 'Failed to read the file',
151
+ notStorageUri: 'Not a storage address',
152
+ notMedia: 'Only images, video and audio are served',
153
+ fileMissing: 'The file does not exist',
154
+ noStorageLayout: 'The storage service is absent, so layout records cannot be read or written',
155
+ layoutReadFailed: 'Failed to read the layout records',
156
+ layoutOpInvalid: "The operation must be '{ op, page }' or '{ op, tab }': pin, unpin, move-up and move-down take page ('{ instance, pageKey }'); open-tab, close-tab, tab-up and tab-down take tab ('{ host }' or '{ instance, pageKey }'); remove-tab takes only a plugin tab ('{ instance, pageKey }'); host tabs can only be closed, not removed",
157
+ pinPluginOnly: 'Only pages placed in plugin details can be pinned',
158
+ openSessionOnly: 'Only session panel pages can be opened in the panel',
159
+ layoutSaveFailed: 'Failed to save the layout records; they are unchanged',
160
+ pinnedFull: 'At most {max} entries; unpin some first',
161
+ tabsFull: 'The session panel keeps at most {max} tabs',
162
+ pageMissing: 'Page {page} ({instance}) does not exist',
163
+ extraParams: 'Unexpected parameters: {keys, list}',
164
+ nameRequired: '{name} must be a non-empty string',
165
+ noSessionManager: 'The session manager service is absent, so session panels are unavailable',
166
+ archiveAbsent: 'The message archive service is absent, so this message was not saved to the WebUI session history',
167
+ sessionMissing: 'Session {session} does not exist',
168
+ inputNotObject: 'input must be an object',
169
+ inputExtraKeys: 'Unexpected keys in input: {keys, list}',
170
+ inputNotJsonString: 'input must be a JSON string',
171
+ inputBadJson: 'input is not valid JSON',
172
+ breach: 'Data source {source} returned bad data: {problem}',
173
+ notJson: 'cannot be converted to JSON: {error}',
174
+ notJsonValue: 'cannot be converted to JSON',
175
+ wantRows: 'must return an array of rows',
176
+ rowNotObject: 'row {row} is not an object',
177
+ rowKeyInvalid: '{key} in row {row} must be a unique non-empty string',
178
+ rowFlagInvalid: '{key} in row {row} must be a boolean',
179
+ rowUriInvalid: '{key} in row {row} must be a storage address',
180
+ wantText: 'must return a string or a text object',
181
+ wantInfo: "must return an array of '{ label, value }'",
182
+ wantGraph: "must return '{ nodes, edges }'",
183
+ nodeInvalid: 'nodes need a unique id and a label',
184
+ edgeInvalid: 'both ends of an edge must be node ids',
185
+ noSource: 'Page {page} has no data source {source}',
186
+ noComponent: 'Page {page} has no component {component}',
187
+ noAction: 'Page {page} has no action {action}',
188
+ requestNotObject: 'The request body must be an object',
189
+ notASentence: 'Action {action} did not return a sentence',
190
+ });
191
+ //# sourceMappingURL=en.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en.js","sourceRoot":"","sources":["../../src/locales/en.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { type I18nService, type RenderOptions } from '@aalis/api-i18n';
2
+ import type { Logger, ServiceSelection } from '@aalis/core';
3
+ import type { Localized, LocalizeSkip } from '@aalis/schema-i18n';
4
+ import type express from 'express';
5
+ /** 交代这次回应的渲染选项:要跳过的原样数据、Markdown 正文的转义。在 res.json 之前调 */
6
+ export declare function renderWith(res: express.Response, options: RenderOptions): void;
7
+ /**
8
+ * schema(插件配置、核心配置、动作的输入字段)里的 default 是取值,不是文字:跳过它们,形如文字对象的默认值原样交出,表单读回
9
+ * 再保存时不被改写成字符串。字段、分组、数组与元素字段按对象身份认,不按键名(配置里可能有名叫 default 的字段)
10
+ */
11
+ export declare function skipSchemaDefaults(schemas: Iterable<unknown>): LocalizeSkip;
12
+ export interface Localizer {
13
+ /** 最早挂上:包住 res.json,渲染后再发 */
14
+ middleware: express.RequestHandler;
15
+ /** 把值里的文字对象按全局层的语言渲染 */
16
+ render<T>(value: T, options?: RenderOptions): Localized<T>;
17
+ /**
18
+ * 全局层的语言链(i18n 的 chainOf),/api/i18n/messages 与页面的 lang 用它。i18n 缺席时为空,取链出错时告警
19
+ * (与渲染共用一次)并为空
20
+ */
21
+ languages(): readonly string[];
22
+ }
23
+ export declare function createLocalizer(i18n: Pick<ServiceSelection<I18nService>, 'present' | 'use'>, logger: Logger): Localizer;
24
+ //# sourceMappingURL=localize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localize.d.ts","sourceRoot":"","sources":["../src/localize.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,WAAW,EAAe,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACpF,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAInC,yDAAyD;AACzD,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAE9E;AAKD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,YAAY,CAa3E;AAED,MAAM,WAAW,SAAS;IACxB,6BAA6B;IAC7B,UAAU,EAAE,OAAO,CAAC,cAAc,CAAC;IACnC,wBAAwB;IACxB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IAC3D;;;OAGG;IACH,SAAS,IAAI,SAAS,MAAM,EAAE,CAAC;CAChC;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,EAC5D,MAAM,EAAE,MAAM,GACb,SAAS,CA0BX"}
@@ -0,0 +1,68 @@
1
+ // ============================================================
2
+ // localize.ts — 回应里的文字按全局层的语言渲染
3
+ //
4
+ // WebUI 的读者是 owner 自己:一律按全局层的语言(i18n 的 { host: true } 读者),日期与时间按服务进程的时区,不看浏览器的
5
+ // 语言与时区(会话与场所的语言设置管的是聊天平台上的读者)。
6
+ // 最早挂的中间件包住 res.json:值里的文字对象渲染后再发,i18n 缺席或渲染抛错时按原文(抛错只告警一次)。路由里外的 JSON 回应
7
+ // (认证的 401 与 403、闸门、未知 API、错误处理)都经过它;不经 res.json 的文字(纯文本的错误、登录页与恢复页、access.txt)
8
+ // 用 render。原样数据(插件配置值、schema 的默认值、插件前端的数据)要跳过、Markdown 正文要转义时,路由在 res.json 之前经
9
+ // renderWith 交代。
10
+ // ============================================================
11
+ import { localizeFor } from '@aalis/api-i18n';
12
+ const optionsOf = new WeakMap();
13
+ /** 交代这次回应的渲染选项:要跳过的原样数据、Markdown 正文的转义。在 res.json 之前调 */
14
+ export function renderWith(res, options) {
15
+ optionsOf.set(res, options);
16
+ }
17
+ const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
18
+ /**
19
+ * schema(插件配置、核心配置、动作的输入字段)里的 default 是取值,不是文字:跳过它们,形如文字对象的默认值原样交出,表单读回
20
+ * 再保存时不被改写成字符串。字段、分组、数组与元素字段按对象身份认,不按键名(配置里可能有名叫 default 的字段)
21
+ */
22
+ export function skipSchemaDefaults(schemas) {
23
+ const entries = new Set();
24
+ const collect = (schema) => {
25
+ if (!isRecord(schema))
26
+ return;
27
+ for (const entry of Object.values(schema)) {
28
+ if (!isRecord(entry) || entries.has(entry))
29
+ continue;
30
+ entries.add(entry);
31
+ collect(entry.fields);
32
+ collect(entry.items);
33
+ }
34
+ };
35
+ for (const schema of schemas)
36
+ collect(schema);
37
+ return (key, parent) => key === 'default' && entries.has(parent);
38
+ }
39
+ export function createLocalizer(i18n, logger) {
40
+ let warned = false;
41
+ const onError = (err) => {
42
+ if (warned)
43
+ return;
44
+ warned = true;
45
+ logger.warn('按全局层的语言渲染出错,按原文发出(之后再出错不再告警):', err);
46
+ };
47
+ const render = (value, options) => localizeFor(i18n, value, { host: true }, { ...options, onError });
48
+ return {
49
+ middleware: (_req, res, next) => {
50
+ const send = res.json.bind(res);
51
+ res.json = body => send(render(body, optionsOf.get(res)));
52
+ next();
53
+ },
54
+ render,
55
+ languages: () => {
56
+ if (!i18n.present)
57
+ return [];
58
+ try {
59
+ return i18n.use.chainOf({ host: true });
60
+ }
61
+ catch (err) {
62
+ onError(err);
63
+ return [];
64
+ }
65
+ },
66
+ };
67
+ }
68
+ //# sourceMappingURL=localize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localize.js","sourceRoot":"","sources":["../src/localize.ts"],"names":[],"mappings":"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"}
package/dist/logs.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import type { LogFilter } from '@aalis/api-webui';
2
+ import type { LogEntry } from '@aalis/core';
3
+ /** 读出筛选:三项都只收字符串,级别要是四种之一,空字符串当没给;写法不对回 undefined */
4
+ export declare function parseLogFilter(value: unknown): LogFilter | undefined;
5
+ /**
6
+ * 按筛选判定日志的函数。registered 是此刻登记着的插件实例:按插件筛时用它分开后缀实例与子作用域;筛的那个实例本身
7
+ * 总认得,卸掉了的插件照样能按名字筛它留下的日志
8
+ */
9
+ export declare function logMatcher(registered: (instance: string) => boolean): (filter: LogFilter) => (entry: LogEntry) => boolean;
10
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,aAAa,CAAC;AAItD,qDAAqD;AACrD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAQpE;AAeD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,IAC1D,QAAQ,SAAS,MAKf,OAAO,QAAQ,KAAG,OAAO,CAKpC"}
package/dist/logs.js ADDED
@@ -0,0 +1,50 @@
1
+ // ============================================================
2
+ // logs.ts — 日志的筛选
3
+ //
4
+ // 历史与实时都由宿主的 host-logs 服务给(@aalis/api-host-logs)。筛选(api-webui 的 LogFilter)在这里一处定,
5
+ // 历史(/api/logs/*)与 /admin 的实时推送用同一个判定。
6
+ // ============================================================
7
+ const LEVELS = ['debug', 'info', 'warn', 'error'];
8
+ /** 读出筛选:三项都只收字符串,级别要是四种之一,空字符串当没给;写法不对回 undefined */
9
+ export function parseLogFilter(value) {
10
+ if (value === undefined)
11
+ return {};
12
+ if (typeof value !== 'object' || value === null)
13
+ return undefined;
14
+ const { level, plugin, text } = value;
15
+ const fields = { level, plugin, text };
16
+ if (Object.values(fields).some(field => field !== undefined && typeof field !== 'string'))
17
+ return undefined;
18
+ if (level && !LEVELS.includes(level))
19
+ return undefined;
20
+ return Object.fromEntries(Object.entries(fields).filter(([, field]) => field));
21
+ }
22
+ /**
23
+ * 一条日志所属的插件实例:作用域是根作用域、实例 id、插件自己分出的子作用域依次用「:」接起来(core 给每个激活的 logger
24
+ * 是根 logger 的 child)。后缀实例(name:suffix)与主实例的子作用域同形,取 known 认得的最长的那个
25
+ */
26
+ function ownerOf(scope, known) {
27
+ const segments = scope.split(':').slice(1);
28
+ for (let n = segments.length; n > 0; n--) {
29
+ const instance = segments.slice(0, n).join(':');
30
+ if (known(instance))
31
+ return instance;
32
+ }
33
+ return undefined;
34
+ }
35
+ /**
36
+ * 按筛选判定日志的函数。registered 是此刻登记着的插件实例:按插件筛时用它分开后缀实例与子作用域;筛的那个实例本身
37
+ * 总认得,卸掉了的插件照样能按名字筛它留下的日志
38
+ */
39
+ export function logMatcher(registered) {
40
+ return (filter) => {
41
+ const floor = filter.level === undefined ? 0 : LEVELS.indexOf(filter.level);
42
+ const text = filter.text?.toLowerCase();
43
+ const { plugin } = filter;
44
+ const known = (instance) => instance === plugin || registered(instance);
45
+ return (entry) => LEVELS.indexOf(entry.level) >= floor &&
46
+ (text === undefined || entry.message.toLowerCase().includes(text)) &&
47
+ (plugin === undefined || ownerOf(entry.scope, known) === plugin);
48
+ };
49
+ }
50
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,kBAAkB;AAClB,EAAE;AACF,kFAAkF;AAClF,uCAAuC;AACvC,+DAA+D;AAK/D,MAAM,MAAM,GAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAEvE,qDAAqD;AACrD,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACnC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAClE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAgC,CAAC;IACjE,MAAM,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACvC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAC;IAC5G,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAiB,CAAC;QAAE,OAAO,SAAS,CAAC;IACnE,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAc,CAAC;AAC9F,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CAAC,KAAa,EAAE,KAAoC;IAClE,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChD,IAAI,KAAK,CAAC,QAAQ,CAAC;YAAE,OAAO,QAAQ,CAAC;IACvC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,UAAyC;IAClE,OAAO,CAAC,MAAiB,EAAE,EAAE;QAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5E,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC;QACxC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;QAC1B,MAAM,KAAK,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,QAAQ,KAAK,MAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;QAChF,OAAO,CAAC,KAAe,EAAW,EAAE,CAClC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK;YACpC,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAClE,CAAC,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,MAAM,CAAC,CAAC;IACrE,CAAC,CAAC;AACJ,CAAC"}