mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-26 17:01:20 -08:00
build(site): [SITE-07] deliver original Monaco language service notices
This commit is contained in:
1 parent
0d3ddbf355
commit
11c9fefadd
42 files changed
+3141
-19
No files matched your search
@@ -80,9 +80,26 @@ disposes both workers and models. Monaco 0.30.1 has no public CSS/HTML/JSON work
|
||||
getter equivalent to `getTypeScriptWorker`. Tests exercise valid/invalid CSS and
|
||||
JSON, HTML tag completion, document symbols, and HTML/JSON formatting on three engines.
|
||||
|
||||
This source checkpoint does not close embedded license review. Follow up with the
|
||||
seven packages' original licenses/third-party notices, including HTML beautifiers
|
||||
and data sources. Core embedded libraries, mode bundles and language definitions
|
||||
also remain under VENDOR-06. Revalidate editor-types and site-vendor tests when
|
||||
changing declarations or delivered notices. Whole-site, physical-device and remote
|
||||
release gates remain separate.
|
||||
## Language-service notices
|
||||
|
||||
`monaco-language-notices.json` binds seven verified package versions to their nine
|
||||
complete original LICENSE/third-party notice files. Two exact source-comment slices
|
||||
preserve the HTML service's CSS/HTML beautifier MIT notices, 2007-2018 author years
|
||||
and formatter authors. The package's older 2007-2017 text remains verbatim. A local
|
||||
attribution explains this difference and the JSON service's original glob-to-regexp
|
||||
BSD conditions; neither component is relabeled as solely Microsoft's MIT code.
|
||||
The separate `beautify.js` source is Microsoft's no-op JS formatting adapter.
|
||||
|
||||
`notices.ts` binds the nine component entries (seven packages plus two embedded
|
||||
origins) to their exact worker paths and delivered notices. The normal site build
|
||||
checks these associations before any output write. Full reproduction additionally
|
||||
matches all 12 notice inputs against their archived files or exact header byte
|
||||
ranges. Preserve raw bytes and the `-text` Git attributes for frozen/output notices.
|
||||
`site-vendor.spec.js` checks all 81 site notice files over HTTP plus the supplement's
|
||||
12 relative links, alongside mobile player playback and console cleanup.
|
||||
|
||||
This does not close all Monaco embedded-source review. Core embedded libraries,
|
||||
mode bundles, language definitions and remaining upstream data/origin details stay
|
||||
under VENDOR-06. Revalidate editor-types and site-vendor tests when changing
|
||||
declarations or delivered notices. Whole-site, physical-device and remote release
|
||||
gates remain separate.
|
||||
@@ -0,0 +1,80 @@
|
||||
import type { VendorManifest } from '../notices.ts'
|
||||
import type { ArchiveCache, Member } from './archives.ts'
|
||||
import assert from 'node:assert/strict'
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { hash } from './archives.ts'
|
||||
|
||||
interface Notice {
|
||||
source: string
|
||||
target: string
|
||||
sha256: string
|
||||
archive?: string
|
||||
member?: string
|
||||
memberSha256?: string
|
||||
slice?: { start: number, end: number }
|
||||
}
|
||||
interface Component { name: string, version: string, tarball: string, assets: string[], notices: string[] }
|
||||
interface NoticeRecord { packages: (Component & { archive: string })[], components: Component[], notices: Notice[] }
|
||||
interface Sources {
|
||||
archives: { name: string, version: string, tarball: string }[]
|
||||
modules: (Member & { id: string })[]
|
||||
workers: { ids: string[], target: { path: string } }[]
|
||||
}
|
||||
function readNotices(root: string): NoticeRecord {
|
||||
return JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/monaco-language-notices.json'), 'utf8'))
|
||||
}
|
||||
|
||||
// Cheap build-time binding checks; do not download or execute archived code.
|
||||
export function verifyMonacoLanguageNotices(root: string, manifest: VendorManifest): number {
|
||||
const record = readNotices(root)
|
||||
const sources: Sources = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/monaco-languages-provenance.json'), 'utf8'))
|
||||
assert.equal(record.notices.length, 12, 'Missing Monaco language notice source')
|
||||
assert.equal(record.components.length, 9, 'Missing Monaco language component source')
|
||||
assert.deepEqual(record.packages.map(item => item.name).sort(), [...new Set(sources.modules.map(item => item.id.split('/')[0]))].sort(), 'Incomplete Monaco service attribution')
|
||||
const group = manifest.groups.find(group => group.name === 'monaco-editor')
|
||||
assert(group?.components, 'Missing Monaco group')
|
||||
for (const pkg of record.packages) {
|
||||
const archive = sources.archives.find(item => `${item.name}-${item.version}` === pkg.archive)
|
||||
assert(archive && archive.name === pkg.name && archive.version === pkg.version && archive.tarball === pkg.tarball, 'Wrong Monaco service source identity')
|
||||
const modules = sources.modules.filter(item => item.archive === pkg.archive).map(item => item.id)
|
||||
const assets = sources.workers.filter(worker => worker.ids.some(id => modules.includes(id))).map(worker => worker.target.path)
|
||||
assert.deepEqual(pkg.assets, assets, 'Wrong Monaco service asset binding')
|
||||
}
|
||||
for (const expected of record.components) {
|
||||
const matches: Component[] = group.components.filter(item => item.name === expected.name)
|
||||
assert.equal(matches.length, 1, `Missing Monaco language component: ${expected.name}`)
|
||||
const actual = matches[0]!
|
||||
assert.equal(actual.version, expected.version, 'Wrong Monaco language version')
|
||||
assert.equal(actual.tarball, expected.tarball, 'Wrong Monaco language source')
|
||||
assert.deepEqual([...actual.assets].sort(), [...expected.assets].sort(), 'Wrong Monaco language asset')
|
||||
assert.deepEqual([...actual.notices].sort(), [...expected.notices].sort(), `Wrong Monaco language notice binding: ${expected.name}`)
|
||||
}
|
||||
for (const expected of record.notices) {
|
||||
const matches: Notice[] = group.notices.filter(item => item.target === expected.target)
|
||||
assert.equal(matches.length, 1, `Missing Monaco language notice: ${expected.target}`)
|
||||
assert.equal(matches[0]!.source, expected.source, 'Wrong Monaco language notice source')
|
||||
assert.equal(matches[0]!.sha256, expected.sha256, 'Wrong Monaco language notice fingerprint')
|
||||
}
|
||||
return record.notices.length
|
||||
}
|
||||
|
||||
// The source reproducer additionally proves the complete original files and the
|
||||
// exact byte slices of embedded formatter headers against verified archives.
|
||||
export function verifyMonacoLanguageNoticeArchives(root: string, cache: ArchiveCache): number {
|
||||
const record = readNotices(root)
|
||||
for (const notice of record.notices) {
|
||||
const local = fs.readFileSync(path.join(root, notice.source))
|
||||
assert.equal(hash(local), notice.sha256, 'Monaco language notice text changed')
|
||||
if (notice.archive && notice.member) {
|
||||
let upstream = cache.read(notice.archive, notice.member)
|
||||
if (notice.slice) {
|
||||
assert.equal(hash(upstream), notice.memberSha256, 'Monaco embedded header source changed')
|
||||
assert(notice.slice.start >= 0 && notice.slice.end > notice.slice.start && notice.slice.end <= upstream.length, 'Invalid Monaco header boundary')
|
||||
upstream = upstream.subarray(notice.slice.start, notice.slice.end)
|
||||
}
|
||||
assert(local.equals(upstream), 'Monaco language notice differs from archive')
|
||||
}
|
||||
}
|
||||
return record.notices.length
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { ArchiveCache, hash } from './archives.ts'
|
||||
import { aliasModule, languageHeader, nameModule, verifyWorkerSources } from './languages.ts'
|
||||
import { verifyMonacoLanguageNoticeArchives } from './notices.ts'
|
||||
|
||||
interface Provenance {
|
||||
archives: Archive[]
|
||||
@@ -46,6 +47,7 @@ for (const member of record.modules) {
|
||||
}
|
||||
const cache = new ArchiveCache(root, path.join(root, 'refactor/.cache/monaco-review'))
|
||||
await cache.verify(record.archives, record.remotes, process.argv.includes('--fetch'))
|
||||
const notices = verifyMonacoLanguageNoticeArchives(root, cache)
|
||||
for (const name of ['typescript', 'terser', 'source-map']) {
|
||||
const archive = record.archives.find(item => item.name === name)
|
||||
assert(archive, 'Missing historical compiler dependency')
|
||||
@@ -115,4 +117,4 @@ for (const worker of record.workers) {
|
||||
assert.equal(languageHeader(worker.language) + code, target.toString('utf8'), 'Minified language worker differs')
|
||||
results.push({ language: worker.language, modules: worker.ids.length, exactSources: true, exactWorker: true, sha256: hash(target) })
|
||||
}
|
||||
console.log(JSON.stringify({ archives: record.archives.length, gitSources: record.remotes.length, npmModules: modules.size, aliases: aliases.size, workers: results, licenseReviewComplete: false, otherMonacoComponentsReviewed: false }))
|
||||
console.log(JSON.stringify({ archives: record.archives.length, gitSources: record.remotes.length, npmModules: modules.size, aliases: aliases.size, workers: results, notices, licenseReviewComplete: false, otherMonacoComponentsReviewed: false }))
|
||||
Reference in new issue
Block a user