diff --git a/.editorconfig b/.editorconfig
index 61ea5dd7..f100c09b 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -10,6 +10,3 @@ indent_size = 2
[*.php]
indent_size = 4
-
-[Makefile]
-indent_style = tab
diff --git a/.gitattributes b/.gitattributes
index cadd4117..641e8a3b 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,25 @@
src/Resources/*.php linguist-generated
src/Routes/*.php linguist-generated
src/SeamClient.php linguist-generated
+
+# Keep development files out of the published package.
+# GitHub builds the archives Composer downloads as dist with git archive,
+# which honours these rules.
+/.devcontainer export-ignore
+/.editorconfig export-ignore
+/.env.example export-ignore
+/.gitattributes export-ignore
+/.github export-ignore
+/.gitignore export-ignore
+/.npmrc export-ignore
+/.prettierignore export-ignore
+/.prettierrc.json export-ignore
+/.releaserc.json export-ignore
+/codegen export-ignore
+/eslint.config.ts export-ignore
+/package-lock.json export-ignore
+/package.json export-ignore
+/phpunit.xml.dist export-ignore
+/tests export-ignore
+/tsconfig.json export-ignore
+/version.ts export-ignore
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index b1dab4d9..c3d9f4b0 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @rchodava @andrii-balitskyi @seveibar
+* @seamapi/sdk
diff --git a/.github/actions/setup-node/action.yml b/.github/actions/setup-node/action.yml
new file mode 100644
index 00000000..d52103d3
--- /dev/null
+++ b/.github/actions/setup-node/action.yml
@@ -0,0 +1,46 @@
+---
+name: Setup Node.js
+description: Setup Node.js and install dependencies.
+
+inputs:
+ node_version:
+ description: The Node.js version.
+ required: false
+ default: '24'
+ registry_url:
+ description: The Node.js package registry URL.
+ required: false
+ default: https://registry.npmjs.org
+ install_dependencies:
+ description: Install dependencies.
+ required: false
+ default: 'true'
+
+runs:
+ using: composite
+ steps:
+ - name: Setup Node.js
+ uses: actions/setup-node@v7
+ if: inputs.install_dependencies == 'true'
+ with:
+ node-version: ${{ inputs.node_version }}
+ registry-url: ${{ inputs.registry_url }}
+ - name: Setup Node.js without cache
+ uses: actions/setup-node@v7
+ if: inputs.install_dependencies == 'false'
+ with:
+ node-version: ${{ inputs.node_version }}
+ registry-url: ${{ inputs.registry_url }}
+ - name: Install dependencies
+ if: inputs.install_dependencies == 'true'
+ shell: bash
+ run: npm ci --ignore-scripts
+ - name: Rebuild Node.js modules
+ shell: bash
+ run: npm rebuild
+ - name: Run postinstall script
+ shell: bash
+ run: npm run postinstall --if-present
+ - name: Run prepare script
+ shell: bash
+ run: npm run prepare --if-present
diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml
index e0b54475..fd9fcf70 100644
--- a/.github/actions/setup/action.yml
+++ b/.github/actions/setup/action.yml
@@ -1,15 +1,12 @@
---
name: Setup
-description: Setup Node.js and install dependencies.
+description: Setup PHP and install dependencies.
+
inputs:
- node_version:
- description: The Node.js version.
- required: false
- default: '24'
- registry_url:
- description: The Node.js package registry URL.
+ php_version:
+ description: The PHP version.
required: false
- default: https://registry.npmjs.org
+ default: '8.5'
install_dependencies:
description: Install dependencies.
required: false
@@ -18,28 +15,30 @@ inputs:
runs:
using: composite
steps:
- - name: Setup Node.js
- uses: actions/setup-node@v7
- if: inputs.install_dependencies == 'true'
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
with:
- node-version: ${{ inputs.node_version }}
- registry-url: ${{ inputs.registry_url }}
- - name: Setup Node.js without cache
- uses: actions/setup-node@v7
- if: inputs.install_dependencies == 'false'
- with:
- node-version: ${{ inputs.node_version }}
- registry-url: ${{ inputs.registry_url }}
- - name: Install dependencies
+ php-version: ${{ inputs.php_version }}
+ tools: composer:v2
+ coverage: none
+ - name: Check lockfile
if: inputs.install_dependencies == 'true'
shell: bash
- run: npm ci --ignore-scripts
- - name: Rebuild Node.js modules
- shell: bash
- run: npm rebuild
- - name: Run postinstall script
+ run: composer validate --strict
+ - name: Get Composer cache directory
+ id: composer_cache
+ if: inputs.install_dependencies == 'true'
shell: bash
- run: npm run postinstall --if-present
- - name: Run prepare script
+ run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
+ - name: Setup Composer cache
+ uses: actions/cache@v4
+ if: inputs.install_dependencies == 'true'
+ with:
+ key: composer-${{ inputs.php_version }}-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('composer.lock') }}
+ restore-keys: |
+ composer-${{ inputs.php_version }}-${{ runner.os }}-${{ runner.arch }}-
+ path: ${{ steps.composer_cache.outputs.dir }}
+ - name: Install dependencies
+ if: inputs.install_dependencies == 'true'
shell: bash
- run: npm run prepare --if-present
+ run: composer install --no-interaction --no-progress
diff --git a/.github/workflows/_build.yml b/.github/workflows/_build.yml
new file mode 100644
index 00000000..63aea632
--- /dev/null
+++ b/.github/workflows/_build.yml
@@ -0,0 +1,36 @@
+---
+name: _build
+
+on:
+ workflow_call:
+ inputs:
+ php_version:
+ description: The PHP version.
+ type: string
+ required: false
+ default: '8.5'
+ outputs:
+ artifact_name:
+ description: The artifact name.
+ value: build-${{ github.sha }}
+
+jobs:
+ build:
+ name: Package
+ runs-on: ubuntu-latest
+ timeout-minutes: 30
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v7
+ - name: Setup
+ uses: ./.github/actions/setup
+ with:
+ php_version: ${{ inputs.php_version }}
+ - name: Build
+ run: composer build
+ - name: Upload artifact
+ uses: actions/upload-artifact@v7
+ with:
+ name: build-${{ github.sha }}
+ if-no-files-found: error
+ path: pkg/
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
new file mode 100644
index 00000000..95ca05d1
--- /dev/null
+++ b/.github/workflows/check.yml
@@ -0,0 +1,124 @@
+---
+name: Check
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - '**'
+
+jobs:
+ test:
+ name: Test (PHP ${{ matrix.php }} on ${{ matrix.os_name }})
+ runs-on: ${{ matrix.os }}
+ timeout-minutes: 30
+ strategy:
+ fail-fast: false
+ matrix:
+ os:
+ - ubuntu-latest
+ php:
+ - '8.0'
+ - '8.5'
+ include:
+ - os: ubuntu-latest
+ os_name: Linux
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v7
+ - name: Setup
+ uses: ./.github/actions/setup
+ with:
+ php_version: ${{ matrix.php }}
+ - name: Setup Node.js
+ uses: ./.github/actions/setup-node
+ - name: Test
+ run: composer test
+ lint:
+ name: Lint (PHP ${{ matrix.php }})
+ runs-on: ubuntu-latest
+ timeout-minutes: 30
+ strategy:
+ fail-fast: false
+ matrix:
+ php:
+ - '8.0'
+ - '8.5'
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v7
+ - name: Setup
+ uses: ./.github/actions/setup
+ with:
+ php_version: ${{ matrix.php }}
+ - name: Setup Node.js
+ uses: ./.github/actions/setup-node
+ - name: Lint
+ run: composer lint
+ - name: Lint with ESLint and Prettier
+ run: npm run lint
+ build:
+ name: Build
+ uses: ./.github/workflows/_build.yml
+ install:
+ name: Install (PHP ${{ matrix.php }} on ${{ matrix.os_name }})
+ runs-on: ${{ matrix.os }}
+ timeout-minutes: 30
+ needs: build
+ strategy:
+ fail-fast: false
+ matrix:
+ os:
+ - ubuntu-latest
+ php:
+ - '8.0'
+ - '8.5'
+ include:
+ - os: ubuntu-latest
+ os_name: Linux
+ steps:
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ tools: composer:v2
+ coverage: none
+ - name: Download artifact
+ uses: actions/download-artifact@v8
+ with:
+ name: ${{ needs.build.outputs.artifact_name }}
+ path: pkg/
+ - name: Extract package
+ run: unzip -q pkg/seam.zip -d package
+ - name: Create composer.json
+ uses: DamianReeves/write-file-action@v1.3
+ with:
+ write-mode: overwrite
+ path: composer.json
+ contents: |
+ {
+ "repositories": [
+ {
+ "type": "path",
+ "url": "./package",
+ "options": { "symlink": false }
+ }
+ ],
+ "require": { "seamapi/seam": "*" },
+ "minimum-stability": "dev"
+ }
+ - name: Create main.php
+ uses: DamianReeves/write-file-action@v1.3
+ with:
+ write-mode: overwrite
+ path: main.php
+ contents: |
+
diff --git a/.github/workflows/generate.yml b/.github/workflows/generate.yml
index dd5e1472..f163e526 100644
--- a/.github/workflows/generate.yml
+++ b/.github/workflows/generate.yml
@@ -27,8 +27,8 @@ jobs:
git_committer_email: ${{ secrets.GIT_USER_EMAIL }}
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
- - name: Setup
- uses: ./.github/actions/setup
+ - name: Setup Node.js
+ uses: ./.github/actions/setup-node
with:
install_dependencies: 'false'
- name: Normalize package-lock.json
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 42ac2323..506ee053 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -1,3 +1,4 @@
+---
name: Publish
run-name: Publish ${{ github.ref_name }}
@@ -8,16 +9,24 @@ on:
- v*
jobs:
+ build:
+ name: Build
+ uses: ./.github/workflows/_build.yml
release:
name: GitHub Releases
runs-on: ubuntu-latest
timeout-minutes: 30
+ needs: build
steps:
- name: Checkout
uses: actions/checkout@v7
with:
fetch-depth: 0
-
+ - name: Download artifact
+ uses: actions/download-artifact@v8
+ with:
+ name: ${{ needs.build.outputs.artifact_name }}
+ path: pkg/
- name: Generate release notes
id: changelog
run: |
@@ -26,11 +35,11 @@ jobs:
echo "outfile=${outfile}" >> $GITHUB_OUTPUT
npx standard-changelog@^5.0.0 --release-count 2 --infile $outfile.tmp --outfile $outfile.tmp
sed '1,3d' $outfile.tmp > $outfile
-
- name: Create GitHub release
uses: softprops/action-gh-release@v3
with:
token: ${{ secrets.GH_TOKEN }}
+ fail_on_unmatched_files: true
prerelease: ${{ contains(github.ref_name, '-') }}
- files: ''
+ files: pkg/*
body_path: ${{ github.workspace }}/${{ steps.changelog.outputs.outfile }}
diff --git a/.github/workflows/semantic-release.yml b/.github/workflows/semantic-release.yml
index 88a1dfc1..b2e3aab9 100644
--- a/.github/workflows/semantic-release.yml
+++ b/.github/workflows/semantic-release.yml
@@ -6,7 +6,7 @@ run-name: Semantic Release from ${{ github.ref_name }}
on:
push:
branches:
- - main
+ - '**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
deleted file mode 100644
index 7f897d7d..00000000
--- a/.github/workflows/test.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-name: PHP Test
-on: ['pull_request']
-jobs:
- test:
- if: "!contains(github.event.head_commit.message, 'skip ci')"
- name: Run PHP Tests
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v7
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- php-version: '8.0'
- - run: composer install
- - run: composer exec phpunit tests
- env:
- SEAM_API_KEY: ${{ secrets.SEAM_API_KEY }}
diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml
index 7435c6d2..3d9a72f8 100644
--- a/.github/workflows/version.yml
+++ b/.github/workflows/version.yml
@@ -29,7 +29,7 @@ jobs:
git_committer_email: ${{ secrets.GIT_USER_EMAIL }}
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
- - name: Setup
- uses: ./.github/actions/setup
+ - name: Setup Node.js
+ uses: ./.github/actions/setup-node
- name: Cut ${{ github.event.inputs.version }} version
run: npm version --sign-git-tag=true ${{ github.event.inputs.version }}
diff --git a/.gitignore b/.gitignore
index 56327be0..78aaf436 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,8 +12,12 @@ CODEGEN.md
vendor
tmp
+# PHPUnit result cache
+.phpunit.result.cache
+
# Build directories
package
+/pkg/
# Environment versions file
.versions
diff --git a/.prettierrc.json b/.prettierrc.json
index 4e3a60e5..66ce34de 100644
--- a/.prettierrc.json
+++ b/.prettierrc.json
@@ -1,15 +1,22 @@
{
"plugins": ["@prettier/plugin-php"],
- "parser": "php",
-
+ "semi": false,
+ "singleQuote": true,
+ "jsxSingleQuote": true,
+ "endOfLine": "lf",
"overrides": [
{
- "files": "**/*.{js,ts,json,yml,md}",
+ "files": "**/*.php",
"options": {
- "semi": false,
- "singleQuote": true,
- "jsxSingleQuote": true,
- "endOfLine": "lf"
+ "parser": "php",
+ "semi": true,
+ "singleQuote": false
+ }
+ },
+ {
+ "files": "**/*.md",
+ "options": {
+ "embeddedLanguageFormatting": "off"
}
}
]
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 00000000..ebaae486
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2021-2024 Seam Labs, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
index 2ca38f9f..567a864c 100644
--- a/README.md
+++ b/README.md
@@ -163,15 +163,96 @@ If you want to install our previous handwritten version, run:
`composer require seamapi/seam:1.1`
-## Development Setup
+## Development and Testing
-1. Run `yarn install` to get prettier installed for formatting
-2. Install [composer](https://getcomposer.org/).
-3. Run `composer install` in this directory
-4. Run `composer exec phpunit tests`
+### Quickstart
-> To run a specific test file, do `composer exec phpunit tests/MyTest.php`
+Install [PHP](https://www.php.net/) 8.0 or later,
+[Composer](https://getcomposer.org/) and [Node.js](https://nodejs.org/),
+then run
+
+```
+$ git clone git@github.com:seamapi/php.git
+$ cd php
+$ composer install
+$ npm install
+```
+
+Primary development tasks are defined as [Composer scripts](https://getcomposer.org/doc/articles/scripts.md)
+in `composer.json` and available via `composer`.
+View them with
+
+```
+$ composer run-script --list
+```
+
+| Task | Command |
+| ----------------- | ------------------ |
+| Run the tests | `composer test` |
+| Lint | `composer lint` |
+| Format | `npm run format` |
+| Build the package | `composer build` |
+| Generate the SDK | `npm run generate` |
+
+Formatting is handled by [Prettier](https://prettier.io/) via
+[@prettier/plugin-php](https://github.com/prettier/plugin-php),
+so PHP, TypeScript, JSON, YAML and Markdown are all formatted by
+`npm run format`.
### Running Tests
-You'll need to export `SEAM_API_KEY` to a sandbox workspace API key.
\ No newline at end of file
+Run the full suite with
+
+```
+$ composer test
+```
+
+To run a specific test file, pass it as an argument
+
+```
+$ composer test -- tests/MyTest.php
+```
+
+PHPUnit is configured in `phpunit.xml.dist`.
+
+### Requirements
+
+This package supports PHP 8.0 and later.
+Continuous integration exercises both ends of that range, PHP 8.0 and 8.5.
+
+### Publishing
+
+#### Automatic
+
+New versions are released automatically from `main` by the
+[Semantic Release](.github/workflows/semantic-release.yml) workflow,
+which reads [Conventional Commits](https://www.conventionalcommits.org/)
+and dispatches the [Version](.github/workflows/version.yml) workflow.
+
+#### Manual
+
+Run the [Version](.github/workflows/version.yml) workflow with the
+version to cut.
+It runs `npm version`, which bumps the `version` field in `package.json`,
+injects that version into `Seam\Utils\PackageVersion`, creates a signed `v*`
+git tag and pushes it.
+Pushing the tag triggers the [Publish](.github/workflows/publish.yml)
+workflow, and [Packagist](https://packagist.org/packages/seamapi/seam)
+picks up the new tag from its GitHub webhook.
+
+> Composer has no canonical place to store a package version, since Packagist
+> derives it from the git tag, and it publishes the tag as-is with no build
+> step in between.
+> This repository therefore keeps the version in `package.json`, which is a
+> development manifest that is not published, and injects it into the
+> `Seam\Utils\PackageVersion::VERSION` constant used for the
+> `seam-sdk-version` header.
+>
+> The injection runs from `version.ts`, wired to the `version` lifecycle
+> script, which npm runs after the bump but before the commit, so the
+> updated constant is part of the tagged commit.
+> Never edit that constant by hand; a test asserts it matches `package.json`.
+
+Development files are kept out of the published package with `export-ignore`
+rules in `.gitattributes`, which `git archive` honours when GitHub builds the
+archives Composer downloads as `dist`.
diff --git a/codegen/lib/handlebars-helpers.ts b/codegen/lib/handlebars-helpers.ts
index 41238d38..263be9ce 100644
--- a/codegen/lib/handlebars-helpers.ts
+++ b/codegen/lib/handlebars-helpers.ts
@@ -52,10 +52,14 @@ const createPhpDoc = (
.split(/\r?\n/)
.map(sanitizePhpDocLine)
const populatedDescription = description.trim() === '' ? [] : descriptionLines
- const populatedTags = tags.filter((tag) => tag.trim() !== '').map(sanitizePhpDocLine)
+ const populatedTags = tags
+ .filter((tag) => tag.trim() !== '')
+ .map(sanitizePhpDocLine)
const lines = [
...populatedDescription,
- ...(populatedDescription.length > 0 && populatedTags.length > 0 ? [''] : []),
+ ...(populatedDescription.length > 0 && populatedTags.length > 0
+ ? ['']
+ : []),
...populatedTags,
]
diff --git a/codegen/lib/resource-model.ts b/codegen/lib/resource-model.ts
index 0289112e..e29a192f 100644
--- a/codegen/lib/resource-model.ts
+++ b/codegen/lib/resource-model.ts
@@ -16,8 +16,14 @@ import { getPhpType } from './map-php-type.js'
export type ResourceClassProperty =
| ({ kind: 'value'; phpType: string } & ResourceClassPropertyMetadata)
- | ({ kind: 'objectReference'; referenceName: string } & ResourceClassPropertyMetadata)
- | ({ kind: 'listReference'; referenceName: string } & ResourceClassPropertyMetadata)
+ | ({
+ kind: 'objectReference'
+ referenceName: string
+ } & ResourceClassPropertyMetadata)
+ | ({
+ kind: 'listReference'
+ referenceName: string
+ } & ResourceClassPropertyMetadata)
interface ResourceClassPropertyMetadata {
name: string
@@ -109,8 +115,12 @@ export const createResourceModel = (blueprint: Blueprint): ResourceModel => {
currentResourceName = name
localClassNames.set(name, [])
const sourceResource =
- blueprint.resources.find((resource) => resource.resourceType === resourceType) ??
- (resourceType === 'event' ? blueprint.events[0] : blueprint.actionAttempts[0])
+ blueprint.resources.find(
+ (resource) => resource.resourceType === resourceType,
+ ) ??
+ (resourceType === 'event'
+ ? blueprint.events[0]
+ : blueprint.actionAttempts[0])
addClass(
name,
baseResources.get(resourceType) ?? [],
diff --git a/codegen/lib/routes.ts b/codegen/lib/routes.ts
index 974a6ecf..f18f155a 100644
--- a/codegen/lib/routes.ts
+++ b/codegen/lib/routes.ts
@@ -102,7 +102,8 @@ export const routes = (
const createClientMethod = (endpoint: Endpoint): PhpClientMethod => {
const { response } = endpoint
- const responseKey = response.responseType === 'void' ? '' : response.responseKey
+ const responseKey =
+ response.responseType === 'void' ? '' : response.responseKey
// Batch responses have no single resource type; they deserialize into the
// Batch resource. A response whose resource type the blueprint cannot
@@ -126,17 +127,17 @@ const createClientMethod = (endpoint: Endpoint): PhpClientMethod => {
isDeprecated: endpoint.isDeprecated,
deprecationMessage: endpoint.deprecationMessage,
parameters: endpoint.request.parameters.map((parameter) => ({
- name: parameter.name,
- type: getPhpType(parameter),
- description: parameter.description,
- required: parameter.isRequired,
- // The primary identifier of a get endpoint always sorts first in the
- // method signature.
- position:
- endpoint.name === 'get' && parameter.name === `${responseKey}_id`
- ? 0
- : undefined,
- })),
+ name: parameter.name,
+ type: getPhpType(parameter),
+ description: parameter.description,
+ required: parameter.isRequired,
+ // The primary identifier of a get endpoint always sorts first in the
+ // method signature.
+ position:
+ endpoint.name === 'get' && parameter.name === `${responseKey}_id`
+ ? 0
+ : undefined,
+ })),
returnPath: responseKey,
returnResource: resourceType === '' ? '' : pascalCase(resourceType),
isArrayResponse:
diff --git a/composer.json b/composer.json
index b8d0b9b4..6827b5ce 100644
--- a/composer.json
+++ b/composer.json
@@ -1,24 +1,96 @@
{
"name": "seamapi/seam",
+ "description": "SDK for the Seam API written in PHP.",
"type": "library",
+ "keywords": [
+ "seam",
+ "sdk",
+ "api",
+ "iot",
+ "smart-lock",
+ "access-control"
+ ],
+ "homepage": "https://github.com/seamapi/php",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Seam Labs, Inc.",
+ "email": "engineering@getseam.com",
+ "homepage": "https://www.seam.co"
+ }
+ ],
+ "support": {
+ "docs": "https://docs.seam.co",
+ "issues": "https://github.com/seamapi/php/issues",
+ "source": "https://github.com/seamapi/php"
+ },
"require": {
+ "php": "^8.0",
"guzzlehttp/guzzle": "^7.5"
},
+ "require-dev": {
+ "phpunit/phpunit": "^9.5",
+ "squizlabs/php_codesniffer": "^3.7"
+ },
"autoload": {
"psr-4": {
- "Seam\\": ["src/", "src/Exceptions/"],
- "Tests\\": "tests/"
+ "Seam\\": [
+ "src/",
+ "src/Exceptions/"
+ ]
},
- "classmap": ["src/Resources/"]
+ "classmap": [
+ "src/Resources/"
+ ]
},
- "authors": [
- {
- "name": "seveibar",
- "email": "seveibar@gmail.com"
+ "autoload-dev": {
+ "psr-4": {
+ "Tests\\": "tests/"
}
- ],
- "require-dev": {
- "phpunit/phpunit": "^9.5",
- "squizlabs/php_codesniffer": "^3.7"
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "archive": {
+ "exclude": [
+ "/.devcontainer",
+ "/.editorconfig",
+ "/.env.example",
+ "/.github",
+ "/.npmrc",
+ "/.phpunit.result.cache",
+ "/.prettierignore",
+ "/.prettierrc.json",
+ "/.releaserc.json",
+ "/codegen",
+ "/eslint.config.ts",
+ "/node_modules",
+ "/package-lock.json",
+ "/package.json",
+ "/phpunit.xml.dist",
+ "/pkg",
+ "/tests",
+ "/tmp",
+ "/tsconfig.json",
+ "/vendor",
+ "/version.ts"
+ ]
+ },
+ "scripts": {
+ "build": "@composer archive --format=zip --dir=pkg --file=seam",
+ "test": "phpunit",
+ "lint": [
+ "@lint:composer",
+ "@lint:syntax"
+ ],
+ "lint:composer": "@composer validate --strict",
+ "lint:syntax": "! find src tests -name '*.php' -exec php -l {} \\; | grep -v '^No syntax errors detected'"
+ },
+ "scripts-descriptions": {
+ "build": "Build a distributable archive of this package into pkg/.",
+ "test": "Run the test suite.",
+ "lint": "Run all lint checks.",
+ "lint:composer": "Validate composer.json and composer.lock.",
+ "lint:syntax": "Check every PHP source file for syntax errors."
}
}
diff --git a/composer.lock b/composer.lock
index 55187fba..bc6794ae 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "dbef2f8bca9faca558cad1eb1b7a1771",
+ "content-hash": "47b28c106be0ff4f75680c1fe23e931a",
"packages": [
{
"name": "guzzlehttp/guzzle",
@@ -54,13 +54,17 @@
}
},
"autoload": {
- "files": ["src/functions_include.php"],
+ "files": [
+ "src/functions_include.php"
+ ],
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["MIT"],
+ "license": [
+ "MIT"
+ ],
"authors": [
{
"name": "Graham Campbell",
@@ -157,13 +161,17 @@
}
},
"autoload": {
- "files": ["src/functions_include.php"],
+ "files": [
+ "src/functions_include.php"
+ ],
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["MIT"],
+ "license": [
+ "MIT"
+ ],
"authors": [
{
"name": "Graham Campbell",
@@ -187,7 +195,9 @@
}
],
"description": "Guzzle promises library",
- "keywords": ["promise"],
+ "keywords": [
+ "promise"
+ ],
"support": {
"issues": "https://github.com/guzzle/promises/issues",
"source": "https://github.com/guzzle/promises/tree/1.5.2"
@@ -256,7 +266,9 @@
}
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["MIT"],
+ "license": [
+ "MIT"
+ ],
"authors": [
{
"name": "Graham Campbell",
@@ -355,7 +367,9 @@
}
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["MIT"],
+ "license": [
+ "MIT"
+ ],
"authors": [
{
"name": "PHP-FIG",
@@ -364,7 +378,12 @@
],
"description": "Common interface for HTTP clients",
"homepage": "https://github.com/php-fig/http-client",
- "keywords": ["http", "http-client", "psr", "psr-18"],
+ "keywords": [
+ "http",
+ "http-client",
+ "psr",
+ "psr-18"
+ ],
"support": {
"source": "https://github.com/php-fig/http-client/tree/master"
},
@@ -400,7 +419,9 @@
}
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["MIT"],
+ "license": [
+ "MIT"
+ ],
"authors": [
{
"name": "PHP-FIG",
@@ -452,7 +473,9 @@
}
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["MIT"],
+ "license": [
+ "MIT"
+ ],
"authors": [
{
"name": "PHP-FIG",
@@ -497,10 +520,14 @@
},
"type": "library",
"autoload": {
- "files": ["src/getallheaders.php"]
+ "files": [
+ "src/getallheaders.php"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["MIT"],
+ "license": [
+ "MIT"
+ ],
"authors": [
{
"name": "Ralph Khattar",
@@ -542,10 +569,14 @@
}
},
"autoload": {
- "files": ["function.php"]
+ "files": [
+ "function.php"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["MIT"],
+ "license": [
+ "MIT"
+ ],
"authors": [
{
"name": "Nicolas Grekas",
@@ -613,7 +644,9 @@
}
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["MIT"],
+ "license": [
+ "MIT"
+ ],
"authors": [
{
"name": "Marco Pivetta",
@@ -623,7 +656,10 @@
],
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
"homepage": "https://www.doctrine-project.org/projects/instantiator.html",
- "keywords": ["constructor", "instantiate"],
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ],
"support": {
"issues": "https://github.com/doctrine/instantiator/issues",
"source": "https://github.com/doctrine/instantiator/tree/1.4.1"
@@ -672,15 +708,25 @@
},
"type": "library",
"autoload": {
- "files": ["src/DeepCopy/deep_copy.php"],
+ "files": [
+ "src/DeepCopy/deep_copy.php"
+ ],
"psr-4": {
"DeepCopy\\": "src/DeepCopy/"
}
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["MIT"],
+ "license": [
+ "MIT"
+ ],
"description": "Create deep copies (clones) of your objects",
- "keywords": ["clone", "copy", "duplicate", "object", "object graph"],
+ "keywords": [
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
+ ],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
"source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
@@ -715,7 +761,9 @@
"ircmaxell/php-yacc": "^0.0.7",
"phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
},
- "bin": ["bin/php-parse"],
+ "bin": [
+ "bin/php-parse"
+ ],
"type": "library",
"extra": {
"branch-alias": {
@@ -728,14 +776,19 @@
}
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Nikita Popov"
}
],
"description": "A PHP parser written in PHP",
- "keywords": ["parser", "php"],
+ "keywords": [
+ "parser",
+ "php"
+ ],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1"
@@ -770,10 +823,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Arne Blankerts",
@@ -817,10 +874,14 @@
},
"type": "library",
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Arne Blankerts",
@@ -888,10 +949,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -901,7 +966,11 @@
],
"description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
"homepage": "https://github.com/sebastianbergmann/php-code-coverage",
- "keywords": ["coverage", "testing", "xunit"],
+ "keywords": [
+ "coverage",
+ "testing",
+ "xunit"
+ ],
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17"
@@ -941,10 +1010,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -954,7 +1027,10 @@
],
"description": "FilterIterator implementation that filters files based on a list of suffixes.",
"homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
- "keywords": ["filesystem", "iterator"],
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ],
"support": {
"issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
"source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6"
@@ -998,10 +1074,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1011,7 +1091,9 @@
],
"description": "Invoke callables with a timeout",
"homepage": "https://github.com/sebastianbergmann/php-invoker/",
- "keywords": ["process"],
+ "keywords": [
+ "process"
+ ],
"support": {
"issues": "https://github.com/sebastianbergmann/php-invoker/issues",
"source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1"
@@ -1051,10 +1133,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1064,7 +1150,9 @@
],
"description": "Simple template engine.",
"homepage": "https://github.com/sebastianbergmann/php-text-template/",
- "keywords": ["template"],
+ "keywords": [
+ "template"
+ ],
"support": {
"issues": "https://github.com/sebastianbergmann/php-text-template/issues",
"source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4"
@@ -1104,10 +1192,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1117,7 +1209,9 @@
],
"description": "Utility class for timing",
"homepage": "https://github.com/sebastianbergmann/php-timer/",
- "keywords": ["timer"],
+ "keywords": [
+ "timer"
+ ],
"support": {
"issues": "https://github.com/sebastianbergmann/php-timer/issues",
"source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3"
@@ -1177,7 +1271,9 @@
"ext-soap": "*",
"ext-xdebug": "*"
},
- "bin": ["phpunit"],
+ "bin": [
+ "phpunit"
+ ],
"type": "library",
"extra": {
"branch-alias": {
@@ -1185,11 +1281,17 @@
}
},
"autoload": {
- "files": ["src/Framework/Assert/Functions.php"],
- "classmap": ["src/"]
+ "files": [
+ "src/Framework/Assert/Functions.php"
+ ],
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1199,7 +1301,11 @@
],
"description": "The PHP Unit Testing framework.",
"homepage": "https://phpunit.de/",
- "keywords": ["phpunit", "testing", "xunit"],
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.24"
@@ -1243,10 +1349,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1295,10 +1405,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1347,10 +1461,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1400,10 +1518,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1424,7 +1546,11 @@
],
"description": "Provides the functionality to compare PHP values for equality",
"homepage": "https://github.com/sebastianbergmann/comparator",
- "keywords": ["comparator", "compare", "equality"],
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
"support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues",
"source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8"
@@ -1465,10 +1591,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1518,10 +1648,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1534,7 +1668,12 @@
],
"description": "Diff implementation",
"homepage": "https://github.com/sebastianbergmann/diff",
- "keywords": ["diff", "udiff", "unidiff", "unified diff"],
+ "keywords": [
+ "diff",
+ "udiff",
+ "unidiff",
+ "unified diff"
+ ],
"support": {
"issues": "https://github.com/sebastianbergmann/diff/issues",
"source": "https://github.com/sebastianbergmann/diff/tree/4.0.4"
@@ -1577,10 +1716,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1589,7 +1732,11 @@
],
"description": "Provides functionality to handle HHVM/PHP environments",
"homepage": "http://www.github.com/sebastianbergmann/environment",
- "keywords": ["Xdebug", "environment", "hhvm"],
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
"support": {
"issues": "https://github.com/sebastianbergmann/environment/issues",
"source": "https://github.com/sebastianbergmann/environment/tree/5.1.4"
@@ -1631,10 +1778,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1659,7 +1810,10 @@
],
"description": "Provides the functionality to export PHP variables for visualization",
"homepage": "https://www.github.com/sebastianbergmann/exporter",
- "keywords": ["export", "exporter"],
+ "keywords": [
+ "export",
+ "exporter"
+ ],
"support": {
"issues": "https://github.com/sebastianbergmann/exporter/issues",
"source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5"
@@ -1705,10 +1859,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1717,7 +1875,9 @@
],
"description": "Snapshotting of global state",
"homepage": "http://www.github.com/sebastianbergmann/global-state",
- "keywords": ["global state"],
+ "keywords": [
+ "global state"
+ ],
"support": {
"issues": "https://github.com/sebastianbergmann/global-state/issues",
"source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5"
@@ -1758,10 +1918,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1812,10 +1976,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1863,10 +2031,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1914,10 +2086,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -1973,10 +2149,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -2024,10 +2204,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -2073,10 +2257,14 @@
}
},
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Sebastian Bergmann",
@@ -2103,12 +2291,12 @@
"version": "3.7.1",
"source": {
"type": "git",
- "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
+ "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
"reference": "1359e176e9307e906dc3d890bcc9603ff6d90619"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619",
+ "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619",
"reference": "1359e176e9307e906dc3d890bcc9603ff6d90619",
"shasum": ""
},
@@ -2121,7 +2309,10 @@
"require-dev": {
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
},
- "bin": ["bin/phpcs", "bin/phpcbf"],
+ "bin": [
+ "bin/phpcs",
+ "bin/phpcbf"
+ ],
"type": "library",
"extra": {
"branch-alias": {
@@ -2129,7 +2320,9 @@
}
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Greg Sherwood",
@@ -2138,7 +2331,10 @@
],
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
"homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
- "keywords": ["phpcs", "standards"],
+ "keywords": [
+ "phpcs",
+ "standards"
+ ],
"support": {
"issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
"source": "https://github.com/squizlabs/PHP_CodeSniffer",
@@ -2168,10 +2364,14 @@
},
"type": "library",
"autoload": {
- "classmap": ["src/"]
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
- "license": ["BSD-3-Clause"],
+ "license": [
+ "BSD-3-Clause"
+ ],
"authors": [
{
"name": "Arne Blankerts",
@@ -2195,10 +2395,12 @@
],
"aliases": [],
"minimum-stability": "stable",
- "stability-flags": [],
+ "stability-flags": {},
"prefer-stable": false,
"prefer-lowest": false,
- "platform": [],
- "platform-dev": [],
- "plugin-api-version": "2.3.0"
+ "platform": {
+ "php": "^8.0"
+ },
+ "platform-dev": {},
+ "plugin-api-version": "2.6.0"
}
diff --git a/package.json b/package.json
index d220fa7c..e2b1f75c 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,7 @@
"private": true,
"license": "MIT",
"scripts": {
+ "version": "tsx ./version.ts && git add src/Utils/PackageVersion.php",
"postversion": "git push --follow-tags",
"generate": "tsx codegen/smith.ts",
"postgenerate": "npm run format",
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 00000000..e953736f
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,22 @@
+
+
+
+
+ tests
+
+
+
+
+ src
+
+
+
diff --git a/renovate.json b/renovate.json
deleted file mode 100644
index 431586d4..00000000
--- a/renovate.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "$schema": "https://docs.renovatebot.com/renovate-schema.json",
- "extends": ["config:base"],
- "commitMessagePrefix": "autorelease:",
- "packageRules": [
- {
- "packagePatterns": ["*"],
- "excludePackagePatterns": ["@seamapi/types"],
- "enabled": false
- },
- {
- "matchUpdateTypes": ["major", "minor", "patch"],
- "automerge": true
- }
- ]
-}
diff --git a/src/Utils/PackageVersion.php b/src/Utils/PackageVersion.php
index 0dc8a6a3..4aa2fb50 100644
--- a/src/Utils/PackageVersion.php
+++ b/src/Utils/PackageVersion.php
@@ -2,41 +2,18 @@
namespace Seam\Utils;
-class PackageVersionException extends \Exception {}
-
class PackageVersion
{
- public static function get()
+ /**
+ * The version of this package.
+ *
+ * Injected from package.json when a version is cut, by the version
+ * lifecycle script in package.json. Do not edit by hand.
+ */
+ public const VERSION = "3.5.0";
+
+ public static function get(): string
{
- $filePath = __DIR__ . "/../../package.json";
-
- if (!file_exists($filePath)) {
- throw new PackageVersionException(
- "Can't get package version. File package.json does not exist.",
- );
- }
-
- $content = file_get_contents($filePath);
- if ($content === false) {
- throw new PackageVersionException(
- "Unable to read package.json file to get package version.",
- );
- }
-
- $json = json_decode($content, true);
- if (json_last_error() !== JSON_ERROR_NONE) {
- throw new PackageVersionException(
- "JSON decode error occurred when decoding package.json: " .
- json_last_error_msg(),
- );
- }
-
- if (!isset($json["version"])) {
- throw new PackageVersionException(
- "Version not set in package.json",
- );
- }
-
- return $json["version"];
+ return self::VERSION;
}
}
diff --git a/tests/PackageVersionTest.php b/tests/PackageVersionTest.php
new file mode 100644
index 00000000..d45e970d
--- /dev/null
+++ b/tests/PackageVersionTest.php
@@ -0,0 +1,36 @@
+assertIsString($contents, "Could not read $path");
+
+ $package = json_decode($contents, true);
+ $this->assertIsArray($package, "Could not decode $path");
+ $this->assertArrayHasKey("version", $package);
+
+ $this->assertSame(
+ $package["version"],
+ PackageVersion::get(),
+ "Seam\\Utils\\PackageVersion is out of date with package.json. " .
+ "It is injected by the version lifecycle script when a " .
+ "version is cut and should not be edited by hand.",
+ );
+ }
+
+ public function testVersionIsUsedAsTheSdkVersionHeader(): void
+ {
+ $seam = new \Seam\SeamClient("seam_apikey1_token");
+ $headers = $seam->client->getConfig("headers");
+
+ $this->assertSame(PackageVersion::get(), $headers["seam-sdk-version"]);
+ }
+}
diff --git a/tsconfig.json b/tsconfig.json
index 6190bfbf..c3d380f1 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -2,5 +2,5 @@
"$schema": "https://json.schemastore.org/tsconfig.json",
"extends": "./node_modules/@seamapi/smith/tsconfig.base.json",
"files": ["codegen/index.ts"],
- "include": ["codegen/**/*", "eslint.config.ts"]
+ "include": ["codegen/**/*", "eslint.config.ts", "version.ts"]
}
diff --git a/version.ts b/version.ts
new file mode 100644
index 00000000..697bea44
--- /dev/null
+++ b/version.ts
@@ -0,0 +1,44 @@
+import { readFile, writeFile } from 'node:fs/promises'
+import { fileURLToPath } from 'node:url'
+
+const versionFile = './src/Utils/PackageVersion.php'
+
+const versionPattern = /public const VERSION = "[^"]*";/
+
+const main = async (): Promise => {
+ const version = await injectVersion(
+ fileURLToPath(new URL(versionFile, import.meta.url)),
+ )
+ // eslint-disable-next-line no-console
+ console.log(`✓ Version ${version} injected into ${versionFile}`)
+}
+
+const injectVersion = async (path: string): Promise => {
+ const { version } = await readPackageJson()
+
+ if (version == null) {
+ throw new Error('Missing version in package.json')
+ }
+
+ const data = (await readFile(path)).toString()
+
+ if (!versionPattern.test(data)) {
+ throw new Error(`Could not find the version constant in ${versionFile}`)
+ }
+
+ await writeFile(
+ path,
+ data.replace(versionPattern, `public const VERSION = "${version}";`),
+ )
+
+ return version
+}
+
+const readPackageJson = async (): Promise<{ version?: string }> => {
+ const pkgBuff = await readFile(
+ fileURLToPath(new URL('package.json', import.meta.url)),
+ )
+ return JSON.parse(pkgBuff.toString())
+}
+
+await main()