fix: no .map
fix: no map
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
*.map
|
||||||
@@ -16,7 +16,8 @@
|
|||||||
"./package.json": "./package.json"
|
"./package.json": "./package.json"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist",
|
||||||
|
"!dist/**/*.map"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
|
|||||||
@@ -45,9 +45,7 @@
|
|||||||
"lib/typert.host.js",
|
"lib/typert.host.js",
|
||||||
"lib/typert.host.d.ts",
|
"lib/typert.host.d.ts",
|
||||||
"lib/typert.remote-client.js",
|
"lib/typert.remote-client.js",
|
||||||
"lib/typert.remote-client.d.ts",
|
"lib/typert.remote-client.d.ts"
|
||||||
"lib/typert.remote-client.d.ts.map",
|
|
||||||
"src"
|
|
||||||
],
|
],
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
|||||||
@@ -49,9 +49,7 @@
|
|||||||
"lib/typert.host.js",
|
"lib/typert.host.js",
|
||||||
"lib/typert.host.d.ts",
|
"lib/typert.host.d.ts",
|
||||||
"lib/typert.remote-client.js",
|
"lib/typert.remote-client.js",
|
||||||
"lib/typert.remote-client.d.ts",
|
"lib/typert.remote-client.d.ts"
|
||||||
"lib/typert.remote-client.d.ts.map",
|
|
||||||
"src"
|
|
||||||
],
|
],
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
|||||||
@@ -49,8 +49,7 @@
|
|||||||
"lib/typert.host.js",
|
"lib/typert.host.js",
|
||||||
"lib/typert.host.d.ts",
|
"lib/typert.host.d.ts",
|
||||||
"lib/typert.remote-client.js",
|
"lib/typert.remote-client.js",
|
||||||
"lib/typert.remote-client.d.ts",
|
"lib/typert.remote-client.d.ts"
|
||||||
"lib/typert.remote-client.d.ts.map"
|
|
||||||
],
|
],
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
|||||||
@@ -98,10 +98,12 @@ export class WorkspaceTypertGenerator {
|
|||||||
const remoteActual = manifest.exports !== null && typeof manifest.exports === 'object'
|
const remoteActual = manifest.exports !== null && typeof manifest.exports === 'object'
|
||||||
? (manifest.exports as Record<string, unknown>)['./remote']
|
? (manifest.exports as Record<string, unknown>)['./remote']
|
||||||
: undefined
|
: undefined
|
||||||
|
// The declaration map is emitted beside these two but never published: it
|
||||||
|
// serves editor navigation in the workspace, where the package link
|
||||||
|
// resolves its source.
|
||||||
const remoteFiles = [
|
const remoteFiles = [
|
||||||
'lib/typert.remote-client.js',
|
'lib/typert.remote-client.js',
|
||||||
'lib/typert.remote-client.d.ts',
|
'lib/typert.remote-client.d.ts',
|
||||||
'lib/typert.remote-client.d.ts.map',
|
|
||||||
]
|
]
|
||||||
if (artifact.remote === undefined) {
|
if (artifact.remote === undefined) {
|
||||||
if (remoteActual !== undefined || remoteFiles.some(file => files.includes(file))) {
|
if (remoteActual !== undefined || remoteFiles.some(file => files.includes(file))) {
|
||||||
|
|||||||
+1
-2
@@ -18,7 +18,6 @@
|
|||||||
"lib/typert.host.js",
|
"lib/typert.host.js",
|
||||||
"lib/typert.host.d.ts",
|
"lib/typert.host.d.ts",
|
||||||
"lib/typert.remote-client.js",
|
"lib/typert.remote-client.js",
|
||||||
"lib/typert.remote-client.d.ts",
|
"lib/typert.remote-client.d.ts"
|
||||||
"lib/typert.remote-client.d.ts.map"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,9 @@ const releaseMemberDirectory = /^(?:packages\/[^/]+\/[^/]+|apps\/[^/]+|vendor\/[
|
|||||||
const localArtifactDirs = new Set(['node_modules'])
|
const localArtifactDirs = new Set(['node_modules'])
|
||||||
const appPackageFiles: Readonly<Record<string, readonly string[]>> = {
|
const appPackageFiles: Readonly<Record<string, readonly string[]>> = {
|
||||||
'@deepseek-ai/dsh': ['lib/*.js', 'config'],
|
'@deepseek-ai/dsh': ['lib/*.js', 'config'],
|
||||||
'@deepseek-ai/dsh-frontend': ['dist'],
|
// The Web build emits sourcemaps for browser debugging; publishing them is
|
||||||
|
// what the payload policy forbids, so the bundle ships without them.
|
||||||
|
'@deepseek-ai/dsh-frontend': ['dist', '!dist/**/*.map'],
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The subset of package.json fields this constraint check cares about. */
|
/** The subset of package.json fields this constraint check cares about. */
|
||||||
@@ -152,7 +154,6 @@ function sameStringList(actual: readonly string[] | undefined, expected: readonl
|
|||||||
|
|
||||||
function expectedDshPackageFiles(manifest: PackageManifest): readonly string[] {
|
function expectedDshPackageFiles(manifest: PackageManifest): readonly string[] {
|
||||||
const extras = manifest.name ? packageFileExtras[manifest.name] ?? [] : []
|
const extras = manifest.name ? packageFileExtras[manifest.name] ?? [] : []
|
||||||
const typeRTRemoteNavigation = hasTypeRTRemoteNavigation(manifest)
|
|
||||||
return [
|
return [
|
||||||
'lib/index.js',
|
'lib/index.js',
|
||||||
// Every package publishes its invariant ownership companion as a separate
|
// Every package publishes its invariant ownership companion as a separate
|
||||||
@@ -185,13 +186,8 @@ function expectedDshPackageFiles(manifest: PackageManifest): readonly string[] {
|
|||||||
...hasExportPair(manifest, './client/typert', './lib/typert.client.d.ts', './lib/typert.client.js')
|
...hasExportPair(manifest, './client/typert', './lib/typert.client.d.ts', './lib/typert.client.js')
|
||||||
? ['lib/typert.client.js', 'lib/typert.client.d.ts']
|
? ['lib/typert.client.js', 'lib/typert.client.d.ts']
|
||||||
: [],
|
: [],
|
||||||
...typeRTRemoteNavigation
|
...hasTypeRTRemoteNavigation(manifest)
|
||||||
? [
|
? ['lib/typert.remote-client.js', 'lib/typert.remote-client.d.ts']
|
||||||
'lib/typert.remote-client.js',
|
|
||||||
'lib/typert.remote-client.d.ts',
|
|
||||||
'lib/typert.remote-client.d.ts.map',
|
|
||||||
'src',
|
|
||||||
]
|
|
||||||
: [],
|
: [],
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -270,9 +266,8 @@ function checkWorkspace({ dir, manifest }: WorkspaceManifest): string[] {
|
|||||||
|
|
||||||
if (manifest.name?.startsWith('@deepseek-ai/')) {
|
if (manifest.name?.startsWith('@deepseek-ai/')) {
|
||||||
const allowedSources = publicationSourceAllowlist[manifest.name] ?? []
|
const allowedSources = publicationSourceAllowlist[manifest.name] ?? []
|
||||||
const publicationPolicy = { typeRTRemoteNavigation: hasTypeRTRemoteNavigation(manifest) }
|
|
||||||
for (const file of manifest.files ?? []) {
|
for (const file of manifest.files ?? []) {
|
||||||
if (isForbiddenPublicationFile(file, publicationPolicy) && !allowedSources.includes(file)) {
|
if (isForbiddenPublicationFile(file) && !allowedSources.includes(file)) {
|
||||||
errors.push(`${label}: package.json files must not publish ${JSON.stringify(file)}`)
|
errors.push(`${label}: package.json files must not publish ${JSON.stringify(file)}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ describe('publication payload policy', () => {
|
|||||||
String.raw`src\index.ts`,
|
String.raw`src\index.ts`,
|
||||||
'lib/types/index.d.ts.map',
|
'lib/types/index.d.ts.map',
|
||||||
'./lib/types/index.d.ts.map',
|
'./lib/types/index.d.ts.map',
|
||||||
|
'lib/typert.remote-client.d.ts.map',
|
||||||
|
'lib/client.js.map',
|
||||||
|
'./lib/client.js.map',
|
||||||
])('rejects static manifest path %s', (file) => {
|
])('rejects static manifest path %s', (file) => {
|
||||||
expect(isForbiddenPublicationFile(file)).toBe(true)
|
expect(isForbiddenPublicationFile(file)).toBe(true)
|
||||||
})
|
})
|
||||||
@@ -40,11 +43,19 @@ describe('publication payload policy', () => {
|
|||||||
])).toThrow('fixture.tgz publishes source file package/src/index.ts')
|
])).toThrow('fixture.tgz publishes source file package/src/index.ts')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('rejects declaration maps in packed tarballs', () => {
|
it('rejects source maps in packed tarballs', () => {
|
||||||
expect(validateFixtureTarball([
|
expect(validateFixtureTarball([
|
||||||
'package/package.json',
|
'package/package.json',
|
||||||
'package/lib/types/index.d.ts.map',
|
'package/lib/types/index.d.ts.map',
|
||||||
])).toThrow('fixture.tgz publishes declaration map package/lib/types/index.d.ts.map')
|
])).toThrow('fixture.tgz publishes source map package/lib/types/index.d.ts.map')
|
||||||
|
expect(validateFixtureTarball([
|
||||||
|
'package/package.json',
|
||||||
|
'package/lib/typert.remote-client.d.ts.map',
|
||||||
|
])).toThrow('fixture.tgz publishes source map package/lib/typert.remote-client.d.ts.map')
|
||||||
|
expect(validateFixtureTarball([
|
||||||
|
'package/package.json',
|
||||||
|
'package/lib/client.js.map',
|
||||||
|
])).toThrow('fixture.tgz publishes source map package/lib/client.js.map')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('accepts a clean packed tarball', () => {
|
it('accepts a clean packed tarball', () => {
|
||||||
@@ -56,19 +67,6 @@ describe('publication payload policy', () => {
|
|||||||
])).not.toThrow()
|
])).not.toThrow()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('allows only the TypeRT declaration map and its navigable source tree when requested', () => {
|
|
||||||
const policy = { typeRTRemoteNavigation: true }
|
|
||||||
expect(isForbiddenPublicationFile('src/index.ts', policy)).toBe(false)
|
|
||||||
expect(isForbiddenPublicationFile('lib/typert.remote-client.d.ts.map', policy)).toBe(false)
|
|
||||||
expect(isForbiddenPublicationFile('lib/types/index.d.ts.map', policy)).toBe(true)
|
|
||||||
expect(() => {
|
|
||||||
validateTarballPayload([
|
|
||||||
'package/lib/typert.remote-client.d.ts.map',
|
|
||||||
'package/src/index.ts',
|
|
||||||
], 'fixture.tgz', policy)
|
|
||||||
}).not.toThrow()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('recognizes only the canonical Host-for-Client export pair', () => {
|
it('recognizes only the canonical Host-for-Client export pair', () => {
|
||||||
expect(hasTypeRTRemoteNavigation({
|
expect(hasTypeRTRemoteNavigation({
|
||||||
exports: {
|
exports: {
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
/** Publication payload policy shared by static manifests and packed tarballs. */
|
/** Publication payload policy shared by static manifests and packed tarballs. */
|
||||||
|
|
||||||
/** Publication exceptions required for TypeRT declaration-map navigation. */
|
/**
|
||||||
export interface PublicationPayloadPolicy {
|
* Whether a package manifest exports generated Host-for-Client metadata.
|
||||||
readonly typeRTRemoteNavigation?: boolean
|
* @param manifest - parsed package manifest to inspect.
|
||||||
}
|
* @returns whether the canonical `./remote` export pair is present.
|
||||||
|
*/
|
||||||
/** Whether a package manifest exports generated Host-for-Client metadata with source navigation. */
|
|
||||||
export function hasTypeRTRemoteNavigation(manifest: unknown): boolean {
|
export function hasTypeRTRemoteNavigation(manifest: unknown): boolean {
|
||||||
if (manifest === null || typeof manifest !== 'object' || Array.isArray(manifest)) return false
|
if (manifest === null || typeof manifest !== 'object' || Array.isArray(manifest)) return false
|
||||||
const exportsField = (manifest as Record<string, unknown>).exports
|
const exportsField = (manifest as Record<string, unknown>).exports
|
||||||
@@ -23,35 +22,34 @@ function payloadPath(file: string): string {
|
|||||||
return normalized.startsWith('package/') ? normalized.slice('package/'.length) : normalized
|
return normalized.startsWith('package/') ? normalized.slice('package/'.length) : normalized
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether a package payload path exposes source or declaration-map intermediates. */
|
/**
|
||||||
export function isForbiddenPublicationFile(
|
* Whether a package payload path exposes source or map intermediates. Maps
|
||||||
file: string,
|
* serve editor navigation during development, where a workspace consumer
|
||||||
policy: PublicationPayloadPolicy = {},
|
* resolves their source through the package link; a published map resolves
|
||||||
): boolean {
|
* nothing, so no payload publishes one.
|
||||||
|
* @param file - manifest path or tarball member to classify.
|
||||||
|
* @returns whether publishing this path is forbidden.
|
||||||
|
*/
|
||||||
|
export function isForbiddenPublicationFile(file: string): boolean {
|
||||||
const normalized = payloadPath(file)
|
const normalized = payloadPath(file)
|
||||||
if (policy.typeRTRemoteNavigation === true
|
|
||||||
&& (normalized === 'src'
|
|
||||||
|| normalized.startsWith('src/')
|
|
||||||
|| normalized === 'lib/typert.remote-client.d.ts.map')) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return normalized === 'src'
|
return normalized === 'src'
|
||||||
|| normalized.startsWith('src/')
|
|| normalized.startsWith('src/')
|
||||||
|| normalized.endsWith('.d.ts.map')
|
|| normalized.endsWith('.d.ts.map')
|
||||||
|
|| normalized.endsWith('.js.map')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reject source and declaration-map members in a packed npm tarball. */
|
/**
|
||||||
export function validateTarballPayload(
|
* Reject source and map members in a packed npm tarball.
|
||||||
files: readonly string[],
|
* @param files - tarball members to validate.
|
||||||
context: string,
|
* @param context - tarball identity named in the failure.
|
||||||
policy: PublicationPayloadPolicy = {},
|
*/
|
||||||
): void {
|
export function validateTarballPayload(files: readonly string[], context: string): void {
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
if (!isForbiddenPublicationFile(file, policy)) continue
|
if (!isForbiddenPublicationFile(file)) continue
|
||||||
const normalized = payloadPath(file)
|
const normalized = payloadPath(file)
|
||||||
if (normalized === 'src' || normalized.startsWith('src/')) {
|
if (normalized === 'src' || normalized.startsWith('src/')) {
|
||||||
throw new Error(`${context} publishes source file ${file}`)
|
throw new Error(`${context} publishes source file ${file}`)
|
||||||
}
|
}
|
||||||
throw new Error(`${context} publishes declaration map ${file}`)
|
throw new Error(`${context} publishes source map ${file}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,7 @@ import { basename, dirname, isAbsolute, join, normalize, relative, resolve, sep
|
|||||||
import { createInterface } from 'node:readline/promises'
|
import { createInterface } from 'node:readline/promises'
|
||||||
import { pathToFileURL } from 'node:url'
|
import { pathToFileURL } from 'node:url'
|
||||||
import { parseArgs } from 'node:util'
|
import { parseArgs } from 'node:util'
|
||||||
import { hasTypeRTRemoteNavigation, validateTarballPayload } from './publication-payload.ts'
|
import { validateTarballPayload } from './publication-payload.ts'
|
||||||
|
|
||||||
const DEFAULT_REGISTRY = 'https://registry.npm.harnessment.com'
|
const DEFAULT_REGISTRY = 'https://registry.npm.harnessment.com'
|
||||||
const DEFAULT_OUTPUT_DIRECTORY = '.artifacts/npm-baseline'
|
const DEFAULT_OUTPUT_DIRECTORY = '.artifacts/npm-baseline'
|
||||||
@@ -323,9 +323,7 @@ class ReleaseBundle {
|
|||||||
throw new Error(`unexpected or duplicate packed package: ${artifact.name}`)
|
throw new Error(`unexpected or duplicate packed package: ${artifact.name}`)
|
||||||
}
|
}
|
||||||
if (expected.origin === 'harness') {
|
if (expected.origin === 'harness') {
|
||||||
validateTarballPayload(artifact.files, tarball, {
|
validateTarballPayload(artifact.files, tarball)
|
||||||
typeRTRemoteNavigation: hasTypeRTRemoteNavigation(artifact.manifest),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
if (artifact.version !== version) {
|
if (artifact.version !== version) {
|
||||||
throw new Error(`${tarball} has version ${artifact.version}; expected ${version}`)
|
throw new Error(`${tarball} has version ${artifact.version}; expected ${version}`)
|
||||||
@@ -401,9 +399,7 @@ class ReleaseBundle {
|
|||||||
}
|
}
|
||||||
const artifact = inspectTarball(path, runner)
|
const artifact = inspectTarball(path, runner)
|
||||||
if (pkg.origin === 'harness') {
|
if (pkg.origin === 'harness') {
|
||||||
validateTarballPayload(artifact.files, pkg.tarball, {
|
validateTarballPayload(artifact.files, pkg.tarball)
|
||||||
typeRTRemoteNavigation: hasTypeRTRemoteNavigation(artifact.manifest),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
if (artifact.name !== pkg.name || artifact.version !== this.manifest.version) {
|
if (artifact.name !== pkg.name || artifact.version !== this.manifest.version) {
|
||||||
throw new Error(`tarball identity mismatch: ${pkg.tarball}`)
|
throw new Error(`tarball identity mismatch: ${pkg.tarball}`)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
import { globSync, readFileSync } from 'node:fs'
|
import { globSync, readFileSync } from 'node:fs'
|
||||||
import { resolve } from 'node:path'
|
import { resolve } from 'node:path'
|
||||||
import { hasTypeRTRemoteNavigation, validateTarballPayload } from '../publication-payload.ts'
|
import { validateTarballPayload } from '../publication-payload.ts'
|
||||||
|
|
||||||
/** Dependency sections that constrain publish order: a consumer must publish after its dependency. */
|
/** Dependency sections that constrain publish order: a consumer must publish after its dependency. */
|
||||||
const ORDER_SECTIONS = ['dependencies', 'optionalDependencies'] as const
|
const ORDER_SECTIONS = ['dependencies', 'optionalDependencies'] as const
|
||||||
@@ -225,9 +225,7 @@ class DshFamily extends ReleaseFamily {
|
|||||||
* @param files - every path inside its tarball.
|
* @param files - every path inside its tarball.
|
||||||
*/
|
*/
|
||||||
validatePayload(member: ReleaseMember, files: readonly string[]): void {
|
validatePayload(member: ReleaseMember, files: readonly string[]): void {
|
||||||
validateTarballPayload(files, member.name, {
|
validateTarballPayload(files, member.name)
|
||||||
typeRTRemoteNavigation: hasTypeRTRemoteNavigation(member.manifest),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly installedEntry = { packageName: '@deepseek-ai/dsh', binPath: 'lib/bin.js' }
|
readonly installedEntry = { packageName: '@deepseek-ai/dsh', binPath: 'lib/bin.js' }
|
||||||
|
|||||||
Reference in New Issue
Block a user