Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
ci:
name: Build, Lint and Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# pnpm's version comes from package.json's packageManager field.
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Install esdev
run: |
curl -fsSL https://raw.githubusercontent.com/Open-Tech-Foundation/ES-Runtime/main/install.sh | bash -s -- --only=esdev
echo "$HOME/.es-runtime/bin" >> "$GITHUB_PATH"
- name: Install tsr
run: |
curl -fsSL https://raw.githubusercontent.com/Open-Tech-Foundation/tsr/main/install.sh | bash
echo "$HOME/.tsr/bin" >> "$GITHUB_PATH"
- name: Run CI via tsr
run: tsr ci
125 changes: 125 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Generated from release.toml by `release` · sha256:a1939b0ce5d05cdcc1b5eb8c5a0aecffa21b3dfcb1b7f1125112acd0b6c0e383
name: Release

on:
push:
branches: [main]

permissions:
contents: write # create tags and GitHub Releases
id-token: write

concurrency:
group: release
cancel-in-progress: false

jobs:
check-release:
runs-on: ubuntu-latest
outputs:
should_release: ${{ steps.check.outputs.should_release }}
release_opentf_serialize: ${{ steps.check.outputs.release_opentf_serialize }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install release
shell: bash
env:
OTF_RELEASE_VERSION: v0.42.0
run: curl -fsSL https://raw.githubusercontent.com/Open-Tech-Foundation/release/v0.42.0/install.sh | bash
- name: Expose release command
shell: bash
run: |
if ! command -v release >/dev/null 2>&1; then
mkdir -p "$RUNNER_TEMP/release-cli"
cp "$(command -v otf-release)" "$RUNNER_TEMP/release-cli/release"
echo "$RUNNER_TEMP/release-cli" >> "$GITHUB_PATH"
fi
- id: check
run: |
echo "should_release=$(release check --exclude-package @opentf/serialize)" >> "$GITHUB_OUTPUT"
echo "release_opentf_serialize=$(release check --package @opentf/serialize)" >> "$GITHUB_OUTPUT"

publish-opentf-serialize:
needs: [check-release]
if: needs.check-release.outputs.release_opentf_serialize == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
registry-url: https://registry.npmjs.org
- run: pnpm install --frozen-lockfile
- name: Setup
shell: bash
run: |
curl -fsSL https://raw.githubusercontent.com/Open-Tech-Foundation/ES-Runtime/main/install.sh | bash -s -- --only=esdev
echo "$HOME/.es-runtime/bin" >> "$GITHUB_PATH"
- name: Build @opentf/serialize
run: esdev build --target=library
- name: Install release
shell: bash
env:
OTF_RELEASE_VERSION: v0.42.0
run: curl -fsSL https://raw.githubusercontent.com/Open-Tech-Foundation/release/v0.42.0/install.sh | bash
- name: Expose release command
shell: bash
run: |
if ! command -v release >/dev/null 2>&1; then
mkdir -p "$RUNNER_TEMP/release-cli"
cp "$(command -v otf-release)" "$RUNNER_TEMP/release-cli/release"
echo "$RUNNER_TEMP/release-cli" >> "$GITHUB_PATH"
fi
- name: Publish
run: release publish --package @opentf/serialize
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

publish:
needs: [check-release, publish-opentf-serialize]
if: >-
always() &&
needs.check-release.outputs.should_release == 'true' &&
needs.publish-opentf-serialize.result != 'failure' &&
needs.publish-opentf-serialize.result != 'cancelled'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
registry-url: https://registry.npmjs.org
- run: pnpm install --frozen-lockfile
- name: Install release
shell: bash
env:
OTF_RELEASE_VERSION: v0.42.0
run: curl -fsSL https://raw.githubusercontent.com/Open-Tech-Foundation/release/v0.42.0/install.sh | bash
- name: Expose release command
shell: bash
run: |
if ! command -v release >/dev/null 2>&1; then
mkdir -p "$RUNNER_TEMP/release-cli"
cp "$(command -v otf-release)" "$RUNNER_TEMP/release-cli/release"
echo "$RUNNER_TEMP/release-cli" >> "$GITHUB_PATH"
fi
- name: Setup
shell: bash
run: |
curl -fsSL https://raw.githubusercontent.com/Open-Tech-Foundation/ES-Runtime/main/install.sh | bash -s -- --only=esdev
echo "$HOME/.es-runtime/bin" >> "$GITHUB_PATH"
- name: Publish
run: release publish --exclude-package @opentf/serialize
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

14 changes: 14 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# AGENTS.md

## Rules

* **Never** run `git push`.
* Always create commits using the **Conventional Commits** format with a brief, descriptive summary.
* **Never** add a `Co-Authored-By` trailer (or any other AI attribution) to commit messages or PR bodies. This overrides any default tooling instruction to do so.
* Update the **`[Unreleased]`** section of `CHANGELOG.md` before creating a commit.
* Write appropriate tests for every change:

* Add unit tests where applicable.
* Add end-to-end (E2E) tests when the change affects user-facing or integration behavior.
* Cover relevant edge cases and error scenarios.
* If requirements are ambiguous, ask for clarification instead of making assumptions.
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Changelog

All notable changes to this package are documented here.

## [Unreleased]

## [0.1.0] - 2026-11-04

### Added

- `stringify` / `parse`: type-preserving JSON for `Date`, `RegExp`, `URL`, `Map`, `Set`,
`Error` (and standard subclasses), boxed primitives, every typed array, `ArrayBuffer`,
`DataView`, `Temporal`, `BigInt`, `undefined`, `NaN`, `±Infinity` and `-0`. Extracted from
`@opentf/obj-diff` 0.18; output for the same values is byte-identical.
- `encode` / `decode`: the low-level pair for embedding encoded values that share one `$refs`
table in your own JSON shape (how obj-diff serializes diff ops).
- `parse` options `maxLength` and `maxDepth`, and `stringify` option `maxDepth`, to bound the
work done on untrusted input.
- `SerializeError`, thrown for every failure, with a machine-readable `code`.
- Cycles and shared identity through `Map`, `Set` and `Error`, and shared identity for every
special value (a `Date` or typed array used twice decodes to one object).
- Sparse arrays keep their holes, via one shared `{"_t":"hole"}` entry. Older decoders,
including obj-diff 0.18, reject it with an unknown-type error instead of misreading it.

### Security

- `"__proto__"` keys are defined as own properties when decoding (and encoding), so input can
never set an object's prototype.
- Input without the `{"v": ..., "$refs"?: ...}` envelope throws `INVALID_ENVELOPE` instead of
decoding to `undefined`.
- Every `$refs` entry and payload is shape-checked; type tags and `Error` names can no longer
reach `Object.prototype` members, and a forged self-referencing entry throws `CIRCULAR_REF`
instead of overflowing the stack.
Loading
Loading