@wasm-oj/core 0.2.0 → 0.2.1
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/dist/index.d.ts +33 -147
- package/dist/index.js +253 -416
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -28,7 +28,6 @@ declare const WASM_OJ_SCHEMAS: Readonly<{
|
|
|
28
28
|
readonly objectCache: "wasm-oj-v2/object-cache";
|
|
29
29
|
readonly pythonToolchain: "wasm-oj-v2/python-toolchain";
|
|
30
30
|
readonly replayBundle: "wasm-oj-v2/replay-bundle";
|
|
31
|
-
readonly releaseManifest: "wasm-oj-v2/release-manifest";
|
|
32
31
|
readonly rustToolchain: "wasm-oj-v2/rust-toolchain";
|
|
33
32
|
readonly runRequest: "wasm-oj-v2/run-request";
|
|
34
33
|
readonly runtimeBundle: "wasm-oj-v2/runtime-bundle";
|
|
@@ -351,8 +350,8 @@ declare function isCostProfileFor(profile: string, language: Language, target: T
|
|
|
351
350
|
|
|
352
351
|
/** Executable runtime components covered by deterministic cost calibration. */
|
|
353
352
|
declare const WASM_OJ_RUNTIME_COMPONENTS: Readonly<{
|
|
354
|
-
readonly runtimeCoreWasmSha256: "
|
|
355
|
-
readonly runtimeSourceRootSha256: "
|
|
353
|
+
readonly runtimeCoreWasmSha256: "e4c7fca566ff5ba66931e0cf11cacbf37610d35c36d5f3ee97d719468a2f6466";
|
|
354
|
+
readonly runtimeSourceRootSha256: "0140ecc6ed5060eae465e73db6822bcde32295734517de84929a537e3c45e663";
|
|
356
355
|
readonly wasmerNativeVersion: "7.2.1";
|
|
357
356
|
readonly wasmerSdkVersion: "0.10.0";
|
|
358
357
|
readonly wasmerSdkWasmSha256: "49a6646209f5ab5e7c737eac33407d87d9a9959ac83e5ecaaab9261b2323589e";
|
|
@@ -363,94 +362,11 @@ declare const WASM_OJ_RUNTIME_COMPONENTS: Readonly<{
|
|
|
363
362
|
* Release verification independently checks the component bytes before this
|
|
364
363
|
* identity is admitted into a calibrated release.
|
|
365
364
|
*/
|
|
366
|
-
declare const WASM_OJ_RUNTIME_IDENTITY_SHA256 = "
|
|
365
|
+
declare const WASM_OJ_RUNTIME_IDENTITY_SHA256 = "59414bf4fa5191d0942c0e190c69d32f3a2251461b8eb41aaba32598baab1d5f";
|
|
367
366
|
/** Exact canonical serialization hashed by `WASM_OJ_RUNTIME_IDENTITY_SHA256`. */
|
|
368
367
|
declare function runtimeIdentityBytes(): Uint8Array;
|
|
369
368
|
declare function verifyRuntimeIdentity(): Promise<void>;
|
|
370
369
|
|
|
371
|
-
declare const WASM_OJ_RELEASE_MANIFEST_SCHEMA: "wasm-oj-v2/release-manifest";
|
|
372
|
-
declare const WASM_OJ_CONTAINER_PROTOCOL_VERSION = "wasm-oj-container-v2";
|
|
373
|
-
interface ReleaseManifest {
|
|
374
|
-
readonly schema: typeof WASM_OJ_RELEASE_MANIFEST_SCHEMA;
|
|
375
|
-
readonly releaseId: string;
|
|
376
|
-
readonly version: string;
|
|
377
|
-
readonly wasmOjContract: typeof WASM_OJ_CONTRACT_VERSION;
|
|
378
|
-
readonly createdAt: string;
|
|
379
|
-
readonly source: {
|
|
380
|
-
readonly repository: string;
|
|
381
|
-
readonly commit: string;
|
|
382
|
-
readonly sourceTreeSha256: string;
|
|
383
|
-
readonly tag?: string;
|
|
384
|
-
};
|
|
385
|
-
readonly build: {
|
|
386
|
-
readonly nodeVersion: string;
|
|
387
|
-
readonly pnpmVersion: string;
|
|
388
|
-
readonly rustVersion: string;
|
|
389
|
-
readonly lockSha256: string;
|
|
390
|
-
readonly sbomSha256: string;
|
|
391
|
-
readonly licensesSha256: string;
|
|
392
|
-
readonly auditSha256: string;
|
|
393
|
-
};
|
|
394
|
-
readonly artifacts: {
|
|
395
|
-
readonly npmPackage: ArtifactDigest;
|
|
396
|
-
readonly workerBundle: ArtifactDigest;
|
|
397
|
-
readonly staticAssets: ArtifactDigest;
|
|
398
|
-
readonly containerImage: {
|
|
399
|
-
readonly registry: string;
|
|
400
|
-
readonly digest: string;
|
|
401
|
-
readonly identitySha256: string;
|
|
402
|
-
readonly platform: "linux/amd64";
|
|
403
|
-
readonly dockerfileSha256: string;
|
|
404
|
-
readonly baseImages: readonly {
|
|
405
|
-
readonly stage: "node-build" | "rust-build" | "judge";
|
|
406
|
-
readonly image: string;
|
|
407
|
-
readonly digest: string;
|
|
408
|
-
}[];
|
|
409
|
-
};
|
|
410
|
-
};
|
|
411
|
-
readonly runtime: {
|
|
412
|
-
readonly protocolVersion: typeof WASM_OJ_CONTAINER_PROTOCOL_VERSION;
|
|
413
|
-
readonly executionRootSha256: string;
|
|
414
|
-
readonly rootSha256: string;
|
|
415
|
-
readonly runtimeIdentitySha256: string;
|
|
416
|
-
readonly runtimeCoreSha256: string;
|
|
417
|
-
readonly wasmerVersion: string;
|
|
418
|
-
readonly wasmerSha256: string;
|
|
419
|
-
readonly compilerSha256: string;
|
|
420
|
-
readonly runnerSha256: string;
|
|
421
|
-
};
|
|
422
|
-
readonly toolchains: {
|
|
423
|
-
readonly rootSha256: string;
|
|
424
|
-
readonly manifestSha256: string;
|
|
425
|
-
};
|
|
426
|
-
readonly cost: {
|
|
427
|
-
readonly model: typeof WEIGHTED_METER_MODEL;
|
|
428
|
-
readonly profileRootSha256: string;
|
|
429
|
-
readonly baselineSha256: string;
|
|
430
|
-
};
|
|
431
|
-
readonly evidence: {
|
|
432
|
-
readonly conformanceSha256: string;
|
|
433
|
-
readonly testsSha256: string;
|
|
434
|
-
readonly costCalibrationSha256: string;
|
|
435
|
-
};
|
|
436
|
-
readonly migrations: {
|
|
437
|
-
readonly databaseSha256: string;
|
|
438
|
-
};
|
|
439
|
-
readonly provenance: {
|
|
440
|
-
readonly issuer: string;
|
|
441
|
-
readonly subject: string;
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
interface ArtifactDigest {
|
|
445
|
-
readonly sha256: string;
|
|
446
|
-
readonly bytes: number;
|
|
447
|
-
}
|
|
448
|
-
declare function parseReleaseManifest(value: unknown): ReleaseManifest;
|
|
449
|
-
declare function createReleaseManifest(value: ReleaseManifest): ReleaseManifest;
|
|
450
|
-
declare function releaseManifestBytes(value: ReleaseManifest): Uint8Array;
|
|
451
|
-
declare function releaseManifestSha256(value: ReleaseManifest): Promise<string>;
|
|
452
|
-
declare function verifyReleaseManifestBytes(bytes: Uint8Array, expectedSha256?: string): Promise<ReleaseManifest>;
|
|
453
|
-
|
|
454
370
|
/**
|
|
455
371
|
* Fail-closed validation boundary for projects crossing persistence or
|
|
456
372
|
* transport boundaries. The candidate is checked without mutation, defaults,
|
|
@@ -1640,58 +1556,28 @@ declare function scoreProblemResults(problem: JudgeProblem, language: BuiltinLan
|
|
|
1640
1556
|
/** Score immutable execution-only judge data without reconstructing a public problem bundle. */
|
|
1641
1557
|
declare function scoreJudgeDataResults(data: JudgeData, language: BuiltinLanguage$1, results: readonly JudgeCaseResult[]): ProblemScore;
|
|
1642
1558
|
|
|
1643
|
-
interface JudgeAllowedProfile {
|
|
1644
|
-
readonly target: "wasip1" | "wasix";
|
|
1645
|
-
readonly optimization: "debug" | "release";
|
|
1646
|
-
}
|
|
1647
|
-
type JudgeAllowedProfiles = Readonly<Partial<Record<BuiltinLanguage, JudgeAllowedProfile>>>;
|
|
1648
|
-
declare function parseJudgeAllowedProfiles(value: unknown, label?: string): JudgeAllowedProfiles;
|
|
1649
|
-
|
|
1650
|
-
declare const MANAGED_COLLECTION_SCHEMA = "wasm-oj-platform/managed-collection/v2";
|
|
1651
|
-
interface ManagedRepositoryObject {
|
|
1652
|
-
/** Normalized path relative to the directory containing collection/index.json. */
|
|
1653
|
-
readonly repositoryPath: string;
|
|
1654
|
-
readonly bytes: number;
|
|
1655
|
-
readonly sha256: string;
|
|
1656
|
-
}
|
|
1657
|
-
interface ManagedProblemPublication {
|
|
1658
|
-
readonly slug: string;
|
|
1659
|
-
readonly allowedProfiles: JudgeAllowedProfiles;
|
|
1660
|
-
readonly contestPublic: ManagedRepositoryObject;
|
|
1661
|
-
readonly judgePackage: ManagedRepositoryObject;
|
|
1662
|
-
}
|
|
1663
|
-
interface ManagedCollectionV2 {
|
|
1664
|
-
readonly schema: typeof MANAGED_COLLECTION_SCHEMA;
|
|
1665
|
-
readonly collectionRevision: string;
|
|
1666
|
-
readonly problems: readonly ManagedProblemPublication[];
|
|
1667
|
-
}
|
|
1668
|
-
/** Parse the value form used by the authoring CLI after JSON decoding. */
|
|
1669
|
-
declare function parseManagedCollectionValueV2(value: unknown): ManagedCollectionV2;
|
|
1670
|
-
/**
|
|
1671
|
-
* Stable platform boundary for generated collection/managed.json bytes.
|
|
1672
|
-
* Published managed contracts must use WASM-OJ canonical JSON; author-only
|
|
1673
|
-
* managed-source documents are intentionally not accepted here.
|
|
1674
|
-
*/
|
|
1675
|
-
declare function parseManagedCollectionV2(bytes: Uint8Array): ManagedCollectionV2;
|
|
1676
|
-
/** Same v2-only value parser retained as the environment-neutral library entry point. */
|
|
1677
|
-
declare const parseManagedCollectionContract: typeof parseManagedCollectionValueV2;
|
|
1678
|
-
|
|
1679
1559
|
declare const CONTEST_PUBLIC_PROJECTION_SCHEMA = "wasm-oj-platform/contest-public-problem-projection/v1";
|
|
1680
1560
|
interface ContestPublicProjection {
|
|
1681
1561
|
readonly schema: typeof CONTEST_PUBLIC_PROJECTION_SCHEMA;
|
|
1682
1562
|
readonly problem: JudgeProblem;
|
|
1683
|
-
readonly digest: string;
|
|
1684
1563
|
}
|
|
1685
1564
|
/**
|
|
1686
|
-
* The
|
|
1687
|
-
*
|
|
1688
|
-
*
|
|
1565
|
+
* The repository practice bundle is safe to fetch for every practice visitor.
|
|
1566
|
+
* Hidden cases and their expected answers exist only in the immutable judge
|
|
1567
|
+
* package built from the authoring source.
|
|
1689
1568
|
*/
|
|
1690
1569
|
declare function derivePracticePublic(authored: JudgeProblem): JudgeProblem;
|
|
1691
1570
|
/** The single deterministic hidden-data redaction used by author CI and platform validation. */
|
|
1692
1571
|
declare function deriveContestPublic(practice: JudgeProblem): JudgeProblem;
|
|
1693
|
-
declare function createContestPublicProjection(practice: JudgeProblem
|
|
1694
|
-
declare function contestPublicProjectionBytes(practice: JudgeProblem
|
|
1572
|
+
declare function createContestPublicProjection(practice: JudgeProblem): ContestPublicProjection;
|
|
1573
|
+
declare function contestPublicProjectionBytes(practice: JudgeProblem): Uint8Array;
|
|
1574
|
+
|
|
1575
|
+
interface JudgeAllowedProfile {
|
|
1576
|
+
readonly target: "wasip1" | "wasix";
|
|
1577
|
+
readonly optimization: "debug" | "release";
|
|
1578
|
+
}
|
|
1579
|
+
type JudgeAllowedProfiles = Readonly<Partial<Record<BuiltinLanguage, JudgeAllowedProfile>>>;
|
|
1580
|
+
declare function parseJudgeAllowedProfiles(value: unknown, label?: string): JudgeAllowedProfiles;
|
|
1695
1581
|
|
|
1696
1582
|
declare const WASM_OJ_JUDGE_PACKAGE_SCHEMA = "wasm-oj-v2/judge-package";
|
|
1697
1583
|
declare const WASM_OJ_JUDGE_PACKAGE_MAGIC = "WOJJDG02";
|
|
@@ -1808,43 +1694,43 @@ declare function decodeJudgePackageForExecution(bytes: Uint8Array): Promise<Deco
|
|
|
1808
1694
|
/** Execution identity is the digest of the exact canonical WOJJDG02 bytes. */
|
|
1809
1695
|
declare function judgePackageSemanticDigest(bytes: Uint8Array): Promise<string>;
|
|
1810
1696
|
|
|
1811
|
-
declare const
|
|
1812
|
-
interface
|
|
1697
|
+
declare const REPOSITORY_AUTHORING_JUDGES_SCHEMA = "wasm-oj-platform/repository-authoring-judges/v1";
|
|
1698
|
+
interface RepositorySourceObject {
|
|
1813
1699
|
readonly path: string;
|
|
1814
1700
|
readonly bytes: number;
|
|
1815
1701
|
readonly sha256: string;
|
|
1816
1702
|
}
|
|
1817
|
-
interface
|
|
1703
|
+
interface RepositorySourceArtifact extends RepositorySourceObject {
|
|
1818
1704
|
readonly runtimeProfile: TrustedJudgeRuntimeProfile;
|
|
1819
1705
|
}
|
|
1820
|
-
interface
|
|
1706
|
+
interface RepositorySourceAsset extends RepositorySourceObject {
|
|
1821
1707
|
readonly guestPath: string;
|
|
1822
1708
|
}
|
|
1823
|
-
type
|
|
1709
|
+
type RepositorySourceJudge = {
|
|
1824
1710
|
readonly kind: "text";
|
|
1825
1711
|
} | {
|
|
1826
1712
|
readonly kind: "checker";
|
|
1827
|
-
readonly artifact:
|
|
1828
|
-
readonly assets: readonly
|
|
1713
|
+
readonly artifact: RepositorySourceArtifact;
|
|
1714
|
+
readonly assets: readonly RepositorySourceAsset[];
|
|
1829
1715
|
readonly args: readonly string[];
|
|
1830
1716
|
} | {
|
|
1831
1717
|
readonly kind: "interactive";
|
|
1832
|
-
readonly artifact:
|
|
1833
|
-
readonly assets: readonly
|
|
1718
|
+
readonly artifact: RepositorySourceArtifact;
|
|
1719
|
+
readonly assets: readonly RepositorySourceAsset[];
|
|
1834
1720
|
readonly args: readonly string[];
|
|
1835
1721
|
readonly inputPath: string;
|
|
1836
1722
|
};
|
|
1837
|
-
interface
|
|
1723
|
+
interface RepositoryAuthoringJudgeProblem {
|
|
1838
1724
|
readonly slug: string;
|
|
1839
1725
|
readonly allowedProfiles: JudgeAllowedProfiles;
|
|
1840
|
-
readonly judge:
|
|
1726
|
+
readonly judge: RepositorySourceJudge;
|
|
1841
1727
|
}
|
|
1842
|
-
interface
|
|
1843
|
-
readonly schema: typeof
|
|
1844
|
-
readonly problems: readonly
|
|
1728
|
+
interface RepositoryAuthoringJudges {
|
|
1729
|
+
readonly schema: typeof REPOSITORY_AUTHORING_JUDGES_SCHEMA;
|
|
1730
|
+
readonly problems: readonly RepositoryAuthoringJudgeProblem[];
|
|
1845
1731
|
}
|
|
1846
|
-
/** Author-only
|
|
1847
|
-
declare function
|
|
1732
|
+
/** Author-only input used by collection build; never accepted by the platform sync boundary. */
|
|
1733
|
+
declare function parseRepositoryAuthoringJudges(value: unknown): RepositoryAuthoringJudges;
|
|
1848
1734
|
|
|
1849
1735
|
/** Build the runtime judge spec directly from verified WOJJDG02 execution data. */
|
|
1850
1736
|
declare function trustedJudgeSpec(data: JudgeData, executable: TrustedJudgeExecutable): JudgeSpec;
|
|
@@ -1879,5 +1765,5 @@ declare const DEFAULT_CONFORMANCE_CASES: readonly ConformanceCase[];
|
|
|
1879
1765
|
declare const CPP_STDLIB_CONFORMANCE_CASE: ConformanceCase;
|
|
1880
1766
|
declare const FULL_CONFORMANCE_CASES: readonly ConformanceCase[];
|
|
1881
1767
|
|
|
1882
|
-
export { BROWSER_COLLECTION_SCHEMA, BROWSER_PROBLEM_SCHEMA, BrowserDependencyNetworkConsent, CONTEST_PUBLIC_PROJECTION_SCHEMA, CPP_STDLIB_CONFORMANCE_CASE, CargoLockDependencyResolver, CompilerRegistry, CostBaselineRegistry, CppLockDependencyResolver, DEFAULT_CONFORMANCE_CASES, DEFAULT_DETERMINISM, DEFAULT_RESOURCE_POLICY, DEPENDENCY_BUILD_LIMITS, DependencyManager, DependencyNetworkError, Engine, FULL_CONFORMANCE_CASES, GoLockDependencyResolver, JudgeEngine,
|
|
1883
|
-
export type { ArtifactBuildExpectation,
|
|
1768
|
+
export { BROWSER_COLLECTION_SCHEMA, BROWSER_PROBLEM_SCHEMA, BrowserDependencyNetworkConsent, CONTEST_PUBLIC_PROJECTION_SCHEMA, CPP_STDLIB_CONFORMANCE_CASE, CargoLockDependencyResolver, CompilerRegistry, CostBaselineRegistry, CppLockDependencyResolver, DEFAULT_CONFORMANCE_CASES, DEFAULT_DETERMINISM, DEFAULT_RESOURCE_POLICY, DEPENDENCY_BUILD_LIMITS, DependencyManager, DependencyNetworkError, Engine, FULL_CONFORMANCE_CASES, GoLockDependencyResolver, JudgeEngine, MemoryDependencyCache, NpmLockDependencyResolver, PROBLEM_STARTER_LIMITS, PROJECT_SOURCE_LIMITS, PyPiLockDependencyResolver, REPOSITORY_AUTHORING_JUDGES_SCHEMA, RuntimeDriverRegistry, TRUSTED_JUDGE_RUNTIME_PROFILES, TRUSTED_JUDGE_WASIP1_IMPORTS, TRUSTED_JUDGE_WASM_MAX_BYTES, WASM_OJ_JUDGE_DATA_SCHEMA, WASM_OJ_JUDGE_PACKAGE_MAGIC, WASM_OJ_JUDGE_PACKAGE_MAX_BYTES, WASM_OJ_JUDGE_PACKAGE_SCHEMA, WASM_OJ_LIBCXX_PCH_HEADER, WASM_OJ_RUNTIME_COMPONENTS, WASM_OJ_RUNTIME_IDENTITY_SHA256, WEIGHTED_METER_MODEL, assertCompilerCacheKey, assertJudgeDataCostProfile, assertJudgeDataMatchesPracticePublic, assertJudgeGuestFilePath, assertProblemCostProfile, assertValidBuildArtifact, assertValidDependencyBuildBundle, assertValidDependencyLock, assertValidProject, assertValidReplayBundle, browserToolchainAssetBaseUrl, browserToolchainAssetUrl, canonicalJsonBytes, compareConformanceSnapshots, contestPublicProjectionBytes, costProfileId, createContestPublicProjection, createDefaultCostBaselineRegistry, createDefaultDependencyBuildAdapters, createDefaultDependencyManager, createDefaultDependencyResolvers, createDefaultRuntimeDrivers, createDependencyBuildBundle, createDependencyLock, createEngine, createExtendedCostBaselineRegistry, createJudgeExecutor, createReplayBundle, createRuntimeBundleManifest, createSdkProject, decodeJudgePackageForExecution, decodeLibcxxPchManifest, decodeReplayBundle, dependencyFileTreeSha256, dependencyLockSha256, dependencyManifestSha256, deriveContestPublic, deriveJudgeData, derivePracticePublic, deterministicTranscript, encodeJudgePackage, encodeReplayBundle, fileMatcher, floatMatcher, goModuleZipHash, isCostProfileFor, isToolchainLibcxxPchHeader, judgePackageSemanticDigest, judgeTranscript, normalizeDependencyNetworkAccess, normalizeDependencyNetworkScope, normalizeExecutionMetrics, normalizeOutput, parseCanonicalJsonBytes, parseJudgeAllowedProfiles, parseJudgeData, parseJudgePackageManifest, parseProblemBundle, parseProblemCollectionIndex, parseRepositoryAuthoringJudges, parseStandaloneProblemBundle, prepareArtifactInteraction, prepareArtifactRun, prepareTrustedJudgeRun, problemCollectionRevision, readJudgePackageManifest, replayBundle, replayBundleSha256, resolveArtifactCostBudget, resolveCostBudget, resolveDeterminism, resolveResourcePolicy, runConformanceHost, runConformanceMatrix, runtimeIdentityBytes, scoreJudgeDataResults, scoreProblemResults, setMatcher, sha256Matcher, snapshotBrowserToolchainSources, summarizeProblemPolicies, textMatcher, tokenMatcher, toolchainAssetSource, toolchainCacheIdentity, toolchainProfileSource, trustedJudgeSpec, unavailableExecutionMetrics, validateBrowserToolchainSources, validateJudgePackage, validateJudgeSpec, validateServerToolchainSources, validateToolchainDescriptors, validateTrustedJudgeWasm, verifyDependencyBuildBundle, verifyProblemBundleBytes, verifyProblemCollectionRevision, verifyRuntimeIdentity, wasmCheckerMatcher };
|
|
1769
|
+
export type { ArtifactBuildExpectation, ArtifactStore, BatchJudgeCaseSpec, CanonicalJsonValue, CompileInput, CompileOptions, Compiler, CompilerRegistration, ConformanceCase, ConformanceHost, ConformanceMismatch, ConformanceOptions, ConformanceReport, ConformanceRunExpectation, ConformanceSample, ConformanceSnapshot, ContestPublicProjection, CostBudget, CppDependencyLockSource, DecodedJudgePackageForExecution, DependencyBuildAdapter, DependencyBuildBundle, DependencyCache, DependencyConsentStorage, DependencyEcosystem, DependencyFetch, DependencyLock, DependencyManifest, DependencyNetworkAccess, DependencyNetworkAuthorizer, DependencyNetworkConsentPrompt, DependencyNetworkScope, DependencyOfflineBundle, DependencyRequirement, DependencyResolutionContext, DependencyResolver, DependencyResolverOptions, DependencySourceFile, DeterministicTranscript, EncodedJudgePackage, EngineOptions, ExecuteResult, InteractiveExecuteResult, InteractiveJudgeCaseSpec, InteractiveOptions, InteractiveProgramOptions, JudgeAllowedProfile, JudgeAllowedProfiles, JudgeCaseResult, JudgeCaseSpec, JudgeCaseVerdict, JudgeData, JudgeDataCase, JudgeEngineOptions, JudgeExecutionAdapter, JudgeExecutor, JudgeFileInputSpec, JudgeInputProvider, JudgeInputSpec, JudgeMatchResult, JudgeMatcher, JudgeMatcherContext, JudgeMatcherSpec, JudgePackageAllowedProfile, JudgePackageAssetInput, JudgePackageAssetReference, JudgePackageBlobReference, JudgePackageByteSource, JudgePackageInput, JudgePackageInputJudge, JudgePackageManifest, JudgePackageManifestJudge, JudgePolicy, JudgeProblem, JudgeProgramSpec, JudgeProjectResult, JudgeResolvedInput, JudgeResult, JudgeRunOptions, JudgeSpec, JudgeStarterTemplate, JudgeStarterTemplates, LibcxxPchAsset, LibcxxPchManifest, LibcxxPchProfile, LockedDependencyPackage, MaterializedDependencyPackage, Operation, OperationEvent, OperationEventPayload, OperationKind, OperationState, OutputNormalization, PackageFileSystemRequest, PolicyPerformanceAggregate, PrecompileOutcome, PrecompileStatus, PreparedRunRequest, ProblemBundleDescriptor, ProblemCollectionEntry, ProblemCollectionIndex, ProblemScore, RawExecutionMetrics, ReplayBundle, ReplayBundleInput, ReplayDecodeOptions, ReplayHost, ReplayJudgeCaseTranscript, ReplayJudgeOperation, ReplayJudgeTranscript, ReplayOperation, ReplayOptions, ReplayResult, ReplayRunOperation, RepositoryAuthoringJudgeProblem, RepositoryAuthoringJudges, RepositorySourceArtifact, RepositorySourceAsset, RepositorySourceJudge, RepositorySourceObject, ResolveDependencyOptions, ResolvedDependencyGraph, RunOptions, Runner, RuntimeDriver, RuntimeResolver, ScoredProblemCase, SubmissionOperation, SubmissionPolicySummary, SubmissionRequest, TrustedJudgeAsset, TrustedJudgeExecutable, TrustedJudgeProgram, TrustedJudgeRuntimeProfile, TrustedJudgeWasmInfo, TrustedJudgeWasmValidationOptions, ValidateJudgePackageOptions, ValidatedJudgePackage };
|
package/dist/index.js
CHANGED
|
@@ -351,8 +351,8 @@ async function sha256Hex$1(value) {
|
|
|
351
351
|
//#region src/core/runtime-identity.ts
|
|
352
352
|
/** Executable runtime components covered by deterministic cost calibration. */
|
|
353
353
|
var WASM_OJ_RUNTIME_COMPONENTS = Object.freeze({
|
|
354
|
-
runtimeCoreWasmSha256: "
|
|
355
|
-
runtimeSourceRootSha256: "
|
|
354
|
+
runtimeCoreWasmSha256: "e4c7fca566ff5ba66931e0cf11cacbf37610d35c36d5f3ee97d719468a2f6466",
|
|
355
|
+
runtimeSourceRootSha256: "0140ecc6ed5060eae465e73db6822bcde32295734517de84929a537e3c45e663",
|
|
356
356
|
wasmerNativeVersion: "7.2.1",
|
|
357
357
|
wasmerSdkVersion: "0.10.0",
|
|
358
358
|
wasmerSdkWasmSha256: "49a6646209f5ab5e7c737eac33407d87d9a9959ac83e5ecaaab9261b2323589e",
|
|
@@ -363,13 +363,13 @@ var WASM_OJ_RUNTIME_COMPONENTS = Object.freeze({
|
|
|
363
363
|
* Release verification independently checks the component bytes before this
|
|
364
364
|
* identity is admitted into a calibrated release.
|
|
365
365
|
*/
|
|
366
|
-
var WASM_OJ_RUNTIME_IDENTITY_SHA256 = "
|
|
366
|
+
var WASM_OJ_RUNTIME_IDENTITY_SHA256 = "59414bf4fa5191d0942c0e190c69d32f3a2251461b8eb41aaba32598baab1d5f";
|
|
367
367
|
/** Exact canonical serialization hashed by `WASM_OJ_RUNTIME_IDENTITY_SHA256`. */
|
|
368
368
|
function runtimeIdentityBytes() {
|
|
369
369
|
return canonicalJsonBytes(WASM_OJ_RUNTIME_COMPONENTS);
|
|
370
370
|
}
|
|
371
371
|
async function verifyRuntimeIdentity() {
|
|
372
|
-
if (await sha256Hex$1(runtimeIdentityBytes()) !== "
|
|
372
|
+
if (await sha256Hex$1(runtimeIdentityBytes()) !== "59414bf4fa5191d0942c0e190c69d32f3a2251461b8eb41aaba32598baab1d5f") throw new Error("WASM-OJ runtime identity declaration does not match its digest.");
|
|
373
373
|
}
|
|
374
374
|
//#endregion
|
|
375
375
|
//#region src/core/cost-profile.ts
|
|
@@ -511,249 +511,6 @@ function assertNonNegativeMetric(value, label) {
|
|
|
511
511
|
if (!Number.isSafeInteger(value) || value < 0) throw new RangeError(`${label} must be a non-negative safe integer.`);
|
|
512
512
|
}
|
|
513
513
|
//#endregion
|
|
514
|
-
//#region src/release-manifest.ts
|
|
515
|
-
var SHA256$6 = /^[0-9a-f]{64}$/;
|
|
516
|
-
var OCI_DIGEST = /^sha256:[0-9a-f]{64}$/;
|
|
517
|
-
var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
518
|
-
var SEMVER = /^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
519
|
-
var VERSION = /^[0-9A-Za-z][0-9A-Za-z._+-]{0,127}$/;
|
|
520
|
-
var IDENTITY = /^[A-Za-z0-9][A-Za-z0-9._:/@+-]{0,511}$/;
|
|
521
|
-
var WASM_OJ_RELEASE_MANIFEST_SCHEMA = WASM_OJ_SCHEMAS$1.releaseManifest;
|
|
522
|
-
var WASM_OJ_CONTAINER_PROTOCOL_VERSION = "wasm-oj-container-v2";
|
|
523
|
-
function record$5(value, label) {
|
|
524
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) throw new TypeError(`${label} must be an object.`);
|
|
525
|
-
return value;
|
|
526
|
-
}
|
|
527
|
-
function exact$4(value, required, optional, label) {
|
|
528
|
-
const allowed = /* @__PURE__ */ new Set([...required, ...optional]);
|
|
529
|
-
if (required.some((key) => !Object.hasOwn(value, key)) || Object.keys(value).some((key) => !allowed.has(key))) throw new TypeError(`${label} has an invalid shape.`);
|
|
530
|
-
}
|
|
531
|
-
function digest$1(value, label) {
|
|
532
|
-
if (typeof value !== "string" || !SHA256$6.test(value)) throw new TypeError(`${label} must be a lowercase SHA-256 digest.`);
|
|
533
|
-
return value;
|
|
534
|
-
}
|
|
535
|
-
function version(value, label) {
|
|
536
|
-
if (typeof value !== "string" || !VERSION.test(value)) throw new TypeError(`${label} is invalid.`);
|
|
537
|
-
return value;
|
|
538
|
-
}
|
|
539
|
-
function artifact(value, label) {
|
|
540
|
-
const item = record$5(value, label);
|
|
541
|
-
exact$4(item, ["bytes", "sha256"], [], label);
|
|
542
|
-
if (!Number.isSafeInteger(item.bytes) || item.bytes < 1) throw new TypeError(`${label}.bytes must be a positive safe integer.`);
|
|
543
|
-
return {
|
|
544
|
-
bytes: item.bytes,
|
|
545
|
-
sha256: digest$1(item.sha256, `${label}.sha256`)
|
|
546
|
-
};
|
|
547
|
-
}
|
|
548
|
-
function timestamp(value) {
|
|
549
|
-
if (typeof value !== "string" || new Date(value).toISOString() !== value) throw new TypeError("createdAt must be a canonical ISO timestamp.");
|
|
550
|
-
return value;
|
|
551
|
-
}
|
|
552
|
-
function sourceRepository(value) {
|
|
553
|
-
if (typeof value !== "string") throw new TypeError("source.repository must be a GitHub HTTPS URL.");
|
|
554
|
-
let url;
|
|
555
|
-
try {
|
|
556
|
-
url = new URL(value);
|
|
557
|
-
} catch (error) {
|
|
558
|
-
throw new TypeError("source.repository must be a GitHub HTTPS URL.", { cause: error });
|
|
559
|
-
}
|
|
560
|
-
if (url.protocol !== "https:" || url.hostname !== "github.com" || url.username || url.password || url.search || url.hash || url.pathname.split("/").filter(Boolean).length !== 2) throw new TypeError("source.repository must identify one credential-free GitHub repository.");
|
|
561
|
-
return url.toString().replace(/\/$/, "");
|
|
562
|
-
}
|
|
563
|
-
function parseReleaseManifest(value) {
|
|
564
|
-
const manifest = record$5(value, "release manifest");
|
|
565
|
-
exact$4(manifest, [
|
|
566
|
-
"artifacts",
|
|
567
|
-
"build",
|
|
568
|
-
"cost",
|
|
569
|
-
"createdAt",
|
|
570
|
-
"evidence",
|
|
571
|
-
"wasmOjContract",
|
|
572
|
-
"migrations",
|
|
573
|
-
"provenance",
|
|
574
|
-
"releaseId",
|
|
575
|
-
"runtime",
|
|
576
|
-
"schema",
|
|
577
|
-
"source",
|
|
578
|
-
"toolchains",
|
|
579
|
-
"version"
|
|
580
|
-
], [], "release manifest");
|
|
581
|
-
if (manifest.schema !== WASM_OJ_RELEASE_MANIFEST_SCHEMA) throw new TypeError("Release manifest schema is unsupported.");
|
|
582
|
-
if (manifest.wasmOjContract !== WASM_OJ_CONTRACT_VERSION$1) throw new TypeError("Release manifest uses another WASM-OJ contract.");
|
|
583
|
-
if (typeof manifest.releaseId !== "string" || !UUID.test(manifest.releaseId)) throw new TypeError("releaseId must be a UUID.");
|
|
584
|
-
if (typeof manifest.version !== "string" || !SEMVER.test(manifest.version)) throw new TypeError("version must be semantic versioning.");
|
|
585
|
-
const source = record$5(manifest.source, "source");
|
|
586
|
-
exact$4(source, [
|
|
587
|
-
"commit",
|
|
588
|
-
"repository",
|
|
589
|
-
"sourceTreeSha256"
|
|
590
|
-
], ["tag"], "source");
|
|
591
|
-
if (typeof source.commit !== "string" || !/^[0-9a-f]{40}$/.test(source.commit)) throw new TypeError("source.commit must be an exact Git commit SHA.");
|
|
592
|
-
if (source.tag !== void 0 && (typeof source.tag !== "string" || !VERSION.test(source.tag))) throw new TypeError("source.tag is invalid.");
|
|
593
|
-
const build = record$5(manifest.build, "build");
|
|
594
|
-
exact$4(build, [
|
|
595
|
-
"auditSha256",
|
|
596
|
-
"licensesSha256",
|
|
597
|
-
"lockSha256",
|
|
598
|
-
"nodeVersion",
|
|
599
|
-
"pnpmVersion",
|
|
600
|
-
"rustVersion",
|
|
601
|
-
"sbomSha256"
|
|
602
|
-
], [], "build");
|
|
603
|
-
const artifacts = record$5(manifest.artifacts, "artifacts");
|
|
604
|
-
exact$4(artifacts, [
|
|
605
|
-
"containerImage",
|
|
606
|
-
"npmPackage",
|
|
607
|
-
"staticAssets",
|
|
608
|
-
"workerBundle"
|
|
609
|
-
], [], "artifacts");
|
|
610
|
-
const container = record$5(artifacts.containerImage, "artifacts.containerImage");
|
|
611
|
-
exact$4(container, [
|
|
612
|
-
"baseImages",
|
|
613
|
-
"digest",
|
|
614
|
-
"dockerfileSha256",
|
|
615
|
-
"identitySha256",
|
|
616
|
-
"platform",
|
|
617
|
-
"registry"
|
|
618
|
-
], [], "artifacts.containerImage");
|
|
619
|
-
if (typeof container.registry !== "string" || !IDENTITY.test(container.registry)) throw new TypeError("Container registry identity is invalid.");
|
|
620
|
-
if (typeof container.digest !== "string" || !OCI_DIGEST.test(container.digest) || container.platform !== "linux/amd64") throw new TypeError("Container image identity is invalid.");
|
|
621
|
-
if (!Array.isArray(container.baseImages) || container.baseImages.length !== 3) throw new TypeError("Container base image inventory is invalid.");
|
|
622
|
-
const expectedStages = [
|
|
623
|
-
"node-build",
|
|
624
|
-
"rust-build",
|
|
625
|
-
"judge"
|
|
626
|
-
];
|
|
627
|
-
const baseImages = container.baseImages.map((value, index) => {
|
|
628
|
-
const base = record$5(value, `container base image ${index}`);
|
|
629
|
-
exact$4(base, [
|
|
630
|
-
"digest",
|
|
631
|
-
"image",
|
|
632
|
-
"stage"
|
|
633
|
-
], [], `container base image ${index}`);
|
|
634
|
-
if (base.stage !== expectedStages[index] || typeof base.image !== "string" || !IDENTITY.test(base.image) || typeof base.digest !== "string" || !OCI_DIGEST.test(base.digest)) throw new TypeError("Container base image inventory is invalid.");
|
|
635
|
-
return {
|
|
636
|
-
stage: base.stage,
|
|
637
|
-
image: base.image,
|
|
638
|
-
digest: base.digest
|
|
639
|
-
};
|
|
640
|
-
});
|
|
641
|
-
const runtime = record$5(manifest.runtime, "runtime");
|
|
642
|
-
exact$4(runtime, [
|
|
643
|
-
"compilerSha256",
|
|
644
|
-
"executionRootSha256",
|
|
645
|
-
"protocolVersion",
|
|
646
|
-
"rootSha256",
|
|
647
|
-
"runnerSha256",
|
|
648
|
-
"runtimeCoreSha256",
|
|
649
|
-
"runtimeIdentitySha256",
|
|
650
|
-
"wasmerSha256",
|
|
651
|
-
"wasmerVersion"
|
|
652
|
-
], [], "runtime");
|
|
653
|
-
if (runtime.protocolVersion !== "wasm-oj-container-v2") throw new TypeError("Container protocol is unsupported.");
|
|
654
|
-
if (runtime.runtimeIdentitySha256 !== "24c0bcff9820fbfd1fd4db1c57e2a866b83041409dd22b5b725688739bd3e223") throw new TypeError("Release runtime identity does not match this WASM-OJ build.");
|
|
655
|
-
const toolchains = record$5(manifest.toolchains, "toolchains");
|
|
656
|
-
exact$4(toolchains, ["manifestSha256", "rootSha256"], [], "toolchains");
|
|
657
|
-
const cost = record$5(manifest.cost, "cost");
|
|
658
|
-
exact$4(cost, [
|
|
659
|
-
"baselineSha256",
|
|
660
|
-
"model",
|
|
661
|
-
"profileRootSha256"
|
|
662
|
-
], [], "cost");
|
|
663
|
-
if (cost.model !== "weighted") throw new TypeError("Release cost model is unsupported.");
|
|
664
|
-
const evidence = record$5(manifest.evidence, "evidence");
|
|
665
|
-
exact$4(evidence, [
|
|
666
|
-
"conformanceSha256",
|
|
667
|
-
"costCalibrationSha256",
|
|
668
|
-
"testsSha256"
|
|
669
|
-
], [], "evidence");
|
|
670
|
-
const migrations = record$5(manifest.migrations, "migrations");
|
|
671
|
-
exact$4(migrations, ["databaseSha256"], [], "migrations");
|
|
672
|
-
const provenance = record$5(manifest.provenance, "provenance");
|
|
673
|
-
exact$4(provenance, ["issuer", "subject"], [], "provenance");
|
|
674
|
-
if (typeof provenance.issuer !== "string" || !IDENTITY.test(provenance.issuer) || typeof provenance.subject !== "string" || !IDENTITY.test(provenance.subject)) throw new TypeError("Release provenance identity is invalid.");
|
|
675
|
-
return {
|
|
676
|
-
schema: WASM_OJ_RELEASE_MANIFEST_SCHEMA,
|
|
677
|
-
releaseId: manifest.releaseId,
|
|
678
|
-
version: manifest.version,
|
|
679
|
-
wasmOjContract: WASM_OJ_CONTRACT_VERSION$1,
|
|
680
|
-
createdAt: timestamp(manifest.createdAt),
|
|
681
|
-
source: {
|
|
682
|
-
repository: sourceRepository(source.repository),
|
|
683
|
-
commit: source.commit,
|
|
684
|
-
sourceTreeSha256: digest$1(source.sourceTreeSha256, "source.sourceTreeSha256"),
|
|
685
|
-
...source.tag === void 0 ? {} : { tag: source.tag }
|
|
686
|
-
},
|
|
687
|
-
build: {
|
|
688
|
-
nodeVersion: version(build.nodeVersion, "build.nodeVersion"),
|
|
689
|
-
pnpmVersion: version(build.pnpmVersion, "build.pnpmVersion"),
|
|
690
|
-
rustVersion: version(build.rustVersion, "build.rustVersion"),
|
|
691
|
-
lockSha256: digest$1(build.lockSha256, "build.lockSha256"),
|
|
692
|
-
sbomSha256: digest$1(build.sbomSha256, "build.sbomSha256"),
|
|
693
|
-
licensesSha256: digest$1(build.licensesSha256, "build.licensesSha256"),
|
|
694
|
-
auditSha256: digest$1(build.auditSha256, "build.auditSha256")
|
|
695
|
-
},
|
|
696
|
-
artifacts: {
|
|
697
|
-
npmPackage: artifact(artifacts.npmPackage, "artifacts.npmPackage"),
|
|
698
|
-
workerBundle: artifact(artifacts.workerBundle, "artifacts.workerBundle"),
|
|
699
|
-
staticAssets: artifact(artifacts.staticAssets, "artifacts.staticAssets"),
|
|
700
|
-
containerImage: {
|
|
701
|
-
registry: container.registry,
|
|
702
|
-
digest: container.digest,
|
|
703
|
-
identitySha256: digest$1(container.identitySha256, "artifacts.containerImage.identitySha256"),
|
|
704
|
-
platform: "linux/amd64",
|
|
705
|
-
dockerfileSha256: digest$1(container.dockerfileSha256, "artifacts.containerImage.dockerfileSha256"),
|
|
706
|
-
baseImages
|
|
707
|
-
}
|
|
708
|
-
},
|
|
709
|
-
runtime: {
|
|
710
|
-
protocolVersion: WASM_OJ_CONTAINER_PROTOCOL_VERSION,
|
|
711
|
-
executionRootSha256: digest$1(runtime.executionRootSha256, "runtime.executionRootSha256"),
|
|
712
|
-
rootSha256: digest$1(runtime.rootSha256, "runtime.rootSha256"),
|
|
713
|
-
runtimeIdentitySha256: WASM_OJ_RUNTIME_IDENTITY_SHA256,
|
|
714
|
-
runtimeCoreSha256: digest$1(runtime.runtimeCoreSha256, "runtime.runtimeCoreSha256"),
|
|
715
|
-
wasmerVersion: version(runtime.wasmerVersion, "runtime.wasmerVersion"),
|
|
716
|
-
wasmerSha256: digest$1(runtime.wasmerSha256, "runtime.wasmerSha256"),
|
|
717
|
-
compilerSha256: digest$1(runtime.compilerSha256, "runtime.compilerSha256"),
|
|
718
|
-
runnerSha256: digest$1(runtime.runnerSha256, "runtime.runnerSha256")
|
|
719
|
-
},
|
|
720
|
-
toolchains: {
|
|
721
|
-
rootSha256: digest$1(toolchains.rootSha256, "toolchains.rootSha256"),
|
|
722
|
-
manifestSha256: digest$1(toolchains.manifestSha256, "toolchains.manifestSha256")
|
|
723
|
-
},
|
|
724
|
-
cost: {
|
|
725
|
-
model: WEIGHTED_METER_MODEL,
|
|
726
|
-
profileRootSha256: digest$1(cost.profileRootSha256, "cost.profileRootSha256"),
|
|
727
|
-
baselineSha256: digest$1(cost.baselineSha256, "cost.baselineSha256")
|
|
728
|
-
},
|
|
729
|
-
evidence: {
|
|
730
|
-
conformanceSha256: digest$1(evidence.conformanceSha256, "evidence.conformanceSha256"),
|
|
731
|
-
testsSha256: digest$1(evidence.testsSha256, "evidence.testsSha256"),
|
|
732
|
-
costCalibrationSha256: digest$1(evidence.costCalibrationSha256, "evidence.costCalibrationSha256")
|
|
733
|
-
},
|
|
734
|
-
migrations: { databaseSha256: digest$1(migrations.databaseSha256, "migrations.databaseSha256") },
|
|
735
|
-
provenance: {
|
|
736
|
-
issuer: provenance.issuer,
|
|
737
|
-
subject: provenance.subject
|
|
738
|
-
}
|
|
739
|
-
};
|
|
740
|
-
}
|
|
741
|
-
function createReleaseManifest(value) {
|
|
742
|
-
return parseReleaseManifest(value);
|
|
743
|
-
}
|
|
744
|
-
function releaseManifestBytes(value) {
|
|
745
|
-
return canonicalJsonBytes(parseReleaseManifest(value));
|
|
746
|
-
}
|
|
747
|
-
async function releaseManifestSha256(value) {
|
|
748
|
-
return sha256Hex$1(releaseManifestBytes(value));
|
|
749
|
-
}
|
|
750
|
-
async function verifyReleaseManifestBytes(bytes, expectedSha256) {
|
|
751
|
-
if (expectedSha256 !== void 0) {
|
|
752
|
-
if (digest$1(expectedSha256, "expected release manifest digest") !== await sha256Hex$1(bytes)) throw new TypeError("Release manifest bytes do not match the expected digest.");
|
|
753
|
-
}
|
|
754
|
-
return parseReleaseManifest(parseCanonicalJsonBytes(bytes, "release manifest"));
|
|
755
|
-
}
|
|
756
|
-
//#endregion
|
|
757
514
|
//#region src/core/project-files.ts
|
|
758
515
|
var PROJECT_SOURCE_LIMITS = Object.freeze({
|
|
759
516
|
files: 256,
|
|
@@ -807,7 +564,7 @@ function canonicalFileEntries(files) {
|
|
|
807
564
|
//#endregion
|
|
808
565
|
//#region src/core/dependencies.ts
|
|
809
566
|
var MIB = 1048576;
|
|
810
|
-
var SHA256$
|
|
567
|
+
var SHA256$3 = /^[0-9a-f]{64}$/;
|
|
811
568
|
/** Contract-level admission limits shared by dependency hosts and compilers. */
|
|
812
569
|
var DEPENDENCY_RESOLUTION_LIMITS = Object.freeze({
|
|
813
570
|
requirements: 128,
|
|
@@ -999,7 +756,7 @@ function assertSortedUnique(values, label) {
|
|
|
999
756
|
for (let index = 1; index < values.length; index += 1) if (values[index - 1] >= values[index]) throw new Error(`${label} must be sorted and unique.`);
|
|
1000
757
|
}
|
|
1001
758
|
function requireSha256$2(value, label) {
|
|
1002
|
-
if (typeof value !== "string" || !SHA256$
|
|
759
|
+
if (typeof value !== "string" || !SHA256$3.test(value)) throw new Error(`${label} SHA-256 must be lowercase hexadecimal.`);
|
|
1003
760
|
}
|
|
1004
761
|
function isRecord$4(value) {
|
|
1005
762
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -5341,10 +5098,10 @@ function quickJsBundle(artifact, stdin, config) {
|
|
|
5341
5098
|
${quickJsDeterminismPrelude(config.determinism)}
|
|
5342
5099
|
const __modules = ${JSON.stringify(modules)};
|
|
5343
5100
|
const __packageManifests = ${JSON.stringify(packageManifests)};
|
|
5344
|
-
|
|
5101
|
+
let __input = ${JSON.stringify(stdin)};
|
|
5345
5102
|
const __cache = Object.create(null);
|
|
5346
5103
|
const __std = {
|
|
5347
|
-
in: { readAsString: () => __input },
|
|
5104
|
+
in: { readAsString: () => { const result = __input; __input = ""; return result; } },
|
|
5348
5105
|
out: { puts: (value) => __wasm_oj_write_stdout(String(value)) },
|
|
5349
5106
|
err: { puts: (value) => __wasm_oj_write_stderr(String(value)) },
|
|
5350
5107
|
};
|
|
@@ -6079,124 +5836,12 @@ function observedJudgeDataMetrics(data, language, result) {
|
|
|
6079
5836
|
return observed;
|
|
6080
5837
|
}
|
|
6081
5838
|
//#endregion
|
|
6082
|
-
//#region src/online-judge/compile-profiles.ts
|
|
6083
|
-
function record$4(value, label) {
|
|
6084
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) throw new TypeError(`${label} must be an object.`);
|
|
6085
|
-
return value;
|
|
6086
|
-
}
|
|
6087
|
-
function parseJudgeAllowedProfiles(value, label = "allowedProfiles") {
|
|
6088
|
-
const profiles = record$4(value, label);
|
|
6089
|
-
const entries = Object.entries(profiles).sort(([left], [right]) => left.localeCompare(right));
|
|
6090
|
-
if (entries.length < 1) throw new TypeError(`${label} must contain at least one compile profile.`);
|
|
6091
|
-
const result = {};
|
|
6092
|
-
for (const [language, candidate] of entries) {
|
|
6093
|
-
if (!isBuiltinLanguage$1(language)) throw new TypeError(`${label} language '${language}' is unsupported.`);
|
|
6094
|
-
const profile = record$4(candidate, `${label}.${language}`);
|
|
6095
|
-
if (JSON.stringify(Object.keys(profile).sort()) !== JSON.stringify(["optimization", "target"])) throw new TypeError(`${label}.${language} has an invalid shape.`);
|
|
6096
|
-
if (profile.target !== "wasip1" && profile.target !== "wasix") throw new TypeError(`${label}.${language}.target is unsupported.`);
|
|
6097
|
-
if (profile.optimization !== "debug" && profile.optimization !== "release") throw new TypeError(`${label}.${language}.optimization is unsupported.`);
|
|
6098
|
-
result[language] = {
|
|
6099
|
-
target: profile.target,
|
|
6100
|
-
optimization: profile.optimization
|
|
6101
|
-
};
|
|
6102
|
-
}
|
|
6103
|
-
return result;
|
|
6104
|
-
}
|
|
6105
|
-
//#endregion
|
|
6106
|
-
//#region src/online-judge/managed-collection.ts
|
|
6107
|
-
var MANAGED_COLLECTION_SCHEMA = "wasm-oj-platform/managed-collection/v2";
|
|
6108
|
-
var SHA256$4 = /^[0-9a-f]{64}$/;
|
|
6109
|
-
var SLUG$1 = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
6110
|
-
var PATH$1 = /^(?!\/)(?!.*(?:^|\/)\.{1,2}(?:\/|$))(?!.*\/\/)(?!.*\\)(?!.*\/$)[^\u0000]+$/;
|
|
6111
|
-
var MAX_MANAGED_COLLECTION_BYTES = 2097152;
|
|
6112
|
-
var MAX_PROJECTION_BYTES = 33554432;
|
|
6113
|
-
function record$3(value, label) {
|
|
6114
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) throw new TypeError(`${label} must be an object.`);
|
|
6115
|
-
return value;
|
|
6116
|
-
}
|
|
6117
|
-
function exact$3(value, expected, label) {
|
|
6118
|
-
const actual = Object.keys(value).sort();
|
|
6119
|
-
const wanted = [...expected].sort();
|
|
6120
|
-
if (JSON.stringify(actual) !== JSON.stringify(wanted)) throw new TypeError(`${label} must contain exactly: ${wanted.join(", ")}.`);
|
|
6121
|
-
}
|
|
6122
|
-
function repositoryObject(value, label, maximum) {
|
|
6123
|
-
const object = record$3(value, label);
|
|
6124
|
-
exact$3(object, [
|
|
6125
|
-
"bytes",
|
|
6126
|
-
"repositoryPath",
|
|
6127
|
-
"sha256"
|
|
6128
|
-
], label);
|
|
6129
|
-
if (typeof object.repositoryPath !== "string" || object.repositoryPath.length < 1 || object.repositoryPath.length > 512 || !PATH$1.test(object.repositoryPath)) throw new TypeError(`${label}.repositoryPath must be a normalized relative POSIX path.`);
|
|
6130
|
-
if (!Number.isSafeInteger(object.bytes) || object.bytes < 1 || object.bytes > maximum) throw new TypeError(`${label}.bytes is outside its publication limit.`);
|
|
6131
|
-
if (typeof object.sha256 !== "string" || !SHA256$4.test(object.sha256)) throw new TypeError(`${label}.sha256 must be a lowercase SHA-256 digest.`);
|
|
6132
|
-
return {
|
|
6133
|
-
repositoryPath: object.repositoryPath,
|
|
6134
|
-
bytes: object.bytes,
|
|
6135
|
-
sha256: object.sha256
|
|
6136
|
-
};
|
|
6137
|
-
}
|
|
6138
|
-
/** Parse the value form used by the authoring CLI after JSON decoding. */
|
|
6139
|
-
function parseManagedCollectionValueV2(value) {
|
|
6140
|
-
const collection = record$3(value, "managed collection");
|
|
6141
|
-
exact$3(collection, [
|
|
6142
|
-
"collectionRevision",
|
|
6143
|
-
"problems",
|
|
6144
|
-
"schema"
|
|
6145
|
-
], "managed collection");
|
|
6146
|
-
if (collection.schema !== "wasm-oj-platform/managed-collection/v2") throw new TypeError(`Managed collection schema must be '${MANAGED_COLLECTION_SCHEMA}'.`);
|
|
6147
|
-
if (typeof collection.collectionRevision !== "string" || !SHA256$4.test(collection.collectionRevision)) throw new TypeError("Managed collection revision must be a lowercase SHA-256 digest.");
|
|
6148
|
-
if (!Array.isArray(collection.problems) || collection.problems.length < 1 || collection.problems.length > 1e3) throw new TypeError("Managed collection must contain between 1 and 1000 problems.");
|
|
6149
|
-
const slugs = /* @__PURE__ */ new Set();
|
|
6150
|
-
const paths = /* @__PURE__ */ new Set();
|
|
6151
|
-
const problems = collection.problems.map((candidate, index) => {
|
|
6152
|
-
const problem = record$3(candidate, `managed problem ${index + 1}`);
|
|
6153
|
-
exact$3(problem, [
|
|
6154
|
-
"allowedProfiles",
|
|
6155
|
-
"contestPublic",
|
|
6156
|
-
"judgePackage",
|
|
6157
|
-
"slug"
|
|
6158
|
-
], `managed problem ${index + 1}`);
|
|
6159
|
-
if (typeof problem.slug !== "string" || !SLUG$1.test(problem.slug) || slugs.has(problem.slug)) throw new TypeError(`Managed problem ${index + 1} has an invalid or duplicate slug.`);
|
|
6160
|
-
slugs.add(problem.slug);
|
|
6161
|
-
const allowedProfiles = parseJudgeAllowedProfiles(problem.allowedProfiles, `managed problem '${problem.slug}' allowedProfiles`);
|
|
6162
|
-
const contestPublic = repositoryObject(problem.contestPublic, `managed problem '${problem.slug}' contestPublic`, 8388608);
|
|
6163
|
-
const judgePackage = repositoryObject(problem.judgePackage, `managed problem '${problem.slug}' judgePackage`, MAX_PROJECTION_BYTES);
|
|
6164
|
-
for (const path of [contestPublic.repositoryPath, judgePackage.repositoryPath]) {
|
|
6165
|
-
if (paths.has(path)) throw new TypeError(`Managed publication path '${path}' is declared more than once.`);
|
|
6166
|
-
paths.add(path);
|
|
6167
|
-
}
|
|
6168
|
-
return {
|
|
6169
|
-
slug: problem.slug,
|
|
6170
|
-
allowedProfiles,
|
|
6171
|
-
contestPublic,
|
|
6172
|
-
judgePackage
|
|
6173
|
-
};
|
|
6174
|
-
});
|
|
6175
|
-
return {
|
|
6176
|
-
schema: MANAGED_COLLECTION_SCHEMA,
|
|
6177
|
-
collectionRevision: collection.collectionRevision,
|
|
6178
|
-
problems
|
|
6179
|
-
};
|
|
6180
|
-
}
|
|
6181
|
-
/**
|
|
6182
|
-
* Stable platform boundary for generated collection/managed.json bytes.
|
|
6183
|
-
* Published managed contracts must use WASM-OJ canonical JSON; author-only
|
|
6184
|
-
* managed-source documents are intentionally not accepted here.
|
|
6185
|
-
*/
|
|
6186
|
-
function parseManagedCollectionV2(bytes) {
|
|
6187
|
-
if (!(bytes instanceof Uint8Array) || bytes.byteLength < 1 || bytes.byteLength > MAX_MANAGED_COLLECTION_BYTES) throw new TypeError("Managed collection bytes are outside the 2 MiB limit.");
|
|
6188
|
-
return parseManagedCollectionValueV2(parseCanonicalJsonBytes(bytes, "managed collection"));
|
|
6189
|
-
}
|
|
6190
|
-
/** Same v2-only value parser retained as the environment-neutral library entry point. */
|
|
6191
|
-
var parseManagedCollectionContract = parseManagedCollectionValueV2;
|
|
6192
|
-
//#endregion
|
|
6193
5839
|
//#region src/online-judge/contest-public.ts
|
|
6194
5840
|
var CONTEST_PUBLIC_PROJECTION_SCHEMA = "wasm-oj-platform/contest-public-problem-projection/v1";
|
|
6195
|
-
var SHA256$3 = /^[0-9a-f]{64}$/;
|
|
6196
5841
|
/**
|
|
6197
|
-
* The
|
|
6198
|
-
*
|
|
6199
|
-
*
|
|
5842
|
+
* The repository practice bundle is safe to fetch for every practice visitor.
|
|
5843
|
+
* Hidden cases and their expected answers exist only in the immutable judge
|
|
5844
|
+
* package built from the authoring source.
|
|
6200
5845
|
*/
|
|
6201
5846
|
function derivePracticePublic(authored) {
|
|
6202
5847
|
return {
|
|
@@ -6216,16 +5861,38 @@ function deriveContestPublic(practice) {
|
|
|
6216
5861
|
judgeCases: practice.judgeCases.filter((testCase) => testCase.kind === "sample").map((testCase) => structuredClone(testCase))
|
|
6217
5862
|
};
|
|
6218
5863
|
}
|
|
6219
|
-
function createContestPublicProjection(practice
|
|
6220
|
-
if (typeof problemBundleSha256 !== "string" || !SHA256$3.test(problemBundleSha256)) throw new TypeError("Contest-public projection digest must be a lowercase SHA-256 digest.");
|
|
5864
|
+
function createContestPublicProjection(practice) {
|
|
6221
5865
|
return {
|
|
6222
5866
|
schema: CONTEST_PUBLIC_PROJECTION_SCHEMA,
|
|
6223
|
-
problem: deriveContestPublic(practice)
|
|
6224
|
-
digest: problemBundleSha256
|
|
5867
|
+
problem: deriveContestPublic(practice)
|
|
6225
5868
|
};
|
|
6226
5869
|
}
|
|
6227
|
-
function contestPublicProjectionBytes(practice
|
|
6228
|
-
return canonicalJsonBytes(createContestPublicProjection(practice
|
|
5870
|
+
function contestPublicProjectionBytes(practice) {
|
|
5871
|
+
return canonicalJsonBytes(createContestPublicProjection(practice));
|
|
5872
|
+
}
|
|
5873
|
+
//#endregion
|
|
5874
|
+
//#region src/online-judge/compile-profiles.ts
|
|
5875
|
+
function record$3(value, label) {
|
|
5876
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new TypeError(`${label} must be an object.`);
|
|
5877
|
+
return value;
|
|
5878
|
+
}
|
|
5879
|
+
function parseJudgeAllowedProfiles(value, label = "allowedProfiles") {
|
|
5880
|
+
const profiles = record$3(value, label);
|
|
5881
|
+
const entries = Object.entries(profiles).sort(([left], [right]) => left.localeCompare(right));
|
|
5882
|
+
if (entries.length < 1) throw new TypeError(`${label} must contain at least one compile profile.`);
|
|
5883
|
+
const result = {};
|
|
5884
|
+
for (const [language, candidate] of entries) {
|
|
5885
|
+
if (!isBuiltinLanguage$1(language)) throw new TypeError(`${label} language '${language}' is unsupported.`);
|
|
5886
|
+
const profile = record$3(candidate, `${label}.${language}`);
|
|
5887
|
+
if (JSON.stringify(Object.keys(profile).sort()) !== JSON.stringify(["optimization", "target"])) throw new TypeError(`${label}.${language} has an invalid shape.`);
|
|
5888
|
+
if (profile.target !== "wasip1" && profile.target !== "wasix") throw new TypeError(`${label}.${language}.target is unsupported.`);
|
|
5889
|
+
if (profile.optimization !== "debug" && profile.optimization !== "release") throw new TypeError(`${label}.${language}.optimization is unsupported.`);
|
|
5890
|
+
result[language] = {
|
|
5891
|
+
target: profile.target,
|
|
5892
|
+
optimization: profile.optimization
|
|
5893
|
+
};
|
|
5894
|
+
}
|
|
5895
|
+
return result;
|
|
6229
5896
|
}
|
|
6230
5897
|
//#endregion
|
|
6231
5898
|
//#region src/online-judge/unicode-scalar.ts
|
|
@@ -6767,8 +6434,8 @@ async function validateJudgePackage(source, options = {}) {
|
|
|
6767
6434
|
}
|
|
6768
6435
|
}
|
|
6769
6436
|
const completed = await reader.finish();
|
|
6770
|
-
if (options.expectedBytes !== void 0 && completed.bytes !== options.expectedBytes) throw new TypeError("Judge package byte length disagrees with its
|
|
6771
|
-
if (options.expectedSha256 !== void 0 && completed.sha256 !== options.expectedSha256) throw new TypeError("Judge package digest disagrees with its
|
|
6437
|
+
if (options.expectedBytes !== void 0 && completed.bytes !== options.expectedBytes) throw new TypeError("Judge package byte length disagrees with its descriptor.");
|
|
6438
|
+
if (options.expectedSha256 !== void 0 && completed.sha256 !== options.expectedSha256) throw new TypeError("Judge package digest disagrees with its descriptor.");
|
|
6772
6439
|
if (!judgeData) throw new TypeError("Judge package is missing its judgeData blob.");
|
|
6773
6440
|
return {
|
|
6774
6441
|
manifest,
|
|
@@ -6988,8 +6655,8 @@ var IncrementalSha256 = class {
|
|
|
6988
6655
|
}
|
|
6989
6656
|
};
|
|
6990
6657
|
//#endregion
|
|
6991
|
-
//#region src/online-judge/
|
|
6992
|
-
var
|
|
6658
|
+
//#region src/online-judge/repository-authoring.ts
|
|
6659
|
+
var REPOSITORY_AUTHORING_JUDGES_SCHEMA = "wasm-oj-platform/repository-authoring-judges/v1";
|
|
6993
6660
|
var SHA256$1 = /^[0-9a-f]{64}$/;
|
|
6994
6661
|
var SLUG = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
6995
6662
|
var PATH = /^(?!\/)(?!.*(?:^|\/)\.{1,2}(?:\/|$))(?!.*\/\/)(?!.*\\)(?!.*\/$)[^\u0000]+$/;
|
|
@@ -7001,9 +6668,7 @@ function record(value, label) {
|
|
|
7001
6668
|
return value;
|
|
7002
6669
|
}
|
|
7003
6670
|
function exact(value, keys, label) {
|
|
7004
|
-
|
|
7005
|
-
const expected = [...keys].sort();
|
|
7006
|
-
if (JSON.stringify(actual) !== JSON.stringify(expected)) throw new TypeError(`${label} has an invalid shape.`);
|
|
6671
|
+
if (Object.keys(value).sort().join("\0") !== [...keys].sort().join("\0")) throw new TypeError(`${label} has an invalid shape.`);
|
|
7007
6672
|
}
|
|
7008
6673
|
function sourceObject(value, label, maximum) {
|
|
7009
6674
|
const object = record(value, label);
|
|
@@ -7021,16 +6686,13 @@ function sourceObject(value, label, maximum) {
|
|
|
7021
6686
|
sha256: object.sha256
|
|
7022
6687
|
};
|
|
7023
6688
|
}
|
|
7024
|
-
function profiles(value, slug) {
|
|
7025
|
-
return parseJudgeAllowedProfiles(value, `managed source '${slug}' allowedProfiles`);
|
|
7026
|
-
}
|
|
7027
6689
|
function judge(value, slug) {
|
|
7028
|
-
const input = record(value, `
|
|
6690
|
+
const input = record(value, `repository authoring '${slug}' judge`);
|
|
7029
6691
|
if (input.kind === "text") {
|
|
7030
|
-
exact(input, ["kind"], `
|
|
6692
|
+
exact(input, ["kind"], `repository authoring '${slug}' text judge`);
|
|
7031
6693
|
return { kind: "text" };
|
|
7032
6694
|
}
|
|
7033
|
-
if (input.kind !== "checker" && input.kind !== "interactive") throw new TypeError(`
|
|
6695
|
+
if (input.kind !== "checker" && input.kind !== "interactive") throw new TypeError(`Repository authoring '${slug}' judge kind is unsupported.`);
|
|
7034
6696
|
exact(input, input.kind === "checker" ? [
|
|
7035
6697
|
"args",
|
|
7036
6698
|
"artifact",
|
|
@@ -7042,86 +6704,86 @@ function judge(value, slug) {
|
|
|
7042
6704
|
"assets",
|
|
7043
6705
|
"inputPath",
|
|
7044
6706
|
"kind"
|
|
7045
|
-
], `
|
|
7046
|
-
const artifactValue = record(input.artifact, `
|
|
6707
|
+
], `repository authoring '${slug}' ${input.kind}`);
|
|
6708
|
+
const artifactValue = record(input.artifact, `repository authoring '${slug}' ${input.kind} artifact`);
|
|
7047
6709
|
exact(artifactValue, [
|
|
7048
6710
|
"bytes",
|
|
7049
6711
|
"path",
|
|
7050
6712
|
"runtimeProfile",
|
|
7051
6713
|
"sha256"
|
|
7052
|
-
], `
|
|
7053
|
-
if (typeof artifactValue.runtimeProfile !== "string" || !TRUSTED_JUDGE_RUNTIME_PROFILES.has(artifactValue.runtimeProfile)) throw new TypeError(`
|
|
6714
|
+
], `repository authoring '${slug}' ${input.kind} artifact`);
|
|
6715
|
+
if (typeof artifactValue.runtimeProfile !== "string" || !TRUSTED_JUDGE_RUNTIME_PROFILES.has(artifactValue.runtimeProfile)) throw new TypeError(`Repository authoring '${slug}' ${input.kind} runtimeProfile is unsupported.`);
|
|
7054
6716
|
const artifact = {
|
|
7055
6717
|
...sourceObject({
|
|
7056
6718
|
bytes: artifactValue.bytes,
|
|
7057
6719
|
path: artifactValue.path,
|
|
7058
6720
|
sha256: artifactValue.sha256
|
|
7059
|
-
}, `
|
|
6721
|
+
}, `repository authoring '${slug}' ${input.kind} artifact`, TRUSTED_JUDGE_WASM_MAX_BYTES),
|
|
7060
6722
|
runtimeProfile: artifactValue.runtimeProfile
|
|
7061
6723
|
};
|
|
7062
|
-
if (!artifact.path.endsWith(".wasm")) throw new TypeError(`
|
|
7063
|
-
if (!Array.isArray(input.assets) || input.assets.length > 256) throw new TypeError(`
|
|
6724
|
+
if (!artifact.path.endsWith(".wasm")) throw new TypeError(`Repository authoring '${slug}' ${input.kind} artifact path must end in '.wasm'.`);
|
|
6725
|
+
if (!Array.isArray(input.assets) || input.assets.length > 256) throw new TypeError(`Repository authoring '${slug}' ${input.kind} assets are invalid.`);
|
|
7064
6726
|
const namespace = input.kind === "checker" ? "/checker/assets/" : "/interactor/assets/";
|
|
7065
6727
|
const assets = input.assets.map((candidate, index) => {
|
|
7066
|
-
const asset = record(candidate, `
|
|
6728
|
+
const asset = record(candidate, `repository authoring '${slug}' ${input.kind} asset ${index}`);
|
|
7067
6729
|
exact(asset, [
|
|
7068
6730
|
"bytes",
|
|
7069
6731
|
"guestPath",
|
|
7070
6732
|
"path",
|
|
7071
6733
|
"sha256"
|
|
7072
|
-
], `
|
|
7073
|
-
if (typeof asset.guestPath !== "string" || !GUEST_PATH.test(asset.guestPath) || !asset.guestPath.startsWith(namespace)) throw new TypeError(`
|
|
6734
|
+
], `repository authoring '${slug}' ${input.kind} asset ${index}`);
|
|
6735
|
+
if (typeof asset.guestPath !== "string" || !GUEST_PATH.test(asset.guestPath) || !asset.guestPath.startsWith(namespace)) throw new TypeError(`Repository authoring '${slug}' ${input.kind} asset ${index} guestPath must be inside '${namespace}'.`);
|
|
7074
6736
|
return {
|
|
7075
6737
|
...sourceObject({
|
|
7076
6738
|
bytes: asset.bytes,
|
|
7077
6739
|
path: asset.path,
|
|
7078
6740
|
sha256: asset.sha256
|
|
7079
|
-
}, `
|
|
6741
|
+
}, `repository authoring '${slug}' ${input.kind} asset ${index}`, MAX_ASSET_BYTES),
|
|
7080
6742
|
guestPath: asset.guestPath
|
|
7081
6743
|
};
|
|
7082
6744
|
});
|
|
7083
6745
|
const guestPaths = assets.map((asset) => asset.guestPath);
|
|
7084
6746
|
const repositoryPaths = [artifact.path, ...assets.map((asset) => asset.path)];
|
|
7085
|
-
if (new Set(guestPaths).size !== guestPaths.length || new Set(repositoryPaths).size !== repositoryPaths.length) throw new TypeError(`
|
|
7086
|
-
if (assets.reduce((total, asset) => total + asset.bytes, 0) > MAX_ASSET_TOTAL_BYTES) throw new TypeError(`
|
|
7087
|
-
if (!Array.isArray(input.args) || input.args.length > 64 || input.args.some((argument) => typeof argument !== "string" || argument.includes("\0") || new TextEncoder().encode(argument).byteLength > 4096)) throw new TypeError(`
|
|
7088
|
-
const
|
|
6747
|
+
if (new Set(guestPaths).size !== guestPaths.length || new Set(repositoryPaths).size !== repositoryPaths.length) throw new TypeError(`Repository authoring '${slug}' ${input.kind} repeats an asset or repository path.`);
|
|
6748
|
+
if (assets.reduce((total, asset) => total + asset.bytes, 0) > MAX_ASSET_TOTAL_BYTES) throw new TypeError(`Repository authoring '${slug}' ${input.kind} assets exceed 4 MiB.`);
|
|
6749
|
+
if (!Array.isArray(input.args) || input.args.length > 64 || input.args.some((argument) => typeof argument !== "string" || argument.includes("\0") || new TextEncoder().encode(argument).byteLength > 4096)) throw new TypeError(`Repository authoring '${slug}' ${input.kind} args are invalid.`);
|
|
6750
|
+
const args = [...input.args];
|
|
7089
6751
|
if (input.kind === "checker") return {
|
|
7090
6752
|
kind: "checker",
|
|
7091
6753
|
artifact,
|
|
7092
6754
|
assets,
|
|
7093
|
-
args
|
|
6755
|
+
args
|
|
7094
6756
|
};
|
|
7095
|
-
if (typeof input.inputPath !== "string" || !GUEST_PATH.test(input.inputPath) || !input.inputPath.startsWith("/interactor/input/")) throw new TypeError(`
|
|
6757
|
+
if (typeof input.inputPath !== "string" || !GUEST_PATH.test(input.inputPath) || !input.inputPath.startsWith("/interactor/input/")) throw new TypeError(`Repository authoring '${slug}' interactive inputPath must be inside '/interactor/input/'.`);
|
|
7096
6758
|
return {
|
|
7097
6759
|
kind: "interactive",
|
|
7098
6760
|
artifact,
|
|
7099
6761
|
assets,
|
|
7100
|
-
args
|
|
6762
|
+
args,
|
|
7101
6763
|
inputPath: input.inputPath
|
|
7102
6764
|
};
|
|
7103
6765
|
}
|
|
7104
|
-
/** Author-only
|
|
7105
|
-
function
|
|
7106
|
-
const source = record(value, "
|
|
7107
|
-
exact(source, ["problems", "schema"], "
|
|
7108
|
-
if (source.schema !== "wasm-oj-platform/
|
|
7109
|
-
if (!Array.isArray(source.problems) || source.problems.length < 1 || source.problems.length > 1e3) throw new TypeError("
|
|
6766
|
+
/** Author-only input used by collection build; never accepted by the platform sync boundary. */
|
|
6767
|
+
function parseRepositoryAuthoringJudges(value) {
|
|
6768
|
+
const source = record(value, "repository authoring judges");
|
|
6769
|
+
exact(source, ["problems", "schema"], "repository authoring judges");
|
|
6770
|
+
if (source.schema !== "wasm-oj-platform/repository-authoring-judges/v1") throw new TypeError(`Repository authoring judge schema must be '${REPOSITORY_AUTHORING_JUDGES_SCHEMA}'.`);
|
|
6771
|
+
if (!Array.isArray(source.problems) || source.problems.length < 1 || source.problems.length > 1e3) throw new TypeError("Repository authoring judges must contain between 1 and 1000 problems.");
|
|
7110
6772
|
const slugs = /* @__PURE__ */ new Set();
|
|
7111
6773
|
return {
|
|
7112
|
-
schema:
|
|
6774
|
+
schema: REPOSITORY_AUTHORING_JUDGES_SCHEMA,
|
|
7113
6775
|
problems: source.problems.map((candidate, index) => {
|
|
7114
|
-
const problem = record(candidate, `
|
|
6776
|
+
const problem = record(candidate, `repository authoring judge problem ${index + 1}`);
|
|
7115
6777
|
exact(problem, [
|
|
7116
6778
|
"allowedProfiles",
|
|
7117
6779
|
"judge",
|
|
7118
6780
|
"slug"
|
|
7119
|
-
], `
|
|
7120
|
-
if (typeof problem.slug !== "string" || !SLUG.test(problem.slug) || slugs.has(problem.slug)) throw new TypeError(`
|
|
6781
|
+
], `repository authoring judge problem ${index + 1}`);
|
|
6782
|
+
if (typeof problem.slug !== "string" || !SLUG.test(problem.slug) || slugs.has(problem.slug)) throw new TypeError(`Repository authoring judge problem ${index + 1} has an invalid or duplicate slug.`);
|
|
7121
6783
|
slugs.add(problem.slug);
|
|
7122
6784
|
return {
|
|
7123
6785
|
slug: problem.slug,
|
|
7124
|
-
allowedProfiles:
|
|
6786
|
+
allowedProfiles: parseJudgeAllowedProfiles(problem.allowedProfiles, `repository authoring '${problem.slug}' allowedProfiles`),
|
|
7125
6787
|
judge: judge(problem.judge, problem.slug)
|
|
7126
6788
|
};
|
|
7127
6789
|
})
|
|
@@ -8394,6 +8056,129 @@ function requireSha256(value) {
|
|
|
8394
8056
|
if (!/^[0-9a-f]{64}$/.test(value)) throw new Error("Dependency integrity must be lowercase SHA-256 hexadecimal.");
|
|
8395
8057
|
}
|
|
8396
8058
|
//#endregion
|
|
8059
|
+
//#region src/conformance/stdio-cases.ts
|
|
8060
|
+
var programs = [
|
|
8061
|
+
{
|
|
8062
|
+
language: "c",
|
|
8063
|
+
entry: "main.c",
|
|
8064
|
+
source: "#include <stdio.h>\nint main(){int c;while((c=getchar())!=EOF)printf(\"%02x\",(unsigned)c);puts(\"\");return 0;}"
|
|
8065
|
+
},
|
|
8066
|
+
{
|
|
8067
|
+
language: "cpp",
|
|
8068
|
+
entry: "main.cpp",
|
|
8069
|
+
source: "#include <iostream>\n#include <cstdio>\nint main(){char c;while(std::cin.get(c))printf(\"%02x\",(unsigned char)c);puts(\"\");}"
|
|
8070
|
+
},
|
|
8071
|
+
{
|
|
8072
|
+
language: "python",
|
|
8073
|
+
entry: "main.py",
|
|
8074
|
+
source: "import sys\nprint(sys.stdin.buffer.read().hex())\n"
|
|
8075
|
+
},
|
|
8076
|
+
{
|
|
8077
|
+
language: "rust",
|
|
8078
|
+
entry: "main.rs",
|
|
8079
|
+
source: "use std::io::{self,Read};fn main(){let mut b=Vec::new();io::stdin().read_to_end(&mut b).unwrap();for x in b{print!(\"{:02x}\",x);}println!();}"
|
|
8080
|
+
},
|
|
8081
|
+
{
|
|
8082
|
+
language: "go",
|
|
8083
|
+
entry: "main.go",
|
|
8084
|
+
source: "package main\nimport(\"fmt\";\"io\";\"os\")\nfunc main(){b,_:=io.ReadAll(os.Stdin);fmt.Printf(\"%x\\n\",b)}"
|
|
8085
|
+
},
|
|
8086
|
+
{
|
|
8087
|
+
language: "java",
|
|
8088
|
+
entry: "Main.java",
|
|
8089
|
+
source: "import java.io.*;public class Main{public static void main(String[]args)throws Exception{BufferedReader r=new BufferedReader(new InputStreamReader(System.in));String s;while((s=r.readLine())!=null)System.out.println(\"[\"+s+\"]\");System.out.println(\"EOF\");}}"
|
|
8090
|
+
},
|
|
8091
|
+
{
|
|
8092
|
+
language: "javascript",
|
|
8093
|
+
entry: "main.js",
|
|
8094
|
+
source: "import * as std from \"std\";const s=std.in.readAsString();console.log(Array.from(unescape(encodeURIComponent(s)),c=>c.charCodeAt(0).toString(16).padStart(2,\"0\")).join(\"\"));if(std.in.readAsString()!==\"\")throw Error(\"Repeated stdin\");"
|
|
8095
|
+
},
|
|
8096
|
+
{
|
|
8097
|
+
language: "typescript",
|
|
8098
|
+
entry: "main.ts",
|
|
8099
|
+
source: "import * as std from \"std\";const s=std.in.readAsString();console.log(Array.from(unescape(encodeURIComponent(s)),c=>c.charCodeAt(0).toString(16).padStart(2,\"0\")).join(\"\"));if(std.in.readAsString()!==\"\")throw Error(\"Repeated stdin\");"
|
|
8100
|
+
}
|
|
8101
|
+
];
|
|
8102
|
+
var inputs = [
|
|
8103
|
+
{
|
|
8104
|
+
id: "empty",
|
|
8105
|
+
stdin: ""
|
|
8106
|
+
},
|
|
8107
|
+
{
|
|
8108
|
+
id: "lf",
|
|
8109
|
+
stdin: "\n"
|
|
8110
|
+
},
|
|
8111
|
+
{
|
|
8112
|
+
id: "one-byte",
|
|
8113
|
+
stdin: "x"
|
|
8114
|
+
},
|
|
8115
|
+
{
|
|
8116
|
+
id: "no-final-lf",
|
|
8117
|
+
stdin: "abc"
|
|
8118
|
+
},
|
|
8119
|
+
{
|
|
8120
|
+
id: "final-lf",
|
|
8121
|
+
stdin: "abc\n"
|
|
8122
|
+
},
|
|
8123
|
+
{
|
|
8124
|
+
id: "multiple-lf",
|
|
8125
|
+
stdin: "abc\n\n"
|
|
8126
|
+
},
|
|
8127
|
+
{
|
|
8128
|
+
id: "crlf",
|
|
8129
|
+
stdin: "abc\r\nx\r\n"
|
|
8130
|
+
},
|
|
8131
|
+
{
|
|
8132
|
+
id: "bare-cr",
|
|
8133
|
+
stdin: "abc\rx"
|
|
8134
|
+
},
|
|
8135
|
+
{
|
|
8136
|
+
id: "spaces",
|
|
8137
|
+
stdin: " abc \n x "
|
|
8138
|
+
},
|
|
8139
|
+
{
|
|
8140
|
+
id: "unicode",
|
|
8141
|
+
stdin: "中文🙂\n終"
|
|
8142
|
+
},
|
|
8143
|
+
{
|
|
8144
|
+
id: "bom",
|
|
8145
|
+
stdin: "abc\n"
|
|
8146
|
+
},
|
|
8147
|
+
{
|
|
8148
|
+
id: "nul",
|
|
8149
|
+
stdin: "a\0b\n"
|
|
8150
|
+
},
|
|
8151
|
+
{
|
|
8152
|
+
id: "long-line",
|
|
8153
|
+
stdin: "x".repeat(8193)
|
|
8154
|
+
},
|
|
8155
|
+
{
|
|
8156
|
+
id: "last-line",
|
|
8157
|
+
stdin: "first\nlast"
|
|
8158
|
+
}
|
|
8159
|
+
];
|
|
8160
|
+
var STDIO_CONFORMANCE_CASES = programs.flatMap((program) => inputs.map(({ id, stdin }) => {
|
|
8161
|
+
const lines = stdin === "" ? [] : stdin.split(/\r\n|\r|\n/);
|
|
8162
|
+
if (/[\r\n]$/.test(stdin)) lines.pop();
|
|
8163
|
+
return {
|
|
8164
|
+
id: `${program.language}-wasip1-stdio-${id}`,
|
|
8165
|
+
label: `${program.language} / wasip1 / stdin ${id}`,
|
|
8166
|
+
input: {
|
|
8167
|
+
language: program.language,
|
|
8168
|
+
target: "wasip1",
|
|
8169
|
+
entry: program.entry,
|
|
8170
|
+
files: { [program.entry]: program.source }
|
|
8171
|
+
},
|
|
8172
|
+
run: { stdin },
|
|
8173
|
+
expect: {
|
|
8174
|
+
code: 0,
|
|
8175
|
+
stdout: program.language === "java" ? `${lines.map((line) => `[${line}]\n`).join("")}EOF\n` : `${Array.from(new TextEncoder().encode(stdin), (byte) => byte.toString(16).padStart(2, "0")).join("")}\n`,
|
|
8176
|
+
stderr: "",
|
|
8177
|
+
termination: "exited"
|
|
8178
|
+
}
|
|
8179
|
+
};
|
|
8180
|
+
}));
|
|
8181
|
+
//#endregion
|
|
8397
8182
|
//#region src/conformance/cases.ts
|
|
8398
8183
|
var DEFAULT_CONFORMANCE_CASES = deepFreeze([
|
|
8399
8184
|
{
|
|
@@ -8619,6 +8404,54 @@ var DEFAULT_CONFORMANCE_CASES = deepFreeze([
|
|
|
8619
8404
|
termination: "exited"
|
|
8620
8405
|
}
|
|
8621
8406
|
},
|
|
8407
|
+
{
|
|
8408
|
+
id: "python-wasip1-stdin-eof",
|
|
8409
|
+
label: "Python / wasip1 / redirected input at EOF",
|
|
8410
|
+
input: {
|
|
8411
|
+
language: "python",
|
|
8412
|
+
target: "wasip1",
|
|
8413
|
+
entry: "src/main.py",
|
|
8414
|
+
files: { "src/main.py": [
|
|
8415
|
+
"import os, sys",
|
|
8416
|
+
"assert not any(os.isatty(fd) for fd in range(3))",
|
|
8417
|
+
"assert not any(stream.isatty() for stream in (sys.stdin, sys.stdout, sys.stderr))",
|
|
8418
|
+
"assert input() == 'abc\\r'",
|
|
8419
|
+
"assert input() == 'x'",
|
|
8420
|
+
"assert input() == '終'",
|
|
8421
|
+
"try:",
|
|
8422
|
+
" input()",
|
|
8423
|
+
"except EOFError:",
|
|
8424
|
+
" print('OK')",
|
|
8425
|
+
"else:",
|
|
8426
|
+
" raise AssertionError('Expected EOFError')",
|
|
8427
|
+
""
|
|
8428
|
+
].join("\n") }
|
|
8429
|
+
},
|
|
8430
|
+
run: { stdin: "abc\r\nx\n終" },
|
|
8431
|
+
expect: {
|
|
8432
|
+
code: 0,
|
|
8433
|
+
stdout: "OK\n",
|
|
8434
|
+
stderr: "",
|
|
8435
|
+
termination: "exited"
|
|
8436
|
+
}
|
|
8437
|
+
},
|
|
8438
|
+
{
|
|
8439
|
+
id: "python-wasip1-stdin-bytes",
|
|
8440
|
+
label: "Python / wasip1 / exact input bytes",
|
|
8441
|
+
input: {
|
|
8442
|
+
language: "python",
|
|
8443
|
+
target: "wasip1",
|
|
8444
|
+
entry: "src/main.py",
|
|
8445
|
+
files: { "src/main.py": "import sys\nassert sys.stdin.buffer.read() == b'abc\\r\\nx'\nprint('OK')\n" }
|
|
8446
|
+
},
|
|
8447
|
+
run: { stdin: "abc\r\nx" },
|
|
8448
|
+
expect: {
|
|
8449
|
+
code: 0,
|
|
8450
|
+
stdout: "OK\n",
|
|
8451
|
+
stderr: "",
|
|
8452
|
+
termination: "exited"
|
|
8453
|
+
}
|
|
8454
|
+
},
|
|
8622
8455
|
{
|
|
8623
8456
|
id: "javascript-wasip1",
|
|
8624
8457
|
label: "JavaScript / wasip1",
|
|
@@ -8968,11 +8801,15 @@ var CPP_STDLIB_CONFORMANCE_CASE = deepFreeze({
|
|
|
8968
8801
|
termination: "exited"
|
|
8969
8802
|
}
|
|
8970
8803
|
});
|
|
8971
|
-
var FULL_CONFORMANCE_CASES = deepFreeze([
|
|
8804
|
+
var FULL_CONFORMANCE_CASES = deepFreeze([
|
|
8805
|
+
...DEFAULT_CONFORMANCE_CASES,
|
|
8806
|
+
...STDIO_CONFORMANCE_CASES,
|
|
8807
|
+
CPP_STDLIB_CONFORMANCE_CASE
|
|
8808
|
+
]);
|
|
8972
8809
|
function deepFreeze(value) {
|
|
8973
8810
|
if (typeof value !== "object" || value === null || Object.isFrozen(value)) return value;
|
|
8974
8811
|
for (const child of Object.values(value)) deepFreeze(child);
|
|
8975
8812
|
return Object.freeze(value);
|
|
8976
8813
|
}
|
|
8977
8814
|
//#endregion
|
|
8978
|
-
export { BROWSER_COLLECTION_SCHEMA, BROWSER_PROBLEM_SCHEMA, BrowserDependencyNetworkConsent, CONTEST_PUBLIC_PROJECTION_SCHEMA, CPP_STDLIB_CONFORMANCE_CASE, CargoLockDependencyResolver, CompilerRegistry, CostBaselineRegistry, CppLockDependencyResolver, DEFAULT_CONFORMANCE_CASES, DEFAULT_DETERMINISM, DEFAULT_RESOURCE_POLICY, DEPENDENCY_BUILD_LIMITS, DependencyManager, DependencyNetworkError, Engine, FULL_CONFORMANCE_CASES, GoLockDependencyResolver, JudgeEngine, LANGUAGES,
|
|
8815
|
+
export { BROWSER_COLLECTION_SCHEMA, BROWSER_PROBLEM_SCHEMA, BrowserDependencyNetworkConsent, CONTEST_PUBLIC_PROJECTION_SCHEMA, CPP_STDLIB_CONFORMANCE_CASE, CargoLockDependencyResolver, CompilerRegistry, CostBaselineRegistry, CppLockDependencyResolver, DEFAULT_CONFORMANCE_CASES, DEFAULT_DETERMINISM, DEFAULT_RESOURCE_POLICY, DEPENDENCY_BUILD_LIMITS, DependencyManager, DependencyNetworkError, Engine, FULL_CONFORMANCE_CASES, GoLockDependencyResolver, JudgeEngine, LANGUAGES, MemoryDependencyCache, NpmLockDependencyResolver, PROBLEM_STARTER_LIMITS, PROJECT_SOURCE_LIMITS, PyPiLockDependencyResolver, REPOSITORY_AUTHORING_JUDGES_SCHEMA, RuntimeDriverRegistry, TRUSTED_JUDGE_RUNTIME_PROFILES, TRUSTED_JUDGE_WASIP1_IMPORTS, TRUSTED_JUDGE_WASM_MAX_BYTES, WASM_OJ_CONTRACT_ID, WASM_OJ_CONTRACT_VERSION, WASM_OJ_ERROR_CODES, WASM_OJ_ERROR_STAGES, WASM_OJ_JUDGE_DATA_SCHEMA, WASM_OJ_JUDGE_PACKAGE_MAGIC, WASM_OJ_JUDGE_PACKAGE_MAX_BYTES, WASM_OJ_JUDGE_PACKAGE_SCHEMA, WASM_OJ_LIBCXX_PCH_HEADER, WASM_OJ_RUNTIME_COMPONENTS, WASM_OJ_RUNTIME_IDENTITY_SHA256, WASM_OJ_SCHEMAS, WASM_OJ_STORAGE, WEIGHTED_METER_MODEL, WasmOjError, asWasmOjError, assertCompilerCacheKey, assertJudgeDataCostProfile, assertJudgeDataMatchesPracticePublic, assertJudgeGuestFilePath, assertLanguageIdentifier, assertProblemCostProfile, assertValidBuildArtifact, assertValidDependencyBuildBundle, assertValidDependencyLock, assertValidProject, assertValidReplayBundle, browserToolchainAssetBaseUrl, browserToolchainAssetUrl, canonicalJsonBytes, compareConformanceSnapshots, contestPublicProjectionBytes, costProfileId, createContestPublicProjection, createDefaultCostBaselineRegistry, createDefaultDependencyBuildAdapters, createDefaultDependencyManager, createDefaultDependencyResolvers, createDefaultRuntimeDrivers, createDependencyBuildBundle, createDependencyLock, createEngine, createExtendedCostBaselineRegistry, createJudgeExecutor, createReplayBundle, createRuntimeBundleManifest, createSdkProject, decodeJudgePackageForExecution, decodeLibcxxPchManifest, decodeReplayBundle, dependencyFileTreeSha256, dependencyLockSha256, dependencyManifestSha256, deriveContestPublic, deriveJudgeData, derivePracticePublic, deterministicTranscript, encodeJudgePackage, encodeReplayBundle, fileMatcher, floatMatcher, goModuleZipHash, isBuiltinLanguage, isCostProfileFor, isToolchainLibcxxPchHeader, judgePackageSemanticDigest, judgeTranscript, normalizeDependencyNetworkAccess, normalizeDependencyNetworkScope, normalizeExecutionMetrics, normalizeOutput, parseCanonicalJsonBytes, parseJudgeAllowedProfiles, parseJudgeData, parseJudgePackageManifest, parseProblemBundle, parseProblemCollectionIndex, parseRepositoryAuthoringJudges, parseStandaloneProblemBundle, prepareArtifactInteraction, prepareArtifactRun, prepareTrustedJudgeRun, problemCollectionRevision, readJudgePackageManifest, replayBundle, replayBundleSha256, resolveArtifactCostBudget, resolveCostBudget, resolveDeterminism, resolveResourcePolicy, runConformanceHost, runConformanceMatrix, runtimeIdentityBytes, scoreJudgeDataResults, scoreProblemResults, setMatcher, sha256Matcher, snapshotBrowserToolchainSources, summarizeProblemPolicies, textMatcher, tokenMatcher, toolchainAssetSource, toolchainCacheIdentity, toolchainProfileSource, trustedJudgeSpec, unavailableExecutionMetrics, validateBrowserToolchainSources, validateJudgePackage, validateJudgeSpec, validateServerToolchainSources, validateToolchainDescriptors, validateTrustedJudgeWasm, verifyDependencyBuildBundle, verifyProblemBundleBytes, verifyProblemCollectionRevision, verifyRuntimeIdentity, wasmCheckerMatcher };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wasm-oj/core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Host-neutral compiler, runner, judge, dependency, and replay orchestration for WASM-OJ.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "JacobLinCool",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"node": ">=24.18.0 <25"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@wasm-oj/contracts": "0.2.
|
|
46
|
+
"@wasm-oj/contracts": "0.2.1",
|
|
47
47
|
"fflate": "0.8.3"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|