jkunz 0631238a48
Default (tags) / security (push) Failing after 1s
Default (tags) / test (push) Failing after 0s
Default (tags) / metadata (push) Skipped
v1.14.0
2026-09-09 20:56:38 +00:00
2026-09-09 20:56:38 +00:00
2024-10-21 12:16:09 +02:00
2026-09-09 20:56:38 +00:00
2024-10-21 12:16:09 +02:00
2024-10-21 12:16:09 +02:00
2024-10-21 12:16:09 +02:00
2026-09-09 20:56:38 +00:00

@git.zone/tspublish

Prepare and publish independently installable TypeScript packages from one repository. Each component has its own dependency list and package metadata; components share the repository version. TsBuild owns compilation. A release coordinator can prepare all packages before packing, journaling and publishing any of them.

Issue Reporting and Security

For reporting bugs, issues, or security vulnerabilities, please visit community.foss.global/. This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a code.foss.global/ account to submit Pull Requests directly.

Install

pnpm install --save-dev @git.zone/tspublish @git.zone/tsbuild

Repository structure

Keep the repository manifest private when it holds dependencies for the entire toolbox. Each named module becomes a separate public package with a filtered dependency manifest.

package.json
tsconfig.json
license.md
ts_core/
  index.ts
  readme.md
  tspublish.json
ts_adapter/
  index.ts
  readme.md
  tspublish.json

The repository's package.json supplies the shared version and external dependency versions. Internal package dependencies use the exact shared version, even when an older published version appears in the root manifest. Unknown external dependencies fail validation instead of being assigned the repository version.

Each package requires its own readme.md. The root license is copied into every prepared package. license.md is preferred; existing repositories using license remain supported.

Module configuration

{
  "name": "@example/adapter",
  "order": 2,
  "description": "Optional provider adapter for the example toolbox.",
  "dependencies": ["@example/core", "external-sdk"],
  "registries": ["useBase"],
  "bin": [],
  "engines": { "node": ">=24" },
  "sideEffects": false,
  "include": ["third-party-notices.md"]
}

Supported fields:

Field Meaning
name Published npm package name. Unnamed descriptors remain available to TsBuild for ordering only.
order Ordering preference among modules whose dependencies are ready. Dependencies always precede consumers.
dependencies Required package names, resolved from sibling modules or root production dependencies.
optionalDependencies Optional dependency names, resolved by the same rules.
peerDependencies Explicit peer version ranges.
peerDependenciesMeta Optional-peer metadata.
description Package description; defaults to the root description.
engines Runtime requirements; defaults to the root engines.
os, cpu, libc Nonempty npm platform-selector arrays. Entries may use ! to exclude a platform; duplicate entries are rejected. Each module declares its own selectors.
publishConfig.executableFiles Exact package-relative files that pnpm must pack with executable permissions. No leading ./, traversal, globs, duplicates, symlinks or directories. Every path must already be included in this package. Other publishConfig keys are rejected.
sideEffects Standard package side-effect declaration.
folders Additional ts_* folders owned by this package. A folder may have only one owner.
exports Explicit subpath/conditional exports into the package's compiled folders. Defaults to typed root exports.
include Exact repository-relative asset files or directories, including applicable notices. No globs or component source/compiled folders; use folders to declare source ownership.
externalRuntimeAssets Exact repository-relative files or directories executed by another runtime, such as Deno source. Copied without npm import validation; the package owner must qualify that runtime and its dependency graph. The same filesystem and folder-ownership restrictions as include apply. Asset declarations cannot overlap.
bin Executable names using the module's exported runCli() entrypoint. Wrappers are generated locally.
registries Destination intent for the standalone publisher; also returned to release coordinators for validation.

Root author, license, repository, homepage, bugs, keywords and funding metadata are preserved. The private repository flag, root scripts, unrelated dependencies and development dependencies are not copied into prepared packages.

Legacy main and types fields are derived from the root export's node, import, default, and types conditions when available. They never point at an unrelated default entrypoint when root exports are customized.

Native packages can declare "os": ["linux"], "cpu": ["x64"], "libc": ["glibc"] and "publishConfig": { "executableFiles": ["dist_ts_native/native"] }. Place the built payload in that module's compiled folder before preparation and include its applicable notices. Preparation preserves the payload's bytes and source permissions; pnpm applies executable permissions when packing it. A parent module can list these platform packages in optionalDependencies, which uses the same exact sibling versions and dependency ordering as required dependencies.

A wrapper that launches Deno can declare "include": ["deno.json", "deno.lock"] and "externalRuntimeAssets": ["mod.ts", "deno_src"]. These files are copied unchanged. Validate the Deno configuration, locked dependencies and execution separately before release. This declaration does not add npm dependencies or allow component ts*/dist_ts* folders to bypass npm import checks. Node source imports into these external assets are not admitted by the declaration.

For a subpath, include the additional source folder and declare both runtime and type entrypoints:

{
  "name": "@example/core",
  "order": 1,
  "dependencies": [],
  "registries": ["useBase"],
  "folders": ["ts_migration"],
  "exports": {
    ".": {
      "types": "./dist_ts_core/index.d.ts",
      "import": "./dist_ts_core/index.js"
    },
    "./migration": {
      "types": "./dist_ts_migration/index.d.ts",
      "import": "./dist_ts_migration/index.js"
    }
  }
}

Imports and local development

Import sibling components through their published package names and declare them in dependencies. Configure TypeScript paths to their source entrypoints within the same repository; GitZone's TypeScript formatter discovers these mappings from tspublish.json. This requires no workspace symlinks or local package dependencies.

Run the normal repository build before preparation:

pnpm build

Preparation requires the matching dist_ts* outputs and verifies every export target. It inspects literal imports in Node sources, declarations and ordinary include assets, and rejects undeclared dependencies and relative imports outside the component. Computed runtime imports remain the responsibility of the module author. Built-in Node modules are allowed. Browser compatibility must still be tested by each component.

Source folders, compiled folders and explicit assets are copied separately for each package. Symlinks, credential files and local dependency directories are rejected, including inside externalRuntimeAssets. Preparation does not bundle dependency implementations.

Plan and prepare

import { TsPublish } from '@git.zone/tspublish';

const publisher = new TsPublish();
const plan = await publisher.plan(process.cwd());
// plan.modules is in deterministic dependency order; order equals its array index.

const packages = await publisher.prepare(
  process.cwd(),
  '/absolute/existing-parent/new-package-directory',
);
// Each result contains folder, folders, name, version, order, manifest,
// include, licenseFile, registries and its prepared directory.

plan() reads manifests and license availability without writes, builds or network calls. It rejects duplicate package names, dependency cycles, unknown external dependency versions, local dependency links and invalid package paths.

prepare() plans again and materializes the already-built packages. The output directory must not exist; its parent must already exist at a canonical path. Output cannot be nested inside an input folder. Preparation removes its own incomplete output on failure and never overwrites a prior result. The caller owns successful prepared directories and their cleanup.

Neither method installs dependencies, fetches templates, contacts registries, publishes packages or terminates the process.

The CLI exposes the same operations:

pnpm exec tspublish plan
pnpm exec tspublish prepare /absolute/existing-parent/new-package-directory

A release coordinator should validate every module's destination intent, prepare all modules, pack every package, record the complete immutable artifact set, and then publish in the returned dependency order. Publication recovery must reuse those retained tarballs rather than rebuilding or preparing again.

Existing standalone publisher

The existing TsPublish.publish(repository) API and no-argument CLI remain available. They build and publish modules sequentially and do not provide transaction recovery. Use the owning repository's approved release workflow.

The standalone publisher supports explicit registry.npmjs.org:public entries, useBase, and extendBase with optional -URL exclusions. Base settings come from @git.zone/cli.release.targets.npm in .smartconfig.json; the previous release.registries and release.accessLevel fields remain readable. An empty registry list means build without publishing.

Standalone generated builds use the repository's declared TsBuild version rather than looking up a mutable latest version. The GiteaAssets helper remains available from its source module for existing integrations.

Development

pnpm build
pnpm test
pnpm exec tsbuild check 'test/**/*'

Packaging tests use disposable directories and do not publish anything.

This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the license.md file.

Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.

Trademarks

This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.

Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.

Company Information

Task Venture Capital GmbH Registered at District Court Bremen HRB 35230 HB, Germany

For any legal inquiries or further information, please contact us via email at hello@task.vc.

By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.

S
Description
publish multiple, concise and small packages from monorepos
Readme
1.3 MiB
Languages
TypeScript 99.5%
JavaScript 0.5%