@jwilleke/ngdpbase-types 0.0.0 → 5.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +16 -2
- package/lib/packages/ngdpbase-types/index.d.ts +32 -0
- package/lib/packages/ngdpbase-types/testing.d.ts +43 -0
- package/lib/packages/ngdpbase-types/testing.js +53 -0
- package/lib/src/cache/CacheDependencies.d.ts +50 -0
- package/lib/src/cache/CacheDependencies.js +50 -0
- package/lib/src/cache/ICacheAdapter.d.ts +86 -0
- package/lib/src/cache/RegionCache.d.ts +171 -0
- package/lib/src/context/ActorContext.d.ts +48 -0
- package/lib/src/context/ActorContext.js +33 -0
- package/lib/src/context/ApiContext.d.ts +194 -0
- package/lib/src/context/ApiContext.js +273 -0
- package/lib/src/context/BaseContext.d.ts +110 -0
- package/lib/src/context/BaseContext.js +143 -0
- package/lib/src/context/JobContext.d.ts +153 -0
- package/lib/src/context/JobContext.js +144 -0
- package/lib/src/context/WikiContext.d.ts +404 -0
- package/lib/src/context/bootActions.d.ts +64 -0
- package/lib/src/context/bootActions.js +111 -0
- package/lib/src/converters/HtmlConverter.d.ts +70 -0
- package/lib/src/converters/IContentConverter.d.ts +94 -0
- package/lib/src/converters/JSPWikiConverter.d.ts +117 -0
- package/lib/src/converters/conversionWarning.d.ts +15 -0
- package/lib/src/converters/ncm/bridge.d.ts +22 -0
- package/lib/src/converters/ncm/existing.d.ts +23 -0
- package/lib/src/converters/ncm/fix/blocks.d.ts +89 -0
- package/lib/src/converters/ncm/fix/bulletMarkers.d.ts +21 -0
- package/lib/src/converters/ncm/fix/index.d.ts +36 -0
- package/lib/src/converters/ncm/fix/jspwikiBullets.d.ts +20 -0
- package/lib/src/converters/ncm/fix/jspwikiCodeMarkers.d.ts +38 -0
- package/lib/src/converters/ncm/fix/jspwikiHeadings.d.ts +25 -0
- package/lib/src/converters/ncm/fix/jspwikiIndent.d.ts +24 -0
- package/lib/src/converters/ncm/fix/jspwikiInsert.d.ts +21 -0
- package/lib/src/converters/ncm/fix/jspwikiItalic.d.ts +29 -0
- package/lib/src/converters/ncm/fix/jspwikiLinkLeftovers.d.ts +27 -0
- package/lib/src/converters/ncm/fix/moreInformationFooter.d.ts +25 -0
- package/lib/src/converters/ncm/fix/styleClosers.d.ts +25 -0
- package/lib/src/converters/ncm/fix/tightenLists.d.ts +30 -0
- package/lib/src/converters/ncm/fix/types.d.ts +33 -0
- package/lib/src/converters/ncm/footnotes.d.ts +39 -0
- package/lib/src/converters/ncm/images.d.ts +49 -0
- package/lib/src/converters/ncm/index.d.ts +20 -0
- package/lib/src/converters/ncm/links.d.ts +21 -0
- package/lib/src/converters/ncm/normalize.d.ts +39 -0
- package/lib/src/converters/ncm/placeholder.d.ts +25 -0
- package/lib/src/converters/ncm/tables.d.ts +36 -0
- package/lib/src/converters/ncm/types.d.ts +42 -0
- package/lib/src/http/egressPolicy.d.ts +52 -0
- package/lib/src/http/guardedFetch.d.ts +89 -0
- package/lib/src/http/guardedFetch.js +113 -0
- package/lib/src/http/guardedLookup.d.ts +48 -0
- package/lib/src/http/guardedLookup.js +73 -0
- package/lib/src/http/ssrf.d.ts +83 -0
- package/lib/src/http/ssrf.js +311 -0
- package/lib/src/mail/MailProvider.d.ts +36 -0
- package/lib/src/mail/NodemailerMailProvider.d.ts +26 -0
- package/lib/src/managers/AddonsManager.d.ts +691 -0
- package/lib/src/managers/AgentTokenManager.d.ts +269 -0
- package/lib/src/managers/AssetManager.d.ts +116 -0
- package/lib/src/managers/AttachmentManager.d.ts +1032 -0
- package/lib/src/managers/AuthManager.d.ts +1257 -0
- package/lib/src/managers/BackgroundJobManager.d.ts +434 -0
- package/lib/src/managers/BaseManager.d.ts +427 -0
- package/lib/src/managers/BaseManager.js +415 -0
- package/lib/src/managers/CacheManager.d.ts +159 -0
- package/lib/src/managers/CatalogManager.d.ts +235 -0
- package/lib/src/managers/CommentManager.d.ts +75 -0
- package/lib/src/managers/ConfigurationManager.d.ts +747 -0
- package/lib/src/managers/DatabaseManager.d.ts +188 -0
- package/lib/src/managers/DatabaseManager.js +590 -0
- package/lib/src/managers/EmailManager.d.ts +47 -0
- package/lib/src/managers/ExportManager.d.ts +129 -0
- package/lib/src/managers/ExportManager.js +420 -0
- package/lib/src/managers/FootnoteManager.d.ts +118 -0
- package/lib/src/managers/MediaManager.d.ts +279 -0
- package/lib/src/managers/MetricsManager.d.ts +89 -0
- package/lib/src/managers/NotificationManager.d.ts +165 -0
- package/lib/src/managers/OidcManager.d.ts +210 -0
- package/lib/src/managers/OrganizationManager.d.ts +107 -0
- package/lib/src/managers/PageManager.d.ts +1645 -0
- package/lib/src/managers/PersonManager.d.ts +48 -0
- package/lib/src/managers/PluginManager.d.ts +179 -0
- package/lib/src/managers/PluginManager.js +393 -0
- package/lib/src/managers/PolicyEvaluator.d.ts +213 -0
- package/lib/src/managers/RenderingManager.d.ts +358 -0
- package/lib/src/managers/RoleManager.d.ts +134 -0
- package/lib/src/managers/SearchManager.d.ts +402 -0
- package/lib/src/managers/ShareManager.d.ts +251 -0
- package/lib/src/managers/TemplateManager.d.ts +176 -0
- package/lib/src/managers/ThemeManager.d.ts +56 -0
- package/lib/src/managers/UserManager.d.ts +480 -0
- package/lib/src/managers/ValidationManager.d.ts +426 -0
- package/lib/src/managers/VariableManager.d.ts +145 -0
- package/lib/src/middleware/csrf.d.ts +3 -0
- package/lib/src/parsers/LinkParser.d.ts +457 -0
- package/lib/src/parsers/MarkupParser.d.ts +769 -0
- package/lib/src/parsers/context/ParseContext.d.ts +314 -0
- package/lib/src/parsers/data/emoji-map.d.ts +18 -0
- package/lib/src/parsers/dom/DOMBuilder.d.ts +210 -0
- package/lib/src/parsers/dom/DOMParser.d.ts +252 -0
- package/lib/src/parsers/dom/Tokenizer.d.ts +358 -0
- package/lib/src/parsers/dom/WikiDocument.d.ts +272 -0
- package/lib/src/parsers/dom/handlers/DOMLinkHandler.d.ts +260 -0
- package/lib/src/parsers/dom/handlers/DOMPluginHandler.d.ts +212 -0
- package/lib/src/parsers/dom/handlers/DOMVariableHandler.d.ts +171 -0
- package/lib/src/parsers/filters/BaseFilter.d.ts +269 -0
- package/lib/src/parsers/filters/FilterChain.d.ts +320 -0
- package/lib/src/parsers/handlers/BaseSyntaxHandler.d.ts +331 -0
- package/lib/src/parsers/handlers/HandlerRegistry.d.ts +225 -0
- package/lib/src/parsers/handlers/JSPWikiPreprocessor.d.ts +89 -0
- package/lib/src/parsers/handlers/LinkParserHandler.d.ts +80 -0
- package/lib/src/parsers/handlers/PluginSyntaxHandler.d.ts +78 -0
- package/lib/src/parsers/handlers/WikiFormHandler.d.ts +149 -0
- package/lib/src/parsers/handlers/WikiTagHandler.d.ts +125 -0
- package/lib/src/parsers/jspwikiTableRow.d.ts +39 -0
- package/lib/src/parsers/styleBlockSyntax.d.ts +14 -0
- package/lib/src/plugins/types.d.ts +79 -0
- package/lib/src/providers/AgentTokenAuthProvider.d.ts +40 -0
- package/lib/src/providers/AuthentikBearerAuthProvider.d.ts +75 -0
- package/lib/src/providers/BaseAttachmentProvider.d.ts +197 -0
- package/lib/src/providers/BaseAuthProvider.d.ts +220 -0
- package/lib/src/providers/BaseCacheProvider.d.ts +140 -0
- package/lib/src/providers/BaseCredentialsProvider.d.ts +84 -0
- package/lib/src/providers/BaseDatabaseProvider.d.ts +22 -0
- package/lib/src/providers/BaseDatabaseProvider.js +12 -0
- package/lib/src/providers/BaseLoggingProvider.d.ts +68 -0
- package/lib/src/providers/BaseLoggingProvider.js +37 -0
- package/lib/src/providers/BaseMediaProvider.d.ts +308 -0
- package/lib/src/providers/BasePageProvider.d.ts +337 -0
- package/lib/src/providers/BaseProvider.d.ts +98 -0
- package/lib/src/providers/BaseProvider.js +74 -0
- package/lib/src/providers/BaseSearchProvider.d.ts +362 -0
- package/lib/src/providers/BasicAttachmentProvider.d.ts +599 -0
- package/lib/src/providers/CloudflareAccessAuthProvider.d.ts +72 -0
- package/lib/src/providers/FileCredentialsProvider.d.ts +33 -0
- package/lib/src/providers/FileJobStateProvider.d.ts +58 -0
- package/lib/src/providers/FileLoggingProvider.d.ts +43 -0
- package/lib/src/providers/FileLoggingProvider.js +120 -0
- package/lib/src/providers/FileOidcAdapter.d.ts +25 -0
- package/lib/src/providers/FileSystemMediaProvider.d.ts +403 -0
- package/lib/src/providers/LunrSearchProvider.d.ts +280 -0
- package/lib/src/providers/MagicLinkAuthProvider.d.ts +125 -0
- package/lib/src/providers/NullCacheProvider.d.ts +72 -0
- package/lib/src/providers/OidcAuthProvider.d.ts +180 -0
- package/lib/src/providers/OidcBearerAuthProvider.d.ts +30 -0
- package/lib/src/providers/PasskeyAuthProvider.d.ts +58 -0
- package/lib/src/providers/PasswordAuthProvider.d.ts +20 -0
- package/lib/src/providers/SqliteDatabaseProvider.d.ts +55 -0
- package/lib/src/providers/SqliteDatabaseProvider.js +90 -0
- package/lib/src/providers/SqliteJobStateProvider.d.ts +41 -0
- package/lib/src/providers/databaseMigrations.d.ts +8 -0
- package/lib/src/providers/databaseMigrations.js +47 -0
- package/lib/src/providers/jobState.d.ts +99 -0
- package/lib/src/providers/lunrQueryToMiniSearch.d.ts +32 -0
- package/lib/src/providers/mediaFilenameDate.d.ts +22 -0
- package/lib/src/providers/sqliteBackup.d.ts +128 -0
- package/lib/src/providers/sqliteBackup.js +365 -0
- package/lib/src/providers/sqliteLocation.d.ts +17 -0
- package/lib/src/providers/sqliteLocation.js +55 -0
- package/lib/src/providers/sqliteMigrations.d.ts +48 -0
- package/lib/src/providers/sqliteMigrations.js +72 -0
- package/lib/src/rendering/githubAlerts.d.ts +22 -0
- package/lib/src/rendering/htmlPolicy.d.ts +76 -0
- package/lib/src/rendering/markdownConverter.d.ts +73 -0
- package/lib/src/security/PolicyDecisionPoint.d.ts +245 -0
- package/lib/src/security/PolicyInformationPoint.d.ts +448 -0
- package/lib/src/security/pageActions.d.ts +40 -0
- package/lib/src/security/permissions.generated.d.ts +78 -0
- package/lib/src/types/Asset.d.ts +414 -0
- package/lib/src/types/Catalog.d.ts +61 -0
- package/lib/src/types/Comment.d.ts +11 -0
- package/lib/src/types/Config.d.ts +388 -0
- package/lib/src/types/Organization.d.ts +78 -0
- package/lib/src/types/OrganizationProvider.d.ts +38 -0
- package/lib/src/types/Page.d.ts +220 -0
- package/lib/src/types/Person.d.ts +56 -0
- package/lib/src/types/PersonProvider.d.ts +25 -0
- package/lib/src/types/Policy.d.ts +139 -0
- package/lib/src/types/Policy.js +17 -0
- package/lib/src/types/Provider.d.ts +810 -0
- package/lib/src/types/Role.d.ts +84 -0
- package/lib/src/types/RoleProvider.d.ts +35 -0
- package/lib/src/types/Schema.d.ts +425 -0
- package/lib/src/types/Share.d.ts +172 -0
- package/lib/src/types/Share.js +81 -0
- package/lib/src/types/User.d.ts +304 -0
- package/lib/src/types/Version.d.ts +189 -0
- package/lib/src/types/WikiEngine.d.ts +128 -0
- package/lib/src/types/express.d.ts +120 -0
- package/lib/src/types/express.js +1 -0
- package/lib/src/types/guards.d.ts +78 -0
- package/lib/src/types/heic-decode.d.ts +16 -0
- package/lib/src/types/index.d.ts +19 -0
- package/lib/src/types/linkedom.d.ts +77 -0
- package/lib/src/types/markdown-it-plugins.d.ts +21 -0
- package/lib/src/utils/DeltaStorage.d.ts +118 -0
- package/lib/src/utils/LocaleUtils.d.ts +105 -0
- package/lib/src/utils/LocaleUtils.js +294 -0
- package/lib/src/utils/PageNameMatcher.d.ts +98 -0
- package/lib/src/utils/PathPreflight.d.ts +38 -0
- package/lib/src/utils/PathPreflight.js +50 -0
- package/lib/src/utils/SectionUtils.d.ts +40 -0
- package/lib/src/utils/addonConfigLayer.d.ts +144 -0
- package/lib/src/utils/addonConfigLayer.js +382 -0
- package/lib/src/utils/addonDatabaseRules.d.ts +25 -0
- package/lib/src/utils/addonDatabaseRules.js +57 -0
- package/lib/src/utils/addonHost.d.ts +51 -0
- package/lib/src/utils/addonHost.js +72 -0
- package/lib/src/utils/addonInstaller.d.ts +109 -0
- package/lib/src/utils/addonLock.d.ts +37 -0
- package/lib/src/utils/addonLock.js +48 -0
- package/lib/src/utils/addonPageSync.d.ts +45 -0
- package/lib/src/utils/addonProvenance.d.ts +48 -0
- package/lib/src/utils/addonTarball.d.ts +41 -0
- package/lib/src/utils/addonsPathResolver.d.ts +76 -0
- package/lib/src/utils/addonsPathResolver.js +129 -0
- package/lib/src/utils/assetMetadataTags.d.ts +66 -0
- package/lib/src/utils/atomicWrite.d.ts +28 -0
- package/lib/src/utils/auditConfigChange.d.ts +57 -0
- package/lib/src/utils/auditEventNames.d.ts +50 -0
- package/lib/src/utils/auditEventNames.generated.d.ts +169 -0
- package/lib/src/utils/auditEventNames.generated.js +174 -0
- package/lib/src/utils/auditEventNames.js +49 -0
- package/lib/src/utils/auditEvents.d.ts +265 -0
- package/lib/src/utils/auditEvents.js +309 -0
- package/lib/src/utils/auditRegistry.d.ts +102 -0
- package/lib/src/utils/auditRegistry.js +168 -0
- package/lib/src/utils/bip39English.d.ts +2 -0
- package/lib/src/utils/configEnvKeys.d.ts +68 -0
- package/lib/src/utils/configFiles.d.ts +74 -0
- package/lib/src/utils/configFiles.js +150 -0
- package/lib/src/utils/delegation.d.ts +48 -0
- package/lib/src/utils/deriveUsername.d.ts +21 -0
- package/lib/src/utils/explainMediaPath.d.ts +123 -0
- package/lib/src/utils/formerTitles.d.ts +69 -0
- package/lib/src/utils/frontmatterAccess.d.ts +54 -0
- package/lib/src/utils/headlessAdminPassword.d.ts +55 -0
- package/lib/src/utils/imageTransform.d.ts +52 -0
- package/lib/src/utils/instanceEnvSecret.d.ts +51 -0
- package/lib/src/utils/jobSlots.d.ts +43 -0
- package/lib/src/utils/keywordNormalizer.d.ts +127 -0
- package/lib/src/utils/logger.d.ts +70 -0
- package/lib/src/utils/logger.js +106 -0
- package/lib/src/utils/magicLinkDeviceState.d.ts +95 -0
- package/lib/src/utils/managerUtils.d.ts +40 -0
- package/lib/src/utils/migrateLegacyPrivateAttachments.d.ts +15 -0
- package/lib/src/utils/orgFilename.d.ts +22 -0
- package/lib/src/utils/pageFeature.d.ts +27 -0
- package/lib/src/utils/pageFrontmatter.d.ts +21 -0
- package/lib/src/utils/pageNotes.d.ts +150 -0
- package/lib/src/utils/pageTitleRule.d.ts +37 -0
- package/lib/src/utils/pageToArticle.d.ts +59 -0
- package/lib/src/utils/pageUrl.d.ts +18 -0
- package/lib/src/utils/passwordChange.d.ts +12 -0
- package/lib/src/utils/passwordHash.d.ts +60 -0
- package/lib/src/utils/permissionCatalog.d.ts +52 -0
- package/lib/src/utils/pluginFormatters.d.ts +452 -0
- package/lib/src/utils/pluginFormatters.js +714 -0
- package/lib/src/utils/privateLinkRewrite.d.ts +42 -0
- package/lib/src/utils/privateStoreAccess.d.ts +57 -0
- package/lib/src/utils/privateStoreAccess.js +65 -0
- package/lib/src/utils/privateStoreCatalogs.d.ts +40 -0
- package/lib/src/utils/privateStoreCrypto.d.ts +127 -0
- package/lib/src/utils/privateStoreDoor.d.ts +181 -0
- package/lib/src/utils/privateStoreExport.d.ts +72 -0
- package/lib/src/utils/privateStoreFiles.d.ts +120 -0
- package/lib/src/utils/privateStoreMeta.d.ts +64 -0
- package/lib/src/utils/privateStoreMigrations.d.ts +37 -0
- package/lib/src/utils/privateStorePath.d.ts +259 -0
- package/lib/src/utils/privateStorePath.js +436 -0
- package/lib/src/utils/privateStoreTakeout.d.ts +76 -0
- package/lib/src/utils/privateStoreUnlock.d.ts +175 -0
- package/lib/src/utils/proxyClaim.d.ts +59 -0
- package/lib/src/utils/proxyClaim.js +30 -0
- package/lib/src/utils/redactPrivateNames.d.ts +21 -0
- package/lib/src/utils/redactPrivateNames.js +89 -0
- package/lib/src/utils/redactSecrets.d.ts +58 -0
- package/lib/src/utils/redactSecrets.js +171 -0
- package/lib/src/utils/renameLinkRewrite.d.ts +112 -0
- package/lib/src/utils/roleGrants.d.ts +35 -0
- package/lib/src/utils/safeRedirect.d.ts +32 -0
- package/lib/src/utils/schedule.d.ts +54 -0
- package/lib/src/utils/secretFileMode.d.ts +17 -0
- package/lib/src/utils/seededShippedPages.d.ts +45 -0
- package/lib/src/utils/sensitiveValues.d.ts +59 -0
- package/lib/src/utils/sensitiveValues.js +106 -0
- package/lib/src/utils/sessionEnd.d.ts +12 -0
- package/lib/src/utils/sessionGeneration.d.ts +24 -0
- package/lib/src/utils/sessionIdle.d.ts +41 -0
- package/lib/src/utils/sessionLimits.d.ts +68 -0
- package/lib/src/utils/shareLockbox.d.ts +64 -0
- package/lib/src/utils/sigstoreTrustedRoot.d.ts +33 -0
- package/lib/src/utils/sniffMime.d.ts +21 -0
- package/lib/src/utils/storeSearchIndex.d.ts +75 -0
- package/lib/src/utils/subjectMayDo.d.ts +21 -0
- package/lib/src/utils/systemCategoryRules.d.ts +30 -0
- package/lib/src/utils/systemCategoryRules.js +41 -0
- package/lib/src/utils/userCreateError.d.ts +62 -0
- package/lib/src/utils/username.d.ts +53 -0
- package/lib/src/utils/vaultUrlRewrite.d.ts +27 -0
- package/lib/src/utils/version.d.ts +84 -0
- package/lib/src/utils/videoFrame.d.ts +21 -0
- package/package.json +54 -3
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scheduled-job state in the application database (#1714). See `jobState.ts`.
|
|
3
|
+
*
|
|
4
|
+
* Uses the one connection `DatabaseManager.getHandle()` hands out — never a
|
|
5
|
+
* database file of its own — so it is encrypted when the database is
|
|
6
|
+
* (SQLCipher, `NGDPBASE_DATABASE_KEY`). The tables come from the core
|
|
7
|
+
* migration ledger (`databaseMigrations.ts`, 20261008180000).
|
|
8
|
+
*
|
|
9
|
+
* A lock is a row in `job_leases`, taken by one conditional write: insert it,
|
|
10
|
+
* or overwrite it only when it has expired or already belongs to the caller.
|
|
11
|
+
* SQLite runs that statement as one unit, so of any servers racing for a slot
|
|
12
|
+
* exactly one sees its row change.
|
|
13
|
+
*
|
|
14
|
+
* @module providers/SqliteJobStateProvider
|
|
15
|
+
*/
|
|
16
|
+
import type Database from 'better-sqlite3-multiple-ciphers';
|
|
17
|
+
import { type JobRunRecord, type JobState, type JobStateLimits, type JobStateProvider } from './jobState.js';
|
|
18
|
+
type Handle = InstanceType<typeof Database>;
|
|
19
|
+
export interface SqliteJobStateOptions extends JobStateLimits {
|
|
20
|
+
/** For tests: the clock. */
|
|
21
|
+
now?: () => number;
|
|
22
|
+
}
|
|
23
|
+
declare class SqliteJobStateProvider implements JobStateProvider {
|
|
24
|
+
private readonly db;
|
|
25
|
+
readonly backend: "sqlite";
|
|
26
|
+
private readonly historyLimit;
|
|
27
|
+
private readonly checkpointMaxBytes;
|
|
28
|
+
private readonly now;
|
|
29
|
+
constructor(db: Handle, options?: SqliteJobStateOptions);
|
|
30
|
+
getState(jobId: string): Promise<JobState | null>;
|
|
31
|
+
putState(state: JobState): Promise<void>;
|
|
32
|
+
recordRun(jobId: string, run: JobRunRecord): Promise<void>;
|
|
33
|
+
listRuns(jobId: string): Promise<JobRunRecord[]>;
|
|
34
|
+
saveCheckpoint(jobId: string, runId: string, data: unknown): Promise<void>;
|
|
35
|
+
loadCheckpoint(jobId: string, runId: string): Promise<unknown>;
|
|
36
|
+
clearCheckpoint(jobId: string, runId: string): Promise<void>;
|
|
37
|
+
takeLock(jobId: string, slot: string, owner: string, ttlMs: number): Promise<boolean>;
|
|
38
|
+
renewLock(jobId: string, slot: string, owner: string, ttlMs: number): Promise<boolean>;
|
|
39
|
+
releaseLock(jobId: string, slot: string, owner: string): Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
export default SqliteJobStateProvider;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The application database's migration ledger (#1536), strictly ascending by
|
|
3
|
+
* id (YYYYMMDDHHMMSS). Each entry is a frozen snapshot of what it did on its
|
|
4
|
+
* date; see `sqliteMigrations.ts`.
|
|
5
|
+
*/
|
|
6
|
+
import type { Migration } from './sqliteMigrations.js';
|
|
7
|
+
declare const DATABASE_MIGRATIONS: Migration[];
|
|
8
|
+
export default DATABASE_MIGRATIONS;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const DATABASE_MIGRATIONS = [
|
|
2
|
+
{
|
|
3
|
+
// #1714: scheduled-job state, history, checkpoints and slot locks.
|
|
4
|
+
id: '20261008180000',
|
|
5
|
+
description: 'scheduled jobs: job_state, job_runs, job_checkpoints, job_leases',
|
|
6
|
+
up: (db) => {
|
|
7
|
+
db.exec(`CREATE TABLE job_state (
|
|
8
|
+
job_id TEXT PRIMARY KEY,
|
|
9
|
+
last_slot_done TEXT,
|
|
10
|
+
next_slot TEXT,
|
|
11
|
+
current_run TEXT,
|
|
12
|
+
updated_at TEXT NOT NULL
|
|
13
|
+
)`);
|
|
14
|
+
db.exec(`CREATE TABLE job_runs (
|
|
15
|
+
run_id TEXT PRIMARY KEY,
|
|
16
|
+
job_id TEXT NOT NULL,
|
|
17
|
+
started_at TEXT NOT NULL,
|
|
18
|
+
record TEXT NOT NULL
|
|
19
|
+
)`);
|
|
20
|
+
db.exec('CREATE INDEX job_runs_by_job ON job_runs (job_id, started_at)');
|
|
21
|
+
db.exec(`CREATE TABLE job_checkpoints (
|
|
22
|
+
job_id TEXT NOT NULL,
|
|
23
|
+
run_id TEXT NOT NULL,
|
|
24
|
+
data TEXT NOT NULL,
|
|
25
|
+
updated_at TEXT NOT NULL,
|
|
26
|
+
PRIMARY KEY (job_id, run_id)
|
|
27
|
+
)`);
|
|
28
|
+
db.exec(`CREATE TABLE job_leases (
|
|
29
|
+
job_id TEXT NOT NULL,
|
|
30
|
+
slot TEXT NOT NULL,
|
|
31
|
+
owner TEXT NOT NULL,
|
|
32
|
+
expires_at INTEGER NOT NULL,
|
|
33
|
+
PRIMARY KEY (job_id, slot)
|
|
34
|
+
)`);
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
// #1715: the schedule a job's slots were computed from, so a rule changed
|
|
39
|
+
// while the server was down is recomputed rather than caught up.
|
|
40
|
+
id: '20261009140000',
|
|
41
|
+
description: 'scheduled jobs: job_state.rule',
|
|
42
|
+
up: (db) => {
|
|
43
|
+
db.exec('ALTER TABLE job_state ADD COLUMN rule TEXT');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
];
|
|
47
|
+
export default DATABASE_MIGRATIONS;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where scheduled jobs keep what must survive a restart (#1714, epic #1611):
|
|
3
|
+
* each job's last slot done, its next slot and its current run, a capped run
|
|
4
|
+
* history, a run's checkpoint, and the lock that lets exactly one server run a
|
|
5
|
+
* slot.
|
|
6
|
+
*
|
|
7
|
+
* Two backends, one contract (`__tests__/jobStateContract.ts` runs against
|
|
8
|
+
* both):
|
|
9
|
+
* - `file` — JSON in FAST_STORAGE, written atomically; a lock is a file
|
|
10
|
+
* created exclusively;
|
|
11
|
+
* - `sqlite` — tables in the application database (DatabaseManager), changed
|
|
12
|
+
* in transactions; a lock is a row taken by a conditional write.
|
|
13
|
+
*
|
|
14
|
+
* `selectJobStateBackend` reads `ngdpbase.jobs.state.provider`: `auto` picks
|
|
15
|
+
* `sqlite` when the application database is open, else `file`. Switching
|
|
16
|
+
* backends carries nothing across: the new one starts empty, next slots are
|
|
17
|
+
* recomputed and missed slots are not caught up.
|
|
18
|
+
*
|
|
19
|
+
* @module providers/jobState
|
|
20
|
+
*/
|
|
21
|
+
import type { JobContext } from '../context/JobContext.js';
|
|
22
|
+
/** One run of a job. Times are ISO 8601 instants. */
|
|
23
|
+
export interface JobRunRecord {
|
|
24
|
+
runId: string;
|
|
25
|
+
/** The slot this run is for; null for a run someone started by hand. */
|
|
26
|
+
slot: string | null;
|
|
27
|
+
startedAt: string;
|
|
28
|
+
/** 1 for the first try; a run resumed after a restart counts up. */
|
|
29
|
+
attempt: number;
|
|
30
|
+
/** `skipped`: a slot the scheduler passed over, by its catch-up or overlap rule (#1715). */
|
|
31
|
+
status: 'running' | 'completed' | 'failed' | 'interrupted' | 'skipped';
|
|
32
|
+
completedAt?: string;
|
|
33
|
+
error?: string;
|
|
34
|
+
/** A failed attempt with attempts left: when it is tried again (#1716). */
|
|
35
|
+
retryAt?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Who asked, for a run started by hand (#1746): the run is restarted as
|
|
38
|
+
* them after a restart, or reported to them. `null` for a scheduled slot,
|
|
39
|
+
* which runs as the system principal — said on purpose (#1399), never left
|
|
40
|
+
* out. A record written before this field existed reads as having none.
|
|
41
|
+
*/
|
|
42
|
+
requestedBy: JobContext | null;
|
|
43
|
+
}
|
|
44
|
+
export interface JobState {
|
|
45
|
+
jobId: string;
|
|
46
|
+
lastSlotDone: string | null;
|
|
47
|
+
/** The first slot not yet handled: run, skipped or failed (#1715). */
|
|
48
|
+
nextSlot: string | null;
|
|
49
|
+
current: JobRunRecord | null;
|
|
50
|
+
/**
|
|
51
|
+
* The schedule the slots were computed from (`rrule|dtstart|timeZone`), so a
|
|
52
|
+
* rule changed while the server was down is seen at the next start: slots
|
|
53
|
+
* are recomputed from then, and nothing is caught up for the old rule
|
|
54
|
+
* (#1715). Null for state written before the rule was kept.
|
|
55
|
+
*/
|
|
56
|
+
rule: string | null;
|
|
57
|
+
}
|
|
58
|
+
export interface JobStateLimits {
|
|
59
|
+
/** Runs kept per job (`ngdpbase.jobs.history-limit`). Default 50. */
|
|
60
|
+
historyLimit?: number;
|
|
61
|
+
/** Largest checkpoint accepted, in bytes of JSON. Default 256 KiB. */
|
|
62
|
+
checkpointMaxBytes?: number;
|
|
63
|
+
}
|
|
64
|
+
export declare const DEFAULT_HISTORY_LIMIT = 50;
|
|
65
|
+
export declare const DEFAULT_CHECKPOINT_MAX_BYTES: number;
|
|
66
|
+
export interface JobStateProvider {
|
|
67
|
+
readonly backend: 'file' | 'sqlite';
|
|
68
|
+
getState(jobId: string): Promise<JobState | null>;
|
|
69
|
+
putState(state: JobState): Promise<void>;
|
|
70
|
+
/** Add or replace a run in the job's history, keeping the newest `historyLimit`. */
|
|
71
|
+
recordRun(jobId: string, run: JobRunRecord): Promise<void>;
|
|
72
|
+
/** The job's runs, newest first. */
|
|
73
|
+
listRuns(jobId: string): Promise<JobRunRecord[]>;
|
|
74
|
+
/** Throws when the JSON is larger than `checkpointMaxBytes`. */
|
|
75
|
+
saveCheckpoint(jobId: string, runId: string, data: unknown): Promise<void>;
|
|
76
|
+
loadCheckpoint(jobId: string, runId: string): Promise<unknown>;
|
|
77
|
+
clearCheckpoint(jobId: string, runId: string): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Take the lock for one slot, or steal it when its holder let it expire.
|
|
80
|
+
* True for exactly one caller among any that contend.
|
|
81
|
+
*/
|
|
82
|
+
takeLock(jobId: string, slot: string, owner: string, ttlMs: number): Promise<boolean>;
|
|
83
|
+
/** Extend a lock this owner holds. False when it no longer holds it. */
|
|
84
|
+
renewLock(jobId: string, slot: string, owner: string, ttlMs: number): Promise<boolean>;
|
|
85
|
+
/** Give up a lock this owner holds; a lock held by another owner is left alone. */
|
|
86
|
+
releaseLock(jobId: string, slot: string, owner: string): Promise<void>;
|
|
87
|
+
close?(): void;
|
|
88
|
+
}
|
|
89
|
+
export declare function assertJobId(jobId: string): void;
|
|
90
|
+
/** A slot as a compact UTC stamp, safe in a file name: `20261008T060000Z`. */
|
|
91
|
+
export declare function slotKey(slot: string): string;
|
|
92
|
+
/** The JSON a checkpoint is stored as, refused when larger than the cap. */
|
|
93
|
+
export declare function checkpointJson(data: unknown, maxBytes: number): string;
|
|
94
|
+
/**
|
|
95
|
+
* Which backend `ngdpbase.jobs.state.provider` names. `auto` (the default)
|
|
96
|
+
* picks `sqlite` when the application database is open. `sqlite` with no
|
|
97
|
+
* database open is an error naming the key to set.
|
|
98
|
+
*/
|
|
99
|
+
export declare function selectJobStateBackend(configured: unknown, databaseEnabled: boolean): 'file' | 'sqlite';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lunr-style query strings, read as MiniSearch query trees (#1736).
|
|
3
|
+
*
|
|
4
|
+
* The search provider moved from Lunr to MiniSearch, but its callers still
|
|
5
|
+
* speak Lunr's query language: the field-scoped search builds `+title:word`,
|
|
6
|
+
* type-ahead appends `*` to the last term (`applyPrefixToLastTerm`), and a
|
|
7
|
+
* person may type any of it into the search box. This keeps that language,
|
|
8
|
+
* with the same meaning:
|
|
9
|
+
*
|
|
10
|
+
* word an optional term; with no required terms, any one matches
|
|
11
|
+
* +word required: every result contains it
|
|
12
|
+
* -word excluded: no result contains it
|
|
13
|
+
* field:word only that field (an unknown field is read as plain text, so
|
|
14
|
+
* a typed URL such as `https://x` is a search, not an error)
|
|
15
|
+
* word* prefix match
|
|
16
|
+
* word~1 fuzzy match, up to that edit distance
|
|
17
|
+
*
|
|
18
|
+
* A term's `^boost` is accepted and ignored. When required terms are present,
|
|
19
|
+
* optional terms no longer narrow the results (as in Lunr); they are not used
|
|
20
|
+
* for ranking either.
|
|
21
|
+
*
|
|
22
|
+
* @module providers/lunrQueryToMiniSearch
|
|
23
|
+
*/
|
|
24
|
+
import { type Query } from 'minisearch';
|
|
25
|
+
/**
|
|
26
|
+
* The MiniSearch query for a Lunr-style string, or null when the string holds
|
|
27
|
+
* nothing to search for.
|
|
28
|
+
*
|
|
29
|
+
* @param query - the query as a caller or a person wrote it
|
|
30
|
+
* @param fields - the indexed field names; a `field:` prefix naming another is plain text
|
|
31
|
+
*/
|
|
32
|
+
export declare function lunrQueryToMiniSearch(query: string, fields: readonly string[]): Query | null;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conservative filename → capture-date parser (#809, slice C of #807).
|
|
3
|
+
*
|
|
4
|
+
* Last-resort fallback used by media providers when a file carries no usable
|
|
5
|
+
* EXIF/QuickTime capture date. Many devices encode the capture time in the
|
|
6
|
+
* filename (e.g. `PXL_20260113_123414708.jpg`, `2026-04-03-IMG_4654.jpg`,
|
|
7
|
+
* `Feb_20_2026_19_25_04.jpg`); without this, those files index with
|
|
8
|
+
* `dateTimeOriginal: null` and sort only by file `mtime`.
|
|
9
|
+
*
|
|
10
|
+
* Design constraints (from the issue):
|
|
11
|
+
* - **Conservative** — only a small set of high-confidence, anchored patterns
|
|
12
|
+
* are accepted. Anything ambiguous returns `null`, and the caller then
|
|
13
|
+
* falls back to `mtime` and surfaces the file to admins.
|
|
14
|
+
* - **Distinguishable provenance** — the caller records that the resulting
|
|
15
|
+
* date came from the filename (`captureDateSource: 'filename'`), so a
|
|
16
|
+
* parsed date never masquerades as authoritative EXIF metadata.
|
|
17
|
+
*
|
|
18
|
+
* Returns a `"YYYY-MM-DD HH:MM:SS"` string (the exact shape produced by the
|
|
19
|
+
* EXIF extractor, so it flows through sort/filter identically), or `null`.
|
|
20
|
+
* A date-only match yields a `00:00:00` time.
|
|
21
|
+
*/
|
|
22
|
+
export declare function parseDateFromFilename(filename: string): string | null;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type DatabaseConstructor from 'better-sqlite3-multiple-ciphers';
|
|
2
|
+
/**
|
|
3
|
+
* The SQLite driver, handed in rather than imported: the worker loads it from
|
|
4
|
+
* the file the site's own thread resolved (`job.driver`), so both threads use
|
|
5
|
+
* the same native module, and a worker run from source (tsx) is not sent to
|
|
6
|
+
* the type declarations tsconfig's `paths` maps the package name to.
|
|
7
|
+
*/
|
|
8
|
+
export type Driver = typeof DatabaseConstructor;
|
|
9
|
+
/** One database to copy into a backup: where it is, the key it opens under ('' = plaintext), and the backup file to write. */
|
|
10
|
+
export interface DatabaseExport {
|
|
11
|
+
name: string;
|
|
12
|
+
source: string;
|
|
13
|
+
sourceKey: string;
|
|
14
|
+
target: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ExportOutcome {
|
|
17
|
+
written: Array<{
|
|
18
|
+
name: string;
|
|
19
|
+
target: string;
|
|
20
|
+
sizeBytes: number;
|
|
21
|
+
tables: number;
|
|
22
|
+
}>;
|
|
23
|
+
/** Databases that could not be copied; the others still are. Each is named, never dropped silently. */
|
|
24
|
+
failed: Array<{
|
|
25
|
+
name: string;
|
|
26
|
+
error: string;
|
|
27
|
+
}>;
|
|
28
|
+
}
|
|
29
|
+
/** One database to stage from a backup: the backup's file, and the live file it will replace at the next start. */
|
|
30
|
+
export interface DatabaseStage {
|
|
31
|
+
name: string;
|
|
32
|
+
backupFile: string;
|
|
33
|
+
live: string;
|
|
34
|
+
targetKey: string;
|
|
35
|
+
}
|
|
36
|
+
export interface StageOutcome {
|
|
37
|
+
staged: Array<{
|
|
38
|
+
name: string;
|
|
39
|
+
staged: string;
|
|
40
|
+
live: string;
|
|
41
|
+
tables: number;
|
|
42
|
+
}>;
|
|
43
|
+
}
|
|
44
|
+
export type SqliteBackupJob = {
|
|
45
|
+
kind: 'export';
|
|
46
|
+
exports: DatabaseExport[];
|
|
47
|
+
backupKey: string;
|
|
48
|
+
} | {
|
|
49
|
+
kind: 'stage';
|
|
50
|
+
stages: DatabaseStage[];
|
|
51
|
+
backupKey: string;
|
|
52
|
+
};
|
|
53
|
+
/** A job as the worker receives it: with the driver's resolved file. */
|
|
54
|
+
export type WorkerJob = SqliteBackupJob & {
|
|
55
|
+
driver: string;
|
|
56
|
+
};
|
|
57
|
+
/** The staged file for a live database: beside it, so staging and applying name the same path. */
|
|
58
|
+
export declare const stagedPath: (live: string) => string;
|
|
59
|
+
/**
|
|
60
|
+
* Write an encrypted copy of each database under `backupKey`. A database that
|
|
61
|
+
* cannot be opened or copied is named in `failed`, its partial file removed;
|
|
62
|
+
* the others are still written. A target that already exists is never
|
|
63
|
+
* overwritten.
|
|
64
|
+
*/
|
|
65
|
+
export declare function exportDatabasesSync(Database: Driver, exports: DatabaseExport[], backupKey: string): ExportOutcome;
|
|
66
|
+
/**
|
|
67
|
+
* Stage a restore: each backup file is opened under the backup key,
|
|
68
|
+
* integrity-checked, and copied into `<live>.staged` under the target
|
|
69
|
+
* database's key, which is then opened and checked too. All or nothing: if
|
|
70
|
+
* any database fails, every staged file is removed and the error names it.
|
|
71
|
+
* Live files are never touched.
|
|
72
|
+
*/
|
|
73
|
+
export declare function stageDatabasesSync(Database: Driver, stages: DatabaseStage[], backupKey: string): StageOutcome;
|
|
74
|
+
/** Run a job of this module on a worker thread, so a large database never stalls requests or the liveness probe. */
|
|
75
|
+
export declare function runOffThread(job: {
|
|
76
|
+
kind: 'export';
|
|
77
|
+
exports: DatabaseExport[];
|
|
78
|
+
backupKey: string;
|
|
79
|
+
}, timeoutMs: number): Promise<ExportOutcome>;
|
|
80
|
+
export declare function runOffThread(job: {
|
|
81
|
+
kind: 'stage';
|
|
82
|
+
stages: DatabaseStage[];
|
|
83
|
+
backupKey: string;
|
|
84
|
+
}, timeoutMs: number): Promise<StageOutcome>;
|
|
85
|
+
/** What a staged restore is: written last, once every database is staged; its presence is what the next start applies. */
|
|
86
|
+
export interface StagedRestoreManifest {
|
|
87
|
+
version: 1;
|
|
88
|
+
stagedAt: string;
|
|
89
|
+
/** When the backup it came from was taken. */
|
|
90
|
+
backup: string;
|
|
91
|
+
/** The backup document's filename. */
|
|
92
|
+
source: string;
|
|
93
|
+
/** Who staged it: the account named by the request's context. */
|
|
94
|
+
stagedBy: string;
|
|
95
|
+
/** The backup of the live data taken just before staging (D6): what to restore to undo this one. */
|
|
96
|
+
safetyBackup?: string;
|
|
97
|
+
databases: Array<{
|
|
98
|
+
name: string;
|
|
99
|
+
live: string;
|
|
100
|
+
staged: string;
|
|
101
|
+
}>;
|
|
102
|
+
}
|
|
103
|
+
/** Where the manifest of a staged restore lives: beside the application database. */
|
|
104
|
+
export declare const manifestPath: (applicationFile: string) => string;
|
|
105
|
+
export declare function writeManifest(file: string, manifest: StagedRestoreManifest): void;
|
|
106
|
+
export interface ApplyOutcome {
|
|
107
|
+
/** Databases now on the restored copy, each with where its previous file was kept. */
|
|
108
|
+
applied: Array<{
|
|
109
|
+
name: string;
|
|
110
|
+
live: string;
|
|
111
|
+
kept: string;
|
|
112
|
+
}>;
|
|
113
|
+
/** Why nothing was applied; the staged files were set aside as `*.incomplete`. */
|
|
114
|
+
refused?: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Apply a staged restore at start, before any database opens. Each live file,
|
|
118
|
+
* with its `-wal` and `-shm`, steps aside as `*.pre-restore` (`-wal`/`-shm`
|
|
119
|
+
* beside it, so the kept copy still opens as it was), and the staged file
|
|
120
|
+
* takes its name. A rename, never a write into a live database.
|
|
121
|
+
*
|
|
122
|
+
* All or nothing: if any database the manifest names is not staged, nothing
|
|
123
|
+
* is applied; what is staged is renamed `*.incomplete`, so it is neither
|
|
124
|
+
* applied nor retried. A staged file with no manifest (staging was
|
|
125
|
+
* interrupted) is set aside the same way. `allowed` says which live paths may
|
|
126
|
+
* be replaced, so a tampered manifest cannot rename an arbitrary file.
|
|
127
|
+
*/
|
|
128
|
+
export declare function applyStagedRestore(applicationFile: string, allowed: (live: string) => boolean): ApplyOutcome | null;
|