Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
8 changes: 8 additions & 0 deletions .changeset/bright-sloths-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@transloadit/node": patch
"@transloadit/zod": patch
"@transloadit/types": patch
"transloadit": patch
---

Add assembly status helpers and expand busy status codes for consistent terminal checks.
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,4 @@ Notes:
- **Lockstep versions:** Changesets use a fixed group, so version bumps and releases are always in lock‑step across `transloadit`, `@transloadit/node`, `@transloadit/types`, and `@transloadit/zod`.
- **Legacy parity:** `transloadit` is generated from `@transloadit/node` artifacts via `scripts/prepare-transloadit.ts`, then verified with `yarn parity:transloadit`. Only `package.json` metadata drift is allowed; any other drift fails.
- **Experimental packages:** Scoped packages (`@transloadit/node`, `@transloadit/types`, `@transloadit/zod`) publish with the `experimental` dist-tag. The unscoped `transloadit` package remains stable.
- **Changelog visibility:** Because versions are locked, a changeset that only lists scoped packages will still bump `transloadit` but may leave its changelog empty. If a change affects `transloadit` users, include `transloadit` in the changeset so the changelog entry is visible.
Comment thread
kvz marked this conversation as resolved.
Outdated
79 changes: 78 additions & 1 deletion packages/node/src/alphalib/types/assemblyStatus.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { z } from 'zod'

export const assemblyBusyCodeSchema = z.enum(['ASSEMBLY_UPLOADING'])
export const assemblyBusyCodeSchema = z.enum([
'ASSEMBLY_UPLOADING',
'ASSEMBLY_EXECUTING',
'ASSEMBLY_REPLAYING',
])

export const assemblyStatusOkCodeSchema = z.enum([
'ASSEMBLY_CANCELED',
Expand Down Expand Up @@ -733,6 +737,79 @@ export function getOk(assembly: AssemblyStatus | undefined | null): string | und
: undefined
}

/**
* Type guard to check if a status string is a busy (in-progress) state.
*/
export function isAssemblyBusyStatus(
status: string | undefined | null,
): status is z.infer<typeof assemblyBusyCodeSchema> {
return Boolean(status) && assemblyBusyCodeSchema.safeParse(status).success
}

/**
* Type guard to check if a status string is an ok (non-error) state.
*/
export function isAssemblyOkStatus(
status: string | undefined | null,
): status is z.infer<typeof assemblyStatusOkCodeSchema> {
return Boolean(status) && assemblyStatusOkCodeSchema.safeParse(status).success
}

/**
* Type guard to check if a status string is an error state.
*/
export function isAssemblyErrorStatus(
status: string | undefined | null,
): status is z.infer<typeof assemblyStatusErrCodeSchema> {
return Boolean(status) && assemblyStatusErrCodeSchema.safeParse(status).success
}

/**
* Type guard to check if an assembly matches the system error shape.
*/
export function isAssemblySysError(
assembly: AssemblyStatus | undefined | null,
): assembly is z.infer<typeof assemblyStatusSysErrSchema> {
return Boolean(assembly) && assemblyStatusSysErrSchema.safeParse(assembly).success
}

/**
* Type guard to check if a status string is terminal (ok, but not busy).
*/
export function isAssemblyTerminalOkStatus(
status: string | undefined | null,
): status is z.infer<typeof assemblyStatusOkCodeSchema> {
return isAssemblyOkStatus(status) && !isAssemblyBusyStatus(status)
}

/**
* Returns true if the assembly is in a busy (in-progress) state.
*/
export function isAssemblyBusy(assembly: AssemblyStatus | undefined | null): boolean {
return isAssemblyBusyStatus(getOk(assembly))
}

/**
* Returns true if the assembly is in a terminal ok state.
*/
export function isAssemblyTerminalOk(assembly: AssemblyStatus | undefined | null): boolean {
return isAssemblyTerminalOkStatus(getOk(assembly))
}

/**
* Returns true if the assembly has a terminal error state.
*/
export function isAssemblyTerminalError(assembly: AssemblyStatus | undefined | null): boolean {
return isAssemblyErrorStatus(getError(assembly)) || isAssemblySysError(assembly)
}

/**
* Returns true if the assembly is terminal (ok or error).
*/
export function isAssemblyTerminal(assembly: AssemblyStatus | undefined | null): boolean {
return isAssemblyTerminalOk(assembly) || isAssemblyTerminalError(assembly)
}

/**
* This type and these functions below are compatibility helpers for
* working with partial assembly status objects during the transition
Expand Down
23 changes: 23 additions & 0 deletions packages/node/test/unit/assembly-status-helpers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { describe, expect, it } from 'vitest'

import type { AssemblyStatus } from '../../src/alphalib/types/assemblyStatus.ts'
import {
isAssemblySysError,
isAssemblyTerminal,
isAssemblyTerminalError,
} from '../../src/alphalib/types/assemblyStatus.ts'

describe('assembly status helpers', () => {
it('treats system error shapes as terminal errors', () => {
const sysError = {
errno: -2,
code: 'ENOENT',
syscall: 'stat',
path: '/tmp/missing',
} as AssemblyStatus

expect(isAssemblySysError(sysError)).toBe(true)
expect(isAssemblyTerminalError(sysError)).toBe(true)
expect(isAssemblyTerminal(sysError)).toBe(true)
})
})
Loading