Ctrl K
ComunidadGuías…

app/scripts/package-proof.mjs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import assert from 'node:assert/strict'
import { spawn, execFileSync } from 'node:child_process'
import { assertPublicPaths } from '../../scripts/validate-public-files.mjs'
import { createHash } from 'node:crypto'
import {
  copyFileSync,
  lstatSync,
  existsSync,
  mkdirSync,
  mkdtempSync,
  readdirSync,
  readFileSync,
  realpathSync,
  writeFileSync,
} from 'node:fs'
import { tmpdir } from 'node:os'
import { dirname, join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'

const app = resolve(dirname(fileURLToPath(import.meta.url)), '..')
const directory = mkdtempSync(join(tmpdir(), 'devpush-package-'))
const logs = resolve(directory, 'logs')
mkdirSync(logs)
const metadata = JSON.parse(readFileSync(resolve(app, 'package.json')))
// No developer app credentials, deployment aliases or local .env files enter the fixture.
const environment = Object.fromEntries(
  ['PATH', 'HOME', 'USER', 'TMPDIR'].flatMap((key) =>
    process.env[key] ? [[key, process.env[key]]] : [],
  ),
)
environment.NO_COLOR = '1'
environment.DEVPUSH_SMOKE_PLUGINS = '1'
console.log(`Independent package consumer: ${directory}`)
async function run(
  name,
  command,
  args,
  cwd = directory,
  extra = {},
  expectedError,
) {
  console.log(name)
  const output = []
  const child = spawn(command, args, {
    cwd,
    env: { ...environment, ...extra },
    stdio: ['ignore', 'pipe', 'pipe'],
  })
  child.stdout.on('data', (chunk) => output.push(chunk))
  child.stderr.on('data', (chunk) => output.push(chunk))
  const code = await new Promise((resolve, reject) => {
    child.once('error', reject)
    child.once('exit', resolve)
  })
  const text = Buffer.concat(output).toString()
  writeFileSync(resolve(logs, `${name}.log`), text)
  if (expectedError) {
    assert.notEqual(code, 0, `${name} unexpectedly succeeded`)
    assert(
      text.includes(expectedError),
      `${name} failed for another reason:\n${text.slice(-12000)}`,
    )
  } else assert.equal(code, 0, `${name} failed:\n${text.slice(-12000)}`)
}
function digest(path) {
  const hash = createHash('sha256')
  function visit(directory) {
    for (const name of readdirSync(directory).sort()) {
      const entry = join(directory, name)
      if (lstatSync(entry).isDirectory()) visit(entry)
      else hash.update(entry.slice(path.length)).update(readFileSync(entry))
    }
  }
  visit(path)
  return hash.digest('hex')
}
function assertApplicationNotOptimized() {
  const cache = resolve(directory, 'node_modules/.vite')
  if (!existsSync(cache)) return
  const source = realpathSync(resolve(directory, 'node_modules/devpush/src'))
  for (const name of readdirSync(cache)) {
    const metadataPath = resolve(cache, name, '_metadata.json')
    if (!existsSync(metadataPath)) continue
    const metadata = JSON.parse(readFileSync(metadataPath, 'utf8'))
    for (const [id, entry] of Object.entries(metadata.optimized ?? {})) {
      const file = resolve(dirname(metadataPath), entry.src)
      if (existsSync(file))
        assert(
          !realpathSync(file).startsWith(source + '/'),
          `Application module was prebundled: ${id}`,
        )
    }
  }
}
function assertClientBoundary(path) {
  let javascript = ''
  function visit(directory) {
    for (const entry of readdirSync(directory, { withFileTypes: true })) {
      const file = resolve(directory, entry.name)
      if (entry.isDirectory()) visit(file)
      else if (entry.name.endsWith('.js'))
        javascript += readFileSync(file, 'utf8')
    }
  }
  visit(path)
  for (const id of ['local-proof', 'npm-proof']) {
    assert(
      javascript.includes('CLIENT_ONLY_' + id),
      `Missing client plugin: ${id}`,
    )
    assert(
      !javascript.includes('SERVER_ONLY_' + id),
      `Server plugin leaked into client: ${id}`,
    )
  }
}
await run('pack', 'pnpm', ['pack', '--pack-destination', directory], app)
const archive = resolve(directory, `${metadata.name}-${metadata.version}.tgz`)
assertPublicPaths(
  execFileSync('tar', ['-tzf', archive], { encoding: 'utf8' })
    .split('\n')
    .filter((path) => path && !path.endsWith('/')),
  { packageContents: true },
)
// Exercise npm's automatic peer resolution without explicit framework pins.
// A clean install must resolve successfully without --force or --legacy-peer-deps.
const npmDirectory = resolve(directory, 'npm-install')
mkdirSync(npmDirectory)
writeFileSync(
  resolve(npmDirectory, 'package.json'),
  JSON.stringify({ name: 'devpush-npm-consumer', private: true }),
)
await run(
  'npm-peer-resolution',
  'npm',
  [
    'install',
    archive,
    '--package-lock-only',
    '--ignore-scripts',
    '--no-audit',
    '--no-fund',
  ],
  npmDirectory,
)
writeFileSync(
  resolve(directory, 'package.json'),
  JSON.stringify(
    {
      name: 'devpush-independent-consumer',
      private: true,
      type: 'module',
      scripts: { build: 'vite build' },
      dependencies: {
        devpush: `file:./${metadata.name}-${metadata.version}.tgz`,
        '@devpush/fixture-plugin': 'file:./fixture-plugin',
        ...Object.fromEntries(
          ['typescript', '@types/react', '@types/react-dom', '@types/node'].map(
            (name) => [
              name,
              JSON.parse(
                readFileSync(
                  resolve(app, 'node_modules', name, 'package.json'),
                ),
              ).version,
            ],
          ),
        ),
        ...metadata.peerDependencies,
        wrangler: JSON.parse(
          readFileSync(resolve(app, 'node_modules/wrangler/package.json')),
        ).version,
      },
      pnpm: {
        onlyBuiltDependencies: [
          'better-sqlite3',
          'esbuild',
          'lightningcss',
          'workerd',
        ],
      },
    },
    null,
    2,
  ),
)
const npmPlugin = resolve(directory, 'fixture-plugin')
mkdirSync(npmPlugin)
writeFileSync(
  resolve(npmPlugin, 'package.json'),
  JSON.stringify({
    name: '@devpush/fixture-plugin',
    version: '1.0.0',
    type: 'module',
    exports: './index.mjs',
    peerDependencies: {
      devpush: metadata.version,
      react: metadata.peerDependencies.react,
    },
  }),
)
function pluginFixture(root, id, name) {
  writeFileSync(
    resolve(root, name + '.server.mjs'),
    `import { defineServerPlugin, WorkspacePolicyError } from 'devpush/plugins/server'
const events = new Map(), denied = new Set()
const orderKey=Symbol.for('devpush.package-proof.order')
const order=globalThis[orderKey] ??= new Map()
const record = (team, event) => {
 const marker='${id}:'+event
 const values=events.get(team)||[]; values.push(marker); events.set(team,values)
 const sequence=order.get(team)||[]; sequence.push(marker); order.set(team,sequence)
}
export default defineServerPlugin(() => ({
  workspaceAccess: {
    async run(input, action) {
      record(input.teamId, 'before')
      try {
        if (denied.has(input.teamId)) throw new WorkspacePolicyError('restricted')
        return await action()
      } finally {record(input.teamId,'after')}
    },
  },
  serverLifecycle: {reconcile:async server=>record(server.teamId,'reconcile'),maintain:async()=>{}},
  ${id === 'local-proof' ? "certificates:{request:async ({server})=>{record(server.teamId,'certificate');return {status:'configuration',dnsNames:['*.proof.example.test']}}}," : ''}
  handleRequest: async (request, session) => {
    const url=new URL(request.url),team=url.searchParams.get('team')
    if(url.pathname.endsWith('/events')) return Response.json(events.get(team)||[])
    if(url.pathname.endsWith('/order')) return Response.json(order.get(team)||[])
    if(url.pathname.endsWith('/deny') && request.method==='POST') {denied.add(team);return new Response(null,{status:204})}
    return Response.json({ id: '${id}', session, marker: 'SERVER_ONLY_${id}' })
  }
}))
`,
  )
  writeFileSync(
    resolve(root, name + '.ui.tsx'),
    `import { defineClientPlugin } from 'devpush/plugins/client'
import { Button } from 'devpush/ui/button'
export default defineClientPlugin({workspace: {header: () => <Button>CLIENT_ONLY_${id}</Button>}})
`,
  )
  writeFileSync(
    resolve(root, name + '.mjs'),
    `import { definePlugin, pluginApiVersion } from 'devpush/plugins'
export default definePlugin({id:'${id}',apiVersion:pluginApiVersion,runtimes:['node','cloudflare'],server:new URL('./${name}.server.mjs',import.meta.url),client:new URL('./${name}.ui.tsx',import.meta.url)})
`,
  )
}
pluginFixture(directory, 'local-proof', 'local')
pluginFixture(npmPlugin, 'npm-proof', 'index')
writeFileSync(
  resolve(directory, 'vite.config.mjs'),
  "import { devpush } from 'devpush/vite'\nimport local from './local.mjs'\nimport npm from '@devpush/fixture-plugin'\nexport default devpush({plugins:[local,npm]})\n",
)
writeFileSync(
  resolve(directory, 'type-proof.tsx'),
  `import { Button } from 'devpush/ui/button'
import { defineClientPlugin } from 'devpush/plugins/client'
export default defineClientPlugin({workspace:{header:()=> <Button variant="outline">Typed plugin UI</Button>}})
`,
)
writeFileSync(
  resolve(directory, 'tsconfig.json'),
  JSON.stringify({
    compilerOptions: {
      target: 'ES2022',
      jsx: 'react-jsx',
      module: 'ESNext',
      moduleResolution: 'Bundler',
      strict: true,
      skipLibCheck: true,
      noEmit: true,
    },
    files: ['type-proof.tsx'],
  }),
)
await run('install', 'pnpm', ['install', '--prefer-offline'])
await run('consumer-types', 'pnpm', ['exec', 'tsc', '--noEmit'])
await run('cli-help', 'pnpm', ['exec', 'devpush', '--help'])
await run('cli-scaffold', 'pnpm', [
  'exec',
  'devpush',
  'init',
  'cli-installation',
  '--target',
  'cloudflare',
  '--no-install',
])
await run('cli-node-scaffold', 'pnpm', [
  'exec',
  'devpush',
  'init',
  'cli-node',
  '--target',
  'docker',
  '--no-install',
])
const cliNode = resolve(directory, 'cli-node')
const cliMigrations = resolve(directory, 'cli-migrations')
mkdirSync(cliMigrations)
await run(
  'cli-node-migrate',
  process.execPath,
  [resolve(directory, 'node_modules/devpush/dist/package/cli.mjs'), 'migrate'],
  cliMigrations,
)
assert(existsSync(resolve(cliMigrations, '.data/devpush.sqlite')))
if (!process.argv.includes('--development-only')) {
  const cliManifest = JSON.parse(
    readFileSync(resolve(cliNode, 'package.json'), 'utf8'),
  )
  cliManifest.dependencies.devpush = `file:${archive}`
  writeFileSync(
    resolve(cliNode, 'package.json'),
    JSON.stringify(cliManifest, null, 2),
  )
  await run(
    'cli-node-install',
    'npm',
    ['install', '--no-audit', '--no-fund'],
    cliNode,
  )
  await run('cli-node-build', 'npm', ['run', 'build'], cliNode)
  await run(
    'cli-node-smoke',
    process.execPath,
    [resolve(app, 'scripts/smoke-node.mjs')],
    app,
    { DEVPUSH_SMOKE_APP_DIR: cliNode, DEVPUSH_SMOKE_PLUGINS: '0' },
  )
}

const installed = resolve(directory, 'node_modules/devpush')
const before = digest(resolve(installed, 'src'))
await run('migrate', process.execPath, [
  '--input-type=module',
  '-e',
  "import { migrateNode } from 'devpush/migrate'; await migrateNode()",
])
if (!process.argv.includes('--development-only')) {
  await run('node-build', 'pnpm', ['build'])
  assertClientBoundary(resolve(directory, '.output/public'))
  assert.equal(
    digest(resolve(installed, 'src')),
    before,
    'Build must not modify installed application source',
  )
  await run(
    'node-smoke',
    process.execPath,
    [resolve(app, 'scripts/smoke-node.mjs')],
    app,
    { DEVPUSH_SMOKE_APP_DIR: directory },
  )
}
await run(
  'node-development',
  process.execPath,
  [resolve(app, 'scripts/smoke-node.mjs')],
  app,
  { DEVPUSH_SMOKE_APP_DIR: directory, DEVPUSH_SMOKE_DEVELOPMENT: '1' },
)
assert.equal(
  digest(resolve(installed, 'src')),
  before,
  'Development must not modify installed application source',
)
assertApplicationNotOptimized()
if (
  !process.argv.includes('--node-only') &&
  !process.argv.includes('--development-only')
) {
  await run(
    'worker-smoke',
    process.execPath,
    [resolve(app, 'scripts/smoke-worker.mjs'), 'd1'],
    app,
    { DEVPUSH_SMOKE_APP_DIR: directory },
  )
  assert.equal(
    digest(resolve(installed, 'src')),
    before,
    'Worker build must not modify installed application source',
  )
  assertClientBoundary(resolve(directory, 'dist/client'))
  await run(
    'worker-development',
    process.execPath,
    [resolve(app, 'scripts/smoke-worker.mjs'), 'd1'],
    app,
    { DEVPUSH_SMOKE_APP_DIR: directory, DEVPUSH_SMOKE_DEVELOPMENT: '1' },
  )
  assert.equal(
    digest(resolve(installed, 'src')),
    before,
    'Worker development must not modify installed application source',
  )
  assertApplicationNotOptimized()
}
if (!process.argv.includes('--development-only')) {
  const ui = resolve(directory, 'local.ui.tsx')
  const original = readFileSync(ui, 'utf8')
  try {
    writeFileSync(
      ui,
      `import server from './local.server.mjs'
import { defineClientPlugin } from 'devpush/plugins/client'
export default defineClientPlugin({workspace:{header:()=> <span>{String(server)}</span>}})
`,
    )
    await run(
      'reject-server-import',
      'pnpm',
      ['build'],
      directory,
      {},
      'Server-only plugin module imported by client',
    )
  } finally {
    writeFileSync(ui, original)
  }
}
const scope = process.argv.includes('--development-only')
  ? 'Development'
  : process.argv.includes('--node-only')
    ? 'Node'
    : 'Node and Workers'
console.log(`${scope} package proof passed. Logs: ${logs}`)

// Publish exactly the archive installed and tested by the independent consumer.
if (process.env.DEVPUSH_PACKAGE_ARTIFACT_DIR) {
  const output = resolve(process.env.DEVPUSH_PACKAGE_ARTIFACT_DIR)
  mkdirSync(output, { recursive: true })
  copyFileSync(
    archive,
    resolve(output, `${metadata.name}-${metadata.version}.tgz`),
  )
}