-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f0a0362
commit 681fac2
Showing
13 changed files
with
789 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { shouldServe, BuildV3, PrepareCache } from '@vercel/build-utils'; | ||
export declare const version = 3; | ||
export declare const build: BuildV3; | ||
export declare const prepareCache: PrepareCache; | ||
export { shouldServe }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.shouldServe = exports.prepareCache = exports.build = exports.version = void 0; | ||
const path_1 = __importDefault(require("path")); | ||
const build_utils_1 = require("@vercel/build-utils"); | ||
Object.defineProperty(exports, "shouldServe", { enumerable: true, get: function () { return build_utils_1.shouldServe; } }); | ||
const utils_1 = require("./utils"); | ||
const COMPOSER_FILE = process.env.COMPOSER || 'composer.json'; | ||
// ########################### | ||
// EXPORTS | ||
// ########################### | ||
exports.version = 3; | ||
const build = async ({ files, entrypoint, workPath, config = {}, meta = {}, }) => { | ||
// Check if now dev mode is used | ||
if (meta.isDev) { | ||
console.log(` | ||
🐘 vercel dev is not supported right now. | ||
Please use PHP built-in development server. | ||
php -S localhost:8000 api/index.php | ||
`); | ||
process.exit(255); | ||
} | ||
console.log('🐘 Downloading user files'); | ||
// Collect user provided files | ||
const userFiles = await (0, build_utils_1.download)(files, workPath, meta); | ||
console.log('🐘 Downloading PHP runtime files'); | ||
// Collect runtime files containing PHP bins and libs | ||
const runtimeFiles = { | ||
// Append PHP files (bins + shared object) | ||
...await (0, utils_1.getPhpFiles)(), | ||
// Append launcher files (builtin server, common helpers) | ||
...(0, utils_1.getLauncherFiles)(), | ||
}; | ||
// If composer.json is provided try to | ||
// - install deps | ||
// - run composer scripts | ||
if (userFiles[COMPOSER_FILE]) { | ||
// Install dependencies (vendor is collected bellow, see harvestedFiles) | ||
await (0, utils_1.runComposerInstall)(workPath); | ||
// Run composer scripts (created files are collected bellow, , see harvestedFiles) | ||
await (0, utils_1.runComposerScripts)(userFiles[COMPOSER_FILE], workPath); | ||
} | ||
// Append PHP directives into php.ini | ||
if (userFiles['api/php.ini']) { | ||
const phpini = await (0, utils_1.modifyPhpIni)(userFiles, runtimeFiles); | ||
if (phpini) { | ||
runtimeFiles['php/php.ini'] = phpini; | ||
} | ||
} | ||
// Collect user files, files creating during build (composer vendor) | ||
// and other files and prefix them with "user" (/var/task/user folder). | ||
const harverstedFiles = (0, build_utils_1.rename)(await (0, build_utils_1.glob)('**', { | ||
cwd: workPath, | ||
ignore: [ | ||
'.vercel/**', | ||
...((config === null || config === void 0 ? void 0 : config.excludeFiles) | ||
? Array.isArray(config.excludeFiles) | ||
? config.excludeFiles | ||
: [config.excludeFiles] | ||
: [ | ||
'node_modules/**', | ||
'now.json', | ||
'.nowignore', | ||
'vercel.json', | ||
'.vercelignore', | ||
]), | ||
], | ||
}), name => path_1.default.join('user', name)); | ||
// 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(harverstedFiles)); | ||
console.log('🐘 Runtime files:', Object.keys(runtimeFiles)); | ||
console.log('🐘 PHP: php.ini', await (0, utils_1.readRuntimeFile)(runtimeFiles['php/php.ini'])); | ||
} | ||
console.log('🐘 Creating lambda'); | ||
const nodeVersion = await (0, build_utils_1.getNodeVersion)(workPath); | ||
const lambda = new build_utils_1.Lambda({ | ||
files: { | ||
// Located at /var/task/user | ||
...harverstedFiles, | ||
// Located at /var/task/php (php bins + ini + modules) | ||
// Located at /var/task/lib (shared libs) | ||
...runtimeFiles | ||
}, | ||
handler: 'launcher.launcher', | ||
runtime: nodeVersion.runtime, | ||
environment: { | ||
NOW_ENTRYPOINT: entrypoint, | ||
NOW_PHP_DEV: meta.isDev ? '1' : '0' | ||
}, | ||
}); | ||
return { output: lambda }; | ||
}; | ||
exports.build = build; | ||
const prepareCache = async ({ workPath }) => { | ||
return { | ||
// Composer | ||
...(await (0, build_utils_1.glob)('vendor/**', workPath)), | ||
...(await (0, build_utils_1.glob)('composer.lock', workPath)), | ||
// NPM | ||
...(await (0, build_utils_1.glob)('node_modules/**', workPath)), | ||
...(await (0, build_utils_1.glob)('package-lock.json', workPath)), | ||
...(await (0, build_utils_1.glob)('yarn.lock', workPath)), | ||
}; | ||
}; | ||
exports.prepareCache = prepareCache; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const http_1 = __importDefault(require("http")); | ||
const child_process_1 = require("child_process"); | ||
const net_1 = __importDefault(require("net")); | ||
const helpers_1 = require("./helpers"); | ||
const path_1 = require("path"); | ||
let server; | ||
async function startServer(entrypoint) { | ||
var _a, _b, _c; | ||
// Resolve document root and router | ||
const router = entrypoint; | ||
const docroot = (0, path_1.join)((0, helpers_1.getUserDir)(), (_a = process.env.VERCEL_PHP_DOCROOT) !== null && _a !== void 0 ? _a : ''); | ||
console.log(`🐘 Spawning: PHP Built-In Server at ${docroot} (document root) and ${router} (router)`); | ||
// php spawn options | ||
const options = { | ||
stdio: ['pipe', 'pipe', 'pipe'], | ||
env: { | ||
...process.env, | ||
LD_LIBRARY_PATH: `/var/task/lib:${process.env.LD_LIBRARY_PATH}` | ||
} | ||
}; | ||
// now vs now-dev | ||
if (!(0, helpers_1.isDev)()) { | ||
options.env.PATH = `${(0, helpers_1.getPhpDir)()}:${process.env.PATH}`; | ||
options.cwd = (0, helpers_1.getPhpDir)(); | ||
} | ||
else { | ||
options.cwd = (0, helpers_1.getUserDir)(); | ||
} | ||
// We need to start PHP built-in server with following setup: | ||
// php -c php.ini -S ip:port -t /var/task/user /var/task/user/foo/bar.php | ||
// | ||
// Path to document root lambda task folder with user prefix, because we move all | ||
// user files to this folder. | ||
// | ||
// Path to router is absolute path, because CWD is different. | ||
// | ||
server = (0, child_process_1.spawn)('php', ['-c', 'php.ini', '-S', '127.0.0.1:8000', '-t', docroot, router], options); | ||
(_b = server.stdout) === null || _b === void 0 ? void 0 : _b.on('data', data => { | ||
console.log(`🐘STDOUT: ${data.toString()}`); | ||
}); | ||
(_c = server.stderr) === null || _c === void 0 ? void 0 : _c.on('data', data => { | ||
console.error(`🐘STDERR: ${data.toString()}`); | ||
}); | ||
server.on('close', function (code, signal) { | ||
console.log(`🐘 PHP Built-In Server process closed code ${code} and signal ${signal}`); | ||
}); | ||
server.on('error', function (err) { | ||
console.error(`🐘 PHP Built-In Server process errored ${err}`); | ||
}); | ||
await whenPortOpens(8000, 500); | ||
process.on('exit', () => { | ||
server.kill(); | ||
}); | ||
return server; | ||
} | ||
async function query({ entrypoint, uri, path, headers, method, body }) { | ||
if (!server) { | ||
await startServer(entrypoint); | ||
} | ||
return new Promise(resolve => { | ||
const options = { | ||
hostname: '127.0.0.1', | ||
port: 8000, | ||
path, | ||
method, | ||
headers, | ||
}; | ||
console.log(`🐘 Accessing ${uri}`); | ||
console.log(`🐘 Querying ${path}`); | ||
const req = http_1.default.request(options, (res) => { | ||
const chunks = []; | ||
res.on('data', (data) => { | ||
chunks.push(data); | ||
}); | ||
res.on('end', () => { | ||
resolve({ | ||
statusCode: res.statusCode || 200, | ||
headers: res.headers, | ||
body: Buffer.concat(chunks) | ||
}); | ||
}); | ||
}); | ||
req.on('error', (error) => { | ||
console.error('🐘 PHP Built-In Server HTTP errored', error); | ||
resolve({ | ||
body: Buffer.from(`PHP Built-In Server HTTP error: ${error}`), | ||
headers: {}, | ||
statusCode: 500 | ||
}); | ||
}); | ||
if (body) { | ||
req.write(body); | ||
} | ||
req.end(); | ||
}); | ||
} | ||
function whenPortOpensCallback(port, attempts, cb) { | ||
const client = net_1.default.connect(port, '127.0.0.1'); | ||
client.on('error', (error) => { | ||
if (!attempts) | ||
return cb(error); | ||
setTimeout(() => { | ||
whenPortOpensCallback(port, attempts - 1, cb); | ||
}, 10); | ||
}); | ||
client.on('connect', () => { | ||
client.destroy(); | ||
cb(); | ||
}); | ||
} | ||
function whenPortOpens(port, attempts) { | ||
return new Promise((resolve, reject) => { | ||
whenPortOpensCallback(port, attempts, (error) => { | ||
if (error) { | ||
reject(error); | ||
} | ||
else { | ||
resolve(); | ||
} | ||
}); | ||
}); | ||
} | ||
async function launcher(event) { | ||
const awsRequest = (0, helpers_1.normalizeEvent)(event); | ||
const input = await (0, helpers_1.transformFromAwsRequest)(awsRequest); | ||
const output = await query(input); | ||
return (0, helpers_1.transformToAwsResponse)(output); | ||
} | ||
exports.launcher = launcher; | ||
// (async function () { | ||
// const response = await launcher({ | ||
// Action: "test", | ||
// httpMethod: "GET", | ||
// body: "", | ||
// path: "/", | ||
// host: "https://vercel.com", | ||
// headers: { | ||
// 'HOST': 'vercel.com' | ||
// }, | ||
// encoding: null, | ||
// }); | ||
// console.log(response); | ||
// })(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {}; |
Oops, something went wrong.