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
12 changes: 8 additions & 4 deletions .github/workflows/regenerate-sdk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,21 @@ jobs:
bash scripts/sdk/bundle-spec.sh "${{ github.workspace }}/_spec.json"

- name: Setup Java (for openapi-generator)
if: inputs.language != 'node'
if: inputs.language != 'node' && inputs.language != 'typescript'
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'

- name: Cache openapi-generator
if: inputs.language != 'node'
if: inputs.language != 'node' && inputs.language != 'typescript'
uses: actions/cache@v4
with:
path: ~/.openapi-generator
key: openapi-generator-${{ inputs.language == 'python' && '5.4.0' || '7.4.0' }}

- name: Install openapi-generator-cli
if: inputs.language != 'node'
if: inputs.language != 'node' && inputs.language != 'typescript'
run: |
npm install -g @openapitools/openapi-generator-cli
# Set generator version based on language
Expand Down Expand Up @@ -129,10 +129,12 @@ jobs:
- name: Copy generated files to SDK repo
run: |
# Remove previously generated files (but not .git, README, .github, etc.)
if [ "${{ inputs.language }}" = "node" ]; then
if [ "${{ inputs.language }}" = "node" ] || [ "${{ inputs.language }}" = "typescript" ]; then
rm -rf src/generated/ dist/
mkdir -p src/generated/
cp -r _generated/src/generated/* src/generated/
# Copy src/index.ts if generated
[ -f _generated/src/index.ts ] && cp _generated/src/index.ts src/index.ts
# Update package.json version only (preserve custom fields)
if [ -f _generated/package.json ]; then
node -e "
Expand All @@ -142,6 +144,8 @@ jobs:
require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
"
fi
# Copy tsconfig if generated and none exists
[ -f _generated/tsconfig.json ] && [ ! -f tsconfig.json ] && cp _generated/tsconfig.json tsconfig.json
elif [ "${{ inputs.language }}" = "php" ]; then
rm -rf src/Api/ src/Model/ src/ApiException.php src/Configuration.php src/HeaderSelector.php src/ObjectSerializer.php
cp -r _generated/src/* src/ 2>/dev/null || true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ jobs:
DISPATCH_TOKEN: ${{ secrets.SDK_DISPATCH_TOKEN }}
run: |
VERSION="${{ steps.release.outputs.version }}"
REPOS=("shotstack-sdk-node" "shotstack-sdk-php" "shotstack-sdk-python" "shotstack-sdk-ruby")
REPOS=("shotstack-sdk-node" "shotstack-sdk-php" "shotstack-sdk-python" "shotstack-sdk-ruby" "shotstack-sdk-typescript")

for repo in "${REPOS[@]}"; do
success=false
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sdk-conformance-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
GH_TOKEN: ${{ secrets.SDK_DISPATCH_TOKEN }}
run: |
OAS_VERSION="${{ steps.oas.outputs.version }}"
REPOS=("shotstack-sdk-node" "shotstack-sdk-php" "shotstack-sdk-python" "shotstack-sdk-ruby")
REPOS=("shotstack-sdk-node" "shotstack-sdk-php" "shotstack-sdk-python" "shotstack-sdk-ruby" "shotstack-sdk-typescript")
stale=""

for repo in "${REPOS[@]}"; do
Expand Down
3 changes: 2 additions & 1 deletion scripts/sdk/conformance-check.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ function getSdkModels(language, sdkDir) {
const models = new Set();

switch (language) {
case 'node': {
case 'node':
case 'typescript': {
// For hey-api generated SDK, check types.gen.ts for exported types
const typesFile = join(sdkDir, 'src', 'generated', 'types.gen.ts');
if (existsSync(typesFile)) {
Expand Down
82 changes: 82 additions & 0 deletions scripts/sdk/generate-typescript.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/env bash
set -euo pipefail

# Generate TypeScript SDK using @hey-api/openapi-ts
# Usage: generate-typescript.sh <spec-file> <output-dir> <version>
#
# Uses hey-api to produce modern TypeScript with typed SDK functions,
# fetch-based HTTP client, and tree-shakeable exports.

SPEC_FILE="${1:?Usage: generate-typescript.sh <spec-file> <output-dir> <version>}"
OUTPUT_DIR="${2:?Usage: generate-typescript.sh <spec-file> <output-dir> <version>}"
VERSION="${3:?Usage: generate-typescript.sh <spec-file> <output-dir> <version>}"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
OAS_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"

echo "Generating TypeScript SDK v${VERSION}..."

mkdir -p "${OUTPUT_DIR}/src/generated"

# hey-api resolves $ref from the spec's directory, so we must run from OAS root
cd "${OAS_ROOT}"
npx @hey-api/openapi-ts \
--input "./api.oas3.yaml" \
--output "${OUTPUT_DIR}/src/generated" \
--plugins @hey-api/typescript @hey-api/sdk

# Write package.json
cat > "${OUTPUT_DIR}/package.json" << EOF
{
"name": "shotstack-sdk-typescript",
"version": "${VERSION}",
"description": "Official TypeScript SDK for the Shotstack Cloud Video Editing API",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
},
"files": ["dist"],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/shotstack/shotstack-sdk-typescript.git"
},
"keywords": ["shotstack", "video", "video-editing", "video-api", "typescript"],
"engines": {
"node": ">=18"
}
}
EOF

# Write tsconfig.json
cat > "${OUTPUT_DIR}/tsconfig.json" << EOF
{
"compilerOptions": {
"target": "ES2022",
"module": "nodenext",
"moduleResolution": "nodenext",
"declaration": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"skipLibCheck": true,
"esModuleInterop": true
},
"include": ["src/**/*"]
}
EOF

# Write index.ts that re-exports everything
cat > "${OUTPUT_DIR}/src/index.ts" << 'EOF'
export * from './generated/types.gen';
export * from './generated/sdk.gen';
EOF

echo "TypeScript SDK generated at ${OUTPUT_DIR}"
2 changes: 1 addition & 1 deletion scripts/sdk/smoke-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ SDK_DIR="${2:?Usage: smoke-test.sh <language> <sdk-dir>}"
echo "Running smoke tests for ${LANGUAGE} SDK at ${SDK_DIR}..."

case "${LANGUAGE}" in
node)
node|typescript)
echo "→ TypeScript type-check..."
cd "${SDK_DIR}"
npm install --ignore-scripts 2>/dev/null || true
Expand Down
Loading