Refactoring: now-php -> vercel-php

pull/65/head
Milan Felix Šulc 4 years ago committed by Milan Felix Šulc
parent e926480481
commit 797fe5d416

4
.gitignore vendored

@ -2,5 +2,5 @@
/node_modules
/packages/**/package-lock.json
# ZEIT
.now
# Vercel
.vercel

@ -1,16 +1,14 @@
<h1 align=center>ZEIT Now PHP</h1>
<h1 align=center>PHP Runtime for <a href="https://vercel.com">Vercel</h1>
<p align=center>
Enjoyable & powerful 🐘 PHP Runtime (<a href="https://php.now.sh">php.now.sh</a>) for ZEIT Now.
Enjoyable & powerful 🐘 PHP Runtime (<a href="https://php.vercel.app">php.vercel.app</a>) for Vercel platform.
<a href="https://vercel.com/new/project?template=https://github.com/juicyfx/vercel-examples/tree/master/php"><img src="https://vercel.com/button"></a>
</p>
<p align=center>
🕹 <a href="https://f3l1x.io">f3l1x.io</a> | 💻 <a href="https://github.com/f3l1x">f3l1x</a> | 🐦 <a href="https://twitter.com/xf3l1x">@xf3l1x</a>
</p>
<p align=center>
<a href="https://www.npmjs.com/package/now-php"><img alt="npm" src="https://img.shields.io/npm/dt/now-php?style=flat-square"></a>
<a href="https://www.npmjs.com/package/now-php"><img alt="npm (latest)" src="https://img.shields.io/npm/v/now-php/latest?style=flat-square"></a>
<a href="https://www.npmjs.com/package/vercel-php"><img src="https://badgen.net/npm/v/vercel-php"></a>
<a href="https://www.npmjs.com/package/vercel-php"><img src="https://badgen.net/npm/dt/vercel-php"></a>
<a href="https://www.npmjs.com/package/vercel-php"><img src="https://badgen.net/github/status/juicyfx/vercel-php/master"></a>
</p>
<p align=center>
@ -21,24 +19,63 @@ Enjoyable & powerful 🐘 PHP Runtime (<a href="https://php.now.sh">php.now.sh</
<a href="https://github.com/phalcon"><img src="https://github.com/phalcon.png" width="128"></a>
</p>
<p align=center><strong>🏋️‍♀️ It works with these frameworks and tools. Discover more at <a href="https://github.com/juicyfx/now-examples">examples</strong>.</p>
<p align=center><strong>🏋️‍♀️ It works with these frameworks and tools. Discover more at <a href="https://github.com/juicyfx/vercel-examples">examples</strong>.</p>
-----
<p align=center>
Made with ❤️ by <a href="https://github.com/f3l1x">@f3l1x</a> 🕹 <a href="https://f3l1x.io">f3l1x.io</a> 🐦 <a href="https://twitter.com/xf3l1x">@xf3l1x</a>
</p>
-----
## 🐣 Versions
Let's picture you want to deploy your awesome microproject written in PHP and you don't know where. You have found [Vercel](https://vercel.com) it's awesome, but for static sites. Not anymore! I would like to introduce you your new best friend `vercel-php`, PHP runtime for Vercel platform.
Most simple example project is this one, using following project structure.
```sh
project
├── api
│ └── index.php
└── now.json
```
First file `api/index.php` is entrypoint of our application. It should be placed in **api** folder, it's very standard location for Vercel.
```php
<?php
phpinfo();
```
Second file `now.json` is pure gold here. Setup your project with configuration like this and voila. That's all.
```json
{
"functions": {
"api/*.php": {
"runtime": "vercel-php@0.1.0"
}
}
}
```
Last thing you have to do is call `now`. If you are more interested take a look at features and usage.
| | Pkg | Tag | Stability | Info |
|----|---------|--------------|-------------|--------------------------|
| ✅ | now-php | latest | production | Rock-solid stable. |
| 🔥 | now-php | canary | testing | For early-adopters. |
| ⚠️ | now-php | experimental | development | Testing and high danger. |
```
# Install it globally
npm i -g now
> Need to know how things are changing? Here is [changelog](./CHANGELOG.md).
# Log in
now login
# Let's fly
now
```
## 🤗 Features
- **Architecture**: PHP development server (🚀 fast enough)
- **PHP version**: 7.4.4
- **PHP version**: 7.4.7
- **Extensions**: apcu, bcmath, brotli, bz2, calendar, Core, ctype, curl, date, dom, ds, exif, fileinfo, filter, ftp, gettext, hash, iconv, igbinary, imap, intl, json, libxml, lua, mbstring, msgpack, mysqli, mysqlnd, openssl, pcntl, pcre, PDO, pdo_mysql, pdo_pgsql, pdo_sqlite, pgsql, phalcon, Phar, protobuf, psr, readline, redis, Reflection, runkit7, session, SimpleXML, soap, sockets, sodium, SPL, sqlite3, standard, swoole, timecop, tokenizer, uuid, xml, xmlreader, xmlrpc, xmlwriter, xsl, Zend OPcache, zlib
- **Speed**: cold ~250ms / warm ~5ms
- **Memory**: ~90mb
@ -48,7 +85,7 @@ Enjoyable & powerful 🐘 PHP Runtime (<a href="https://php.now.sh">php.now.sh</
## ⚙️ Usage
Take a look at [ZEIT's](https://zeit.co) blogpost about [`Serverless Functions`](https://zeit.co/blog/customizing-serverless-functions).
Take a look at [Vercel's](https://vercel.com) blogpost about [`Serverless Functions`](https://vercel.com/blog/customizing-serverless-functions).
You should define `functions` property in `now.json` and list PHP files directly or using wildcard (*).
@ -56,7 +93,16 @@ You should define `functions` property in `now.json` and list PHP files directly
{
"functions": {
"api/*.php": {
"runtime": "now-php@0.0.10"
"runtime": "vercel-php@0.1.0"
},
// Can be list directly also
"api/one.php": {
"runtime": "vercel-php@0.1.0"
},
"api/two.php": {
"runtime": "vercel-php@0.1.0"
}
}
}
@ -68,7 +114,7 @@ If you need to show index page define `routes` properly.
{
"functions": {
"api/index.php": {
"runtime": "now-php@0.0.10"
"runtime": "vercel-php@0.1.0"
}
},
"routes": [
@ -77,13 +123,13 @@ If you need to show index page define `routes` properly.
}
```
Additional function properties are `memory`, `maxDuration`.
Additional function properties are `memory`, `maxDuration`. Learn more about [functions](https://vercel.com/docs/configuration#project/functions).
```json
{
"functions": {
"api/*.php": {
"runtime": "now-php@0.0.10",
"runtime": "vercel-php@0.1.0",
"memory": 3008,
"maxDuration": 500
}
@ -91,36 +137,37 @@ Additional function properties are `memory`, `maxDuration`.
}
```
**Click & Go**
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/juicyfx/now-examples/tree/master/php)
## 👨‍💻`now dev`
For running `now dev` properly, you need to have PHP installed on your computer, [learn more](errors/now-dev-no-local-php.md).
But it's PHP and as you know PHP has built-in development server. It works out of box.
```
php -S localhost:8000 api/index.php
```
## 👀 Demo
- official - https://php.now.sh/
- phpinfo - https://php.jfx.cz/
- extensions - https://php.jfx.cz/ext/
- ini - https://php.jfx.cz/ini/
- JSON API - https://php.jfx.cz/api/users.php
- test - https://php.jfx.cz/test.php
- official - https://php.vercel.app/
- phpinfo - https://phpshow.vercel.app/
- extensions - https://phpshow.vercel.app/ext/
- ini - https://phpshow.vercel.app/ini/
- JSON API - https://phpshow.vercel.app/api/users.php
- test - https://phpshow.vercel.app/test.php
![](docs/phpinfo.png)
## 🎯Examples
- [PHP - fast & simple](https://github.com/juicyfx/now-examples/tree/master/php/)
- [Composer - install dependencies](https://github.com/juicyfx/now-examples/tree/master/php-composer/)
- [Framework - Lumen](https://github.com/juicyfx/now-examples/tree/master/php-framework-lumen/)
- [Framework - Nette](https://github.com/juicyfx/now-examples/tree/master/php-framework-nette/)
- [Framework - Slim](https://github.com/juicyfx/now-examples/tree/master/php-framework-slim/)
- [Framework - Symfony - Microservice](https://github.com/juicyfx/now-examples/tree/master/php-framework-symfony-microservice/)
- [Framework - Phalcon](https://github.com/juicyfx/now-examples/tree/master/php-framework-phalcon/)
- [PHP - fast & simple](https://github.com/juicyfx/vercel-examples/tree/master/php/)
- [Composer - install dependencies](https://github.com/juicyfx/vercel-examples/tree/master/php-composer/)
- [Framework - Lumen](https://github.com/juicyfx/vercel-examples/tree/master/php-framework-lumen/)
- [Framework - Nette](https://github.com/juicyfx/vercel-examples/tree/master/php-framework-nette/)
- [Framework - Slim](https://github.com/juicyfx/vercel-examples/tree/master/php-framework-slim/)
- [Framework - Symfony - Microservice](https://github.com/juicyfx/vercel-examples/tree/master/php-framework-symfony-microservice/)
- [Framework - Phalcon](https://github.com/juicyfx/vercel-examples/tree/master/php-framework-phalcon/)
Browse [more examples](https://github.com/juicyfx/now-examples). 👀
Browse [more examples](https://github.com/juicyfx/vercel-examples). 👀
## 📜 Resources
@ -133,25 +180,26 @@ Browse [more examples](https://github.com/juicyfx/now-examples). 👀
## 🚧 Roadmap
- next-gen PHP runtime ✅
**WIP**
- customize php.ini
- composer.json scripts
**Done**
- next-gen PHP runtime
- Composer
- config.composer: true ✅
- composer.json detection ✅
- zero config ✅
- `now dev`
- rewrite to typescript ✅
- setup CI ✅
- configure php.ini 🚧
- using `builds.config`
- using `build.env` 🚧
- PHP versions
- 7.4 ✅ (used)
- 7.3 ✅
- 7.2 ✅
- config.composer: true
- composer.json detection
- zero config
- `now dev`
- typescript codebase
- github workflows (CI)
- PHP 7.4
**Help wanted**
- create many examples (majority frameworks and other use-cases)
- create examples using vercel-php
## 👨🏻💻CHANGELOG

@ -1,17 +1,18 @@
# It looks like you don't have PHP on your machine.
#### Why This Error Occurred
**Why This Error Occurred**
You ran `now dev` on a machine where PHP is not installed.
For the time being, this runtime requires a local PHP installation to run the runtime locally.
#### Possible Ways to Fix It
**Possible Ways to Fix It**
##### Install PHP to your computer
1. Install PHP to your computer
**OSX**
```
brew install php@7.3
brew install php@7.4
```
**Ubuntu**
@ -21,7 +22,7 @@ apt-get -y install apt-transport-https lsb-release ca-certificates
wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
apt-get update
apt-get install php7.3-cli php7.3-cgi php7.3-json php7.3-curl php7.3-mbstring
apt-get install php7.4-cli php7.4-cgi php7.4-json php7.4-curl php7.4-mbstring
```
**Fedora**
@ -30,10 +31,17 @@ apt-get install php7.3-cli php7.3-cgi php7.3-json php7.3-curl php7.3-mbstring
yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum install https://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum install yum-utils
yum-config-manager --enable remi-php73
yum-config-manager --enable remi-php74
yum update
yum install php73-cli php73-cgi php73-json php73-curl php73-mbstring
yum install php74-cli php74-cgi php74-json php74-curl php74-mbstring
```
##### Check that php is in the path
2. Start PHP built-in Development Server
```sh
php -S localhost:8000 api/index.php
```
**Check that php is in the path**
If you do have installed PHP but still get this error, check that PHP executable is added to the PATH environment variable.

@ -1,5 +1,5 @@
{
"name": "now-php-monorepo",
"name": "vercel-php-monorepo",
"scripts": {
"test-unit": "jest --config unit.jest.config.js"
},

@ -1,4 +1,4 @@
# now-php
# vercel-php
1. Create `api/index.php`.
@ -7,18 +7,18 @@
phpinfo();
```
1. Create `now.json`
2. Create `now.json`
```json
{
"functions": {
"api/index.php": {
"runtime": "now-php@0.0.9"
"runtime": "vercel-php@0.1.0"
}
}
}
```
3. Call `now` and see magic.
3. Call `vercel`, `vc` or `now` and see magic.
4. Discover more in documentation at [Github repository](https://github.com/juicyfx/now-php).
4. Discover more in documentation at [Github repository](https://github.com/juicyfx/vercel-php).

@ -1,15 +1,16 @@
{
"name": "now-php",
"description": "PHP ZEIT Now Runtime",
"version": "0.0.10",
"name": "vercel-php",
"description": "Vercel PHP runtime",
"version": "0.1.0",
"license": "MIT",
"main": "./dist/index.js",
"homepage": "https://github.com/juicyfx/now-php",
"homepage": "https://github.com/juicyfx/vercel-php",
"repository": {
"type": "git",
"url": "https://github.com/juicyfx/now-php.git"
"url": "https://github.com/juicyfx/vercel-php.git"
},
"keywords": [
"vercel",
"zeit",
"now",
"php",
@ -24,17 +25,16 @@
"prepublishOnly": "tsc"
},
"files": [
"dist",
"lib"
"dist"
],
"dependencies": {
"@now-php/lib-74": "latest"
"@libphp/amazon-linux-2-v74": "^0.0.6"
},
"devDependencies": {
"@now/build-utils": "^0.9.4",
"@types/glob": "^7.1.1",
"@types/node": "^10.0.0",
"jest": "^24.8.0",
"typescript": "^3.5.3"
"@vercel/build-utils": "^2.4.0",
"@types/glob": "^7.1.2",
"@types/node": "^12.12.47",
"jest": "^26.0.1",
"typescript": "^3.9.5"
}
}

@ -14,7 +14,8 @@ import {
getIncludedFiles,
getComposerFiles,
ensureLocalPhp,
modifyPhpIni
modifyPhpIni,
readRuntimeFile
} from './utils';
// ###########################
@ -47,7 +48,7 @@ export async function build({
console.log(`
It looks like you don't have PHP on your machine.
Learn more about how to run now dev on your machine.
https://err.sh/juicyfx/now-php/now-dev-no-local-php
https://err.sh/juicyfx/vercel-php/now-dev-no-local-php
`)
}
}
@ -56,33 +57,37 @@ export async function build({
const userFiles = rename(includedFiles, name => path.join('user', name));
// Bridge files contains PHP bins and libs
let bridgeFiles: Files = {};
let runtimeFiles: RuntimeFiles = {};
// Append PHP files (bins + shared object)
bridgeFiles = { ...bridgeFiles, ...await getPhpFiles({ meta }) };
runtimeFiles = { ...runtimeFiles, ...await getPhpFiles() };
// Append launcher files (server for lambda, cgi for now dev)
bridgeFiles = { ...bridgeFiles, ...getLauncherFiles({ meta }) };
runtimeFiles = { ...runtimeFiles, ...getLauncherFiles({ meta }) };
// Append custom directives into php.ini
if (config['php.ini']) {
bridgeFiles['php/php.ini'] = modifyPhpIni((bridgeFiles['php/php.ini'] as FileBlob), (config['php.ini'] as PhpIni));
runtimeFiles['php/php.ini'] = modifyPhpIni((runtimeFiles['php/php.ini'] as FileBlob), (config['php.ini'] as PhpIni));
}
// Show some debug notes during build
if (process.env.NOW_PHP_DEBUG === '1') {
console.log('🐘 Entrypoint:', entrypoint);
console.log('🐘 Config:', config);
console.log('🐘 Work path:', workPath);
console.log('🐘 Meta:', meta);
console.log('🐘 User files:', Object.keys(userFiles));
console.log('🐘 Bridge files:', Object.keys(bridgeFiles));
console.log('🐘 PHP: php.ini', (bridgeFiles['php/php.ini'] as FileBlob).data.toString());
console.log('🐘 Runtime files:', Object.keys(runtimeFiles));
console.log('🐘 PHP: php.ini', await readRuntimeFile(runtimeFiles['php/php.ini']));
}
const lambda = await createLambda({
files: {
// Located at /var/task/user
...userFiles,
...bridgeFiles
// Located at /var/task/php (php bins + ini + modules)
// Located at /var/task/lib (shared libs)
...runtimeFiles
},
handler: 'launcher.launcher',
runtime: 'nodejs12.x',
@ -95,7 +100,7 @@ export async function build({
return { output: lambda };
};
export async function prepareCache({ workPath }: PrepareCacheOptions): Promise<Files> {
export async function prepareCache({ workPath }: PrepareCacheOptions): Promise<RuntimeFiles> {
return {
// Composer
...(await glob('vendor/**', workPath)),

@ -3,11 +3,11 @@ import { spawn, ChildProcess, SpawnOptions } from 'child_process';
import net from 'net';
import {
getPhpDir,
getUserDir,
normalizeEvent,
transformFromAwsRequest,
transformToAwsResponse,
isDev,
getUserDir
isDev
} from './helpers';
let server: ChildProcess;
@ -47,7 +47,7 @@ async function startServer(entrypoint: string): Promise<ChildProcess> {
options,
);
server.stderr.on('data', data => {
server.stderr?.on('data', data => {
console.error(`🐘STDERR: ${data.toString()}`);
});
@ -59,7 +59,7 @@ async function startServer(entrypoint: string): Promise<ChildProcess> {
console.error(`🐘 PHP Built-In Server process errored ${err}`);
});
await whenPortOpens(8000, 400);
await whenPortOpens(8000, 500);
process.on('exit', () => {
server.kill();
@ -123,7 +123,7 @@ function whenPortOpensCallback(port: number, attempts: number, cb: (error?: stri
if (!attempts) return cb(error);
setTimeout(() => {
whenPortOpensCallback(port, attempts - 1, cb);
}, 50);
}, 10);
});
client.on('connect', () => {
client.destroy();
@ -154,15 +154,15 @@ exports.launcher = launcher;
// (async function () {
// const response = await launcher({
// Action: "test",
// httpMethod: "GET",
// body: "",
// path: "/",
// host: "https://zeit.co",
// headers: {
// 'HOST': 'zeit.co'
// },
// encoding: null,
// Action: "test",
// httpMethod: "GET",
// body: "",
// path: "/",
// host: "https://vercel.com",
// headers: {
// 'HOST': 'vercel.com'
// },
// encoding: null,
// });
// console.log(response);

@ -29,7 +29,7 @@ function createCGIReq({ entrypoint, path, host, method, headers }: CgiInput): Cg
GATEWAY_INTERFACE: "CGI/1.1",
SERVER_PROTOCOL: "HTTP/1.1",
PATH: process.env.PATH,
SERVER_SOFTWARE: "ZEIT Now PHP",
SERVER_SOFTWARE: "Vercel PHP",
LD_LIBRARY_PATH: process.env.LD_LIBRARY_PATH
};
@ -129,6 +129,24 @@ function query({ entrypoint, path, host, headers, method, body }: PhpInput): Pro
options,
);
// Validate pipes [stdin]
if (!php.stdin) {
console.error(`🐘 Fatal error. PHP CGI child process has no stdin.`);
process.exit(253);
}
// Validate pipes [stdout]
if (!php.stdout) {
console.error(`🐘 Fatal error. PHP CGI child process has no stdout.`);
process.exit(254);
}
// Validate pipes [stderr]
if (!php.stderr) {
console.error(`🐘 Fatal error. PHP CGI child process has no stderr.`);
process.exit(255);
}
// Output
php.stdout.on('data', data => {
chunks.push(data);
@ -185,9 +203,9 @@ exports.launcher = launcher;
// httpMethod: "GET",
// body: "",
// path: "/",
// host: "https://zeit.co",
// host: "https://vercel.com",
// headers: {
// 'HOST': 'zeit.co'
// 'HOST': 'vercel.com'
// },
// encoding: null,
// });

@ -34,6 +34,24 @@ function query({ entrypoint, body }: PhpInput): Promise<PhpOutput> {
options,
);
// Validate pipes [stdin]
if (!php.stdin) {
console.error(`🐘 Fatal error. PHP CLI child process has no stdin.`);
process.exit(253);
}
// Validate pipes [stdout]
if (!php.stdout) {
console.error(`🐘 Fatal error. PHP CLI child process has no stdout.`);
process.exit(254);
}
// Validate pipes [stderr]
if (!php.stderr) {
console.error(`🐘 Fatal error. PHP CLI child process has no stderr.`);
process.exit(255);
}
// Output
php.stdout.on('data', data => {
chunks.push(data);
@ -87,9 +105,9 @@ exports.launcher = launcher;
// httpMethod: "GET",
// body: "",
// path: "/",
// host: "https://zeit.co",
// host: "https://vercel.com",
// headers: {
// 'HOST': 'zeit.co'
// 'HOST': 'vercel.com'
// },
// encoding: null,
// });

@ -1,11 +1,11 @@
type Headers = { [k: string]: string | string[] | undefined };
interface Files {
[filePath: string]: import('@now/build-utils').File;
interface RuntimeFiles {
[filePath: string]: import('@vercel/build-utils').File;
}
interface MetaOptions {
meta: import('@now/build-utils').Meta;
meta: import('@vercel/build-utils').Meta;
}
interface AwsRequest {

@ -3,19 +3,20 @@ import { spawn } from 'child_process';
import {
glob,
download,
File,
FileFsRef,
FileBlob,
BuildOptions
} from '@now/build-utils';
import { getLibFiles } from "@now-php/lib-74";
} from '@vercel/build-utils';
import * as libphp from "@libphp/amazon-linux-2-v74";
const PHP_PKG = path.dirname(require.resolve('@now-php/lib-74/package.json'));
const PHP_PKG = path.dirname(require.resolve('@libphp/amazon-linux-2-v74/package.json'));
const PHP_BIN_DIR = path.join(PHP_PKG, "native/php");
const PHP_MODULES_DIR = path.join(PHP_BIN_DIR, "modules");
const PHP_LIB_DIR = path.join(PHP_PKG, "native/lib");
const COMPOSER_BIN = path.join(PHP_BIN_DIR, "composer");
export async function getIncludedFiles({ files, entrypoint, workPath, config, meta }: BuildOptions): Promise<Files> {
export async function getIncludedFiles({ files, entrypoint, workPath, config, meta }: BuildOptions): Promise<RuntimeFiles> {
// Download all files to workPath
const downloadedFiles = await download(files, workPath, meta);
@ -38,24 +39,28 @@ export async function getIncludedFiles({ files, entrypoint, workPath, config, me
return includedFiles;
}
export async function getPhpFiles({ meta }: MetaOptions): Promise<Files> {
const files = await getLibFiles();
export async function getPhpFiles(): Promise<RuntimeFiles> {
const files = await libphp.getFiles();
if (meta && meta.isDev) {
delete files['php/php'];
delete files['php/php-fpm'];
delete files['php/php-fpm.ini'];
} else {
delete files['php/php-cgi'];
delete files['php/php-fpm'];
delete files['php/php-fpm.ini'];
// Drop CGI + FPM from libphp, it's not needed for our case
delete files['php/php-cgi'];
delete files['php/php-fpm'];
delete files['php/php-fpm.ini'];
const runtimeFiles: RuntimeFiles = {};
// Map from @libphp to Vercel's File objects
for (const [filename, filepath] of Object.entries(files)) {
runtimeFiles[filename] = new FileFsRef({
fsPath: filepath
})
}
return files;
}
// Set some bins executable
(runtimeFiles['php/php'] as FileFsRef).mode = 33261; // 0755;
(runtimeFiles['php/composer'] as FileFsRef).mode = 33261; // 0755;
export async function getPhpLibFiles(): Promise<Files> {
return await getLibFiles();
return runtimeFiles;
}
export function modifyPhpIni(phpini: FileBlob, directives: PhpIni): FileBlob {
@ -71,8 +76,8 @@ export function modifyPhpIni(phpini: FileBlob, directives: PhpIni): FileBlob {
return phpini;
}
export function getLauncherFiles({ meta }: MetaOptions): Files {
const files: Files = {
export function getLauncherFiles({ meta }: MetaOptions): RuntimeFiles {
const files: RuntimeFiles = {
'helpers.js': new FileFsRef({
fsPath: path.join(__dirname, 'launchers/helpers.js'),
})
@ -91,7 +96,7 @@ export function getLauncherFiles({ meta }: MetaOptions): Files {
return files;
}
export async function getComposerFiles(workPath: string): Promise<Files> {
export async function getComposerFiles(workPath: string): Promise<RuntimeFiles> {
console.log('🐘 Installing Composer deps.');
// Install composer dependencies
@ -154,6 +159,14 @@ export async function ensureLocalPhp(): Promise<boolean> {
}
}
export async function readRuntimeFile(file: File): Promise<string> {
const blob = await FileBlob.fromStream({
stream: file.toStream(),
});
return blob.data.toString();
}
function spawnAsync(command: string, args: any[], cwd?: string, opts = {}) {
return new Promise((resolve, reject) => {
const child = spawn(command, args, {

@ -1,11 +1,10 @@
const cgi = require('./../../../dist/launchers/cgi');
test('create CGI request', () => {
const request = {
entrypoint: "index.php",
path: "/index.php",
host: "https://zeit.co",
host: "https://vercel.com",
method: "GET",
headers: {}
};
@ -26,7 +25,7 @@ test('create CGI request', () => {
expect(env).toHaveProperty("QUERY_STRING", '');
expect(env).toHaveProperty("GATEWAY_INTERFACE", 'CGI/1.1');
expect(env).toHaveProperty("SERVER_PROTOCOL", 'HTTP/1.1');
expect(env).toHaveProperty("SERVER_SOFTWARE", 'ZEIT Now PHP');
expect(env).toHaveProperty("SERVER_SOFTWARE", 'Vercel PHP');
expect(env).toHaveProperty("PATH", process.env.PATH);
expect(env).toHaveProperty("LD_LIBRARY_PATH", process.env.LD_LIBRARY_PATH);
expect(env).toHaveProperty("CUSTOM_VALUE", process.env.CUSTOM_VALUE);

@ -1,13 +1,13 @@
const url = require('url');
test('url.parse search & query are string', () => {
const { search, query } = url.parse('https://zeit.co/?foo=bar&foo2=baz#foo');
const { search, query } = url.parse('https://vercel.com/?foo=bar&foo2=baz#foo');
expect(search).toBe('?foo=bar&foo2=baz');
expect(query).toBe('foo=bar&foo2=baz');
});
test('url.parse search string, query object', () => {
const { search, query } = url.parse('https://zeit.co/?foo=bar&foo2=baz#foo', true);
const { search, query } = url.parse('https://vercel.com/?foo=bar&foo2=baz#foo', true);
expect(search).toBe('?foo=bar&foo2=baz');
expect(query).toMatchObject({ foo: 'bar', 'foo2': 'baz' });
});

@ -2,20 +2,28 @@
"compilerOptions": {
"strict": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"lib": [
"esnext"
"ES2019"
],
"target": "esnext",
"module": "commonjs",
"target": "ES2019",
"module": "CommonJS",
"outDir": "dist",
"sourceMap": false,
"declaration": true,
"noImplicitAny": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true,
"typeRoots": [
"./node_modules/@types"
]
},
"include": [
"src/**/*"
"src/**/*.ts"
],
"exclude": [
"dist",

@ -1,7 +1,4 @@
{
"version": 2,
"name": "now-caddy",
"scope": "juicyfx",
"functions": {
"api/*.php": {
"runtime": "@now-php/caddy@0.0.1-canary.5"

@ -1,5 +1,5 @@
# PHP
/vendor
# ZEIT
.now
# Vercel
.vercel

@ -1,10 +1,15 @@
{
"functions": {
"api/index.php": {
"runtime": "now-php@0.0.11-canary.1"
"runtime": "vercel-php@0.0.8"
}
},
"routes": [
{ "src": "/(.*)", "dest": "/api/index.php" }
]
],
"build": {
"env": {
"NOW_PHP_DEBUG": "1"
}
}
}

@ -1,2 +1,2 @@
# ZEIT
.now
# Vercel
.vercel

@ -1,10 +1,7 @@
{
"version": 2,
"name": "now-php",
"scope": "juicyfx",
"functions": {
"api/**/*.php": {
"runtime": "now-php@0.0.11-canary.1"
"runtime": "vercel-php@0.0.8"
}
},
"routes": [

@ -1,2 +1,2 @@
# ZEIT
.now
# Vercel
.vercel

@ -1,10 +1,7 @@
{
"version": 2,
"name": "now-test",
"scope": "juicyfx",
"functions": {
"api/*.php": {
"runtime": "now-php@0.0.9"
"runtime": "vercel-php@0.0.3"
}
},
"routes": [

@ -166,7 +166,7 @@ function fetchTokenWithRetry(url, retries = 3) {
}
async function fetchApi(url, opts = {}) {
const apiHost = process.env.API_HOST || 'api.zeit.co';
const apiHost = process.env.API_HOST || 'api.vercel.com';
const urlWithHost = `https://${apiHost}${url}`;
const { method = 'GET', body } = opts;

Loading…
Cancel
Save