cyclicapp ERR deploy laravel9+inertiajs - deployment

hye,
since yesterday I try to deploy my application on cyclicapp but it gives me this error:
Could not resolve '../../vendor/tightenco/ziggy/dist/vue.m' from resources/js/app.js
error during build:
package.json:
{
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"start": "npm start"
},
"devDependencies": {
"#inertiajs/inertia": "^0.11.0",
"#inertiajs/inertia-vue3": "^0.6.0",
"#inertiajs/progress": "^0.2.7",
"#tailwindcss/forms": "^0.5.2",
"#tailwindcss/typography": "^0.5.2",
"#vitejs/plugin-vue": "^3.0.0",
"autoprefixer": "^10.4.7",
"axios": "^0.27",
"laravel-vite-plugin": "^0.6.0",
"lodash": "^4.17.19",
"postcss": "^8.4.14",
"sass": "^1.55.0",
"tailwindcss": "^3.1.0",
"vite": "^3.0.0",
"vue": "^3.2.31"
},
"dependencies": {
"#vitejs/plugin-vue": "^3.1.0",
"vue": "^3.2.36",
"vue-loader": "^17.0.0"
}
}
vite.config.js :
import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
import vue from "#vitejs/plugin-vue";
export default defineConfig({
plugins: [
laravel({
input: "resources/js/app.js",
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
});
app.js:
import "./bootstrap";
import "../css/app.css";
import { createApp, h } from "vue";
import { createInertiaApp } from "#inertiajs/inertia-vue3";
import { InertiaProgress } from "#inertiajs/progress";
import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers";
import { ZiggyVue } from "../../vendor/tightenco/ziggy/dist/vue.m";
const appName =
window.document.getElementsByTagName("title")[0]?.innerText || "Laravel";
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) =>
resolvePageComponent(
`./Pages/${name}.vue`,
import.meta.glob("./Pages/**/*.vue")
),
setup({ el, app, props, plugin }) {
return createApp({ render: () => h(app, props) })
.use(plugin)
.use(ZiggyVue, Ziggy)
.mount(el);
},
});
InertiaProgress.init({ color: "#4B5563" });
myproject is a laravel9 + inertia js + vue3 + jetstream
any help please

Related

Why do I keep getting this error when I try to connect mongodb to my next.js project

I keep getting this error when I try to connect my mongodb to my user api route file. I don't know what is going wrong and I do not know how to solve it, but I'm sure this is what my teacher wrote on his computer and it worked without any errors.
This is what my dbconnection file looks like
// MongoDB Connection
import mongoose from "mongoose";
if (!process.env.MONGODB_URL) {
throw new Error("Please define the MONGODB_URL environment variable inside .env.local");
}
let cached = global.mongoose;
if (!cached) {
cached = global.mongoose = { conn: null, promise: null };
}
async function dbConnect() {
if (cached.conn) {
return cached.conn;
}
if (!cached.promise) {
const opts = {
bufferCommands: false,
};
cached.promise = mongoose.connect(process.env.MONGODB_URL, opts).then((mongoose) => {
return mongoose;
});
}
cached.conn = await cached.promise;
return cached.conn;
}
export default dbConnect;
And this is how I define my user routes to the /api/user endpoint
import Users from "../../../api/models/Users";
import dbConnect from "../../util/mongo";
export default async function handler(req, res) {
const { method } = req;
dbConnect()
switch (method) {
case "GET":
try {
const res = await Users.find();
res.status(200).json(res);
} catch (error) {
res.status(500).json(error);
}
break;
case "POST":
console.log(POST);
break;
case "PUT":
console.log(PUT);
break;
case "Delete":
console.log(Delete);
break;
}
}
my package.json file is thus:
"name": "smooon",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"axios": "^1.1.0",
"mongodb": "^3.7.3",
"mongodb-client-encryption": "^2.3.0",
"mongoose": "^6.6.5",
"next": "12.3.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-snowfall": "^1.2.1",
"react-spinners-kit": "^1.9.1",
"react-tinder-card": "^1.5.4"
},
"devDependencies": {
"eslint": "8.23.1",
"eslint-config-next": "12.3.1"
}
}

#babel/plugin-transform-runtime is allowing esm imports in cjs files

I'm using Rollup.js, and babel to bundle my js library. I noticed that my dist cjs files are referencing esm core-js helpers in addition to the correct cjs helpers.
For instance, in my final cjs file, I see a reference to both var _extends$2 = require('#babel/runtime-corejs3/helpers/esm/extends'); and var _extends$3 = require('#babel/runtime-corejs3/helpers/extends'); when I run yarn build:lib.
Has anyone seen this before? Been racking my brain and haven't been able to find what is the cause of this.
For reference,
package.json (condensed for brevity)
{
"name": "my-platform",
"version": "0.1.0",
"description": "",
"main": "dist/index.cjs",
"module": "dist/my-platform.esm.js",
"types": "dist/index.d.ts",
"engines": {
"node": ">=10.18.0"
},
"scripts": {
"build:lib": "rollup -c",
"build:docs": "build-storybook",
"build": "concurrently \"yarn build:lib\" \"yarn build:docs\"",
},
"sideEffects": false,
"peerDependencies": {
"#emotion/core": "^10.0.22",
"react": "^16.12.0 || 17"
},
"resolutions": {
"git-raw-commits": "2.0.8"
},
"devDependencies": {
"#babel/cli": "^7.12.7",
"#babel/core": "^7.12.7",
"#babel/plugin-transform-runtime": "^7.12.10",
"#babel/preset-env": "^7.12.7",
"#babel/preset-react": "^7.12.7",
"#babel/preset-typescript": "^7.12.7",
"#commitlint/cli": "^11.0.0",
"#commitlint/config-conventional": "^11.0.0",
"#emotion/babel-preset-css-prop": "^10.0.23",
"#emotion/core": "^10.0.22",
"#jest/globals": "^26.6.2",
"#rollup/plugin-babel": "^5.2.2",
"#rollup/plugin-commonjs": "^17.1.0",
"#rollup/plugin-json": "^4.1.0",
"#rollup/plugin-node-resolve": "^11.1.0",
"#rollup/plugin-replace": "^2.3.4",
"#typescript-eslint/eslint-plugin": "^4.14.0",
"#typescript-eslint/parser": "^4.14.0",
"babel-jest": "^26.6.3",
"babel-loader": "^8.0.6",
"babel-plugin-annotate-pure-calls": "^0.4.0",
"babel-plugin-dev-expression": "^0.2.2",
"babel-plugin-macros": "^3.0.1",
"concurrently": "^5.0.1",
"fs-extra": "^9.1.0",
"husky": ">=4.3.8",
"jest": "^26.6.3",
"jest-emotion": "^10.0.26",
"jest-junit": "^12.0.0",
"path": "^0.12.7",
"prettier": "^2.2.1",
"react": "^17.0.1",
"react-docgen-typescript-loader": "^3.4.0",
"react-dom": "^17.0.1",
"react-test-renderer": "^17.0.1",
"regenerator-runtime": "^0.13.3",
"rollup": "^2.38.1",
"rollup-plugin-delete": "^2.0.0",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.29.0",
"stylelint": "^13.9.0",
"stylelint-config-prettier": "^8.0.0",
"stylelint-config-standard": "^20.0.0",
"tsdx": "^0.14.1",
"tslib": "^2.1.0",
"typescript": "^4.1.3"
},
"dependencies": {
"#babel/runtime-corejs3": "~7.12.18"
}
}
babel.config
module.exports = (api) => {
const isTest = api.env('test');
api.cache.forever();
return {
presets: [
[
'#babel/preset-env',
isTest ? { targets: { node: 'current' } } : { modules: false },
],
'#babel/preset-react',
'#babel/preset-typescript',
'#emotion/babel-preset-css-prop',
],
plugins: [
'annotate-pure-calls',
'dev-expression',
'macros',
[
'#babel/plugin-transform-runtime',
{
corejs: 3,
version: '^7.12.5',
},
],
],
comments: false,
};
};
rollup.config.js
import fs from 'fs-extra';
import path from 'path';
import resolve from '#rollup/plugin-node-resolve';
import babel from '#rollup/plugin-babel';
import typescript from 'rollup-plugin-typescript2';
import json from '#rollup/plugin-json';
import commonjs from '#rollup/plugin-commonjs';
import replace from '#rollup/plugin-replace';
import del from 'rollup-plugin-delete';
import { terser } from 'rollup-plugin-terser';
import { DEFAULT_EXTENSIONS } from '#babel/core';
import pkg from './package.json';
const external = [
...Object.keys(pkg.peerDependencies || {}),
...Object.keys(pkg.dependencies || {}),
];
const makeExternalPredicate = (externalArr) => {
if (externalArr.length === 0) {
return () => false;
}
const pattern = new RegExp(`^(${externalArr.join('|')})($|/)`);
return (id) => pattern.test(id);
};
const configTerser = () =>
terser({
output: { comments: false },
compress: {
keep_infinity: true,
pure_getters: true,
passes: 10,
},
ecma: 5,
toplevel: true,
warnings: true,
});
function writeCjsEntryFile() {
const baseLine = `module.exports = require('./my-platform`;
const contents = `
'use strict'
if (process.env.NODE_ENV === 'production') {
${baseLine}.cjs.production.min.js')
} else {
${baseLine}.cjs.development.js')
}
`;
return fs.outputFile(path.join(__dirname, './dist', 'index.js'), contents);
}
const getEnv = (format, minify) => {
switch (format) {
case 'cjs':
return minify ? 'production.' : 'development.';
default:
return '';
}
};
const makeOutput = (format, minify) => ({
file: `dist/my-platform.${format}.${getEnv(format, minify)}${
minify ? 'min.' : ''
}js`,
esModule: true,
exports: 'named',
format,
freeze: false,
sourcemap: true,
plugins: [
minify && configTerser(),
format === 'cjs' && {
writeBundle: writeCjsEntryFile,
},
],
});
let currentBundleIndex = 0;
const makeRollupConfig = (minify, format) => {
return {
input: './src/index.ts',
output: makeOutput(format, minify),
plugins: [
currentBundleIndex === 1 && del({ targets: 'dist/**' }),
minify &&
replace({
'process.env.NODE_ENV': JSON.stringify('production'),
}),
resolve({
extensions: ['.js', '.jsx', '.ts', '.tsx'],
}),
json(),
typescript({
typescript: require('typescript'),
tsconfigOverride: {
exclude: [
'**/*.spec.ts',
'**/*.test.ts',
'**/*.stories.ts',
'**/*.spec.tsx',
'**/*.test.tsx',
'**/*.stories.tsx',
'node_modules',
'test',
],
compilerOptions: {
target: 'esnext',
rootDir: 'src',
},
},
}),
commonjs(),
babel({
babelHelpers: 'runtime',
exclude: 'node_modules/**',
extensions: [...DEFAULT_EXTENSIONS, '.ts', '.tsx'],
presets: [
[
'#babel/preset-env',
{
modules: false,
},
],
],
plugins: [
[
'#babel/plugin-transform-runtime',
{
useESModules: format === 'esm',
corejs: 3,
version: '^7.12.5',
},
],
],
}),
],
external: makeExternalPredicate(external),
};
};
export default [
makeRollupConfig(false, 'cjs'),
makeRollupConfig(false, 'esm'),
makeRollupConfig(true, 'cjs'),
];
Any help would be appreciated. Thanks!

Rollup.js building error with material-ui layout-grid component included

I integrated Material UI into my Svelte project with help of "Svelte Material UI" package.
But it don't contains Material layout-grid component.
I installed it separately using yarn add "#material/layout-grid" command.
But now I'm getting error during build process:
[!] (plugin postcss) Error: Invalid CSS after "...ch $size in map": expected expression (e.g. 1px, bold), was ".keys(variables.$co"
node_modules/#material/layout-grid/mdc-layout-grid.scss
Error: Invalid CSS after "...ch $size in map": expected expression (e.g. 1px, bold), was ".keys(variables.$co"
at options.error (/media/hdd-home/d/WebServers/home/spadmin.org/public_html/todoapp/node_modules/node-sass/lib/index.js:291:26)
So, I gave up resolving it myself.
The project package.json:
{
"name": "svelte-app",
"version": "1.0.0",
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"start": "sirv ."
},
"devDependencies": {
"#mdi/js": "^5.3.45",
"#rollup/plugin-commonjs": "^12.0.0",
"#rollup/plugin-node-resolve": "^8.0.0",
"#smui/button": "^1.0.0-beta.21",
"#smui/card": "^1.0.0-beta.21",
"#smui/checkbox": "^1.0.0-beta.21",
"#smui/chips": "^1.0.0-beta.21",
"#smui/common": "^1.0.0-beta.21",
"#smui/form-field": "^1.0.0-beta.21",
"#smui/linear-progress": "^1.0.0-beta.21",
"#smui/textfield": "^1.0.0-beta.21",
"#smui/top-app-bar": "^1.0.0-beta.21",
"material": "^0.4.3",
"node-sass": "^4.14.1",
"rollup": "^2.3.4",
"rollup-plugin-copy": "^3.3.0",
"rollup-plugin-livereload": "^1.0.0",
"rollup-plugin-postcss": "^3.1.1",
"rollup-plugin-svelte": "^5.0.3",
"rollup-plugin-terser": "^5.1.2",
"svelte": "^3.0.0",
"svelte-preprocess": "^3.7.4"
},
"dependencies": {
"#material/layout-grid": "^6.0.0",
"sirv-cli": "^0.4.4"
}
}
And here is rollup.config.js
import svelte from 'rollup-plugin-svelte';
import resolve from '#rollup/plugin-node-resolve';
import commonjs from '#rollup/plugin-commonjs';
import copy from 'rollup-plugin-copy';
import livereload from 'rollup-plugin-livereload';
import {terser} from 'rollup-plugin-terser';
import postcss from 'rollup-plugin-postcss';
import autoPreprocess from 'svelte-preprocess';
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'scripts/app.js',
},
plugins: [
copy({
targets: [
{src: 'src/index.html', dest: '.'},
],
}),
svelte({
dev: !production,
emitCss: true,
css: css => {
css.write('css/app.css');
},
preprocess: autoPreprocess()
}),
resolve({
browser: true,
dedupe: ['svelte', '#material'],
}),
commonjs(),
postcss({
extract: 'css/app.css',
minimize: true,
sourceMap: true,
use: [
[
'sass', {
includePaths: [
'./theme',
'./node_modules',
],
},
],
],
}),
!production && serve(),
!production && livereload({watch: ['scripts', 'css', 'src', 'theme']}),
production && terser(),
],
watch: {
clearScreen: false,
},
};
function serve() {
let started = false;
return {
writeBundle() {
if (!started) {
started = true;
require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true,
});
}
},
};
}
It clearly tries to parse the scss file as css. So it probably misses the compile step. I can't find the scss rollup plugin in your package.json.
Check this, it could solve your problem: https://www.npmjs.com/package/rollup-plugin-scss

ngrx/effects type inference error

I'm trying to implement an authentication functionality using effects. These are the relevant classes
// auth.actions.ts
import { Action } from '#ngrx/store';
import { AuthVM, ParamsVM } from '../models';
import { Credential } from '../interfaces';
export const FETCH_AUTH_INFO = 'FETCH_AUTH_INFO';
export const AUTHENTICATE_WITHOUT_CREDENTIALS = 'AUTHENTICATE_WITHOUT_CREDENTIALS';
export class FetchAuthInfo implements Action {
readonly type = FETCH_AUTH_INFO;
constructor(public payload = undefined) { }
}
export class AuthenticateWithoutCredentials implements Action {
readonly type = AUTHENTICATE_WITHOUT_CREDENTIALS;
constructor(public payload: ParamsVM = undefined) { }
}
export type AuthActions = FetchAuthInfo | AuthenticateWithoutCredentials;
#
// auth.effects.ts
import { Injectable } from "#angular/core";
import { Actions, Effect } from '#ngrx/effects';
import { Observable } from 'rxjs/Observable';
import { Action } from '#ngrx/store';
import * as fromAuthActions from './auth.actions';
import { Storage } from '#ionic/storage';
import { fromPromise } from "rxjs/observable/fromPromise";
import { AuthVM, ParamsVM } from '../models';
import { of } from 'rxjs/observable/of';
import { AuthInfoFetched, AuthenticateWithoutCredentials} from './auth.actions';
#Injectable()
export class AuthEffects {
constructor(
private actions$: Actions,
private storage: Storage
) { }
#Effect() fetchAuthInfo$: Observable<Action> = this.actions$
.ofType(fromAuthActions.FETCH_AUTH_INFO)
.mergeMap(() => fromPromise(this.storage.get('authInfo')))
.mergeMap((data: AuthVM) => {
if (data) {
return of(new AuthInfoFetched(data));
} else {
return of(new AuthenticateWithoutCredentials());
}
});
}
I'm getting this error:
The type argument for type parameter 'R' cannot be inferred from the usage. Consider specifying the type
arguments explicitly. Type argument candidate 'AuthInfoFetched' is not a valid type argument because it is
not a supertype of candidate 'AuthenticateWithoutCredentials'. Types of property 'type' are incompatible.
Type '"AUTHENTICATE_WITHOUT_CREDENTIALS"' is not assignable to type '"AUTH_INFO_FETCHED"'.
As far as I know, an Action Observable should be returned at the end of the operators chain. I can't understand why I'm getting the error since AuthInfoFetched and AuthenticateWithoutCredentials both implement the Action interface.
This is the package.json file if it is of any use
{
"name": "app",
"version": "0.0.1",
"author": "Ionic Framework",
"homepage": "http://ionicframework.com/",
"private": true,
"scripts": {
"clean": "ionic-app-scripts clean",
"build": "ionic-app-scripts build",
"lint": "ionic-app-scripts lint",
"ionic:build": "ionic-app-scripts build",
"ionic:serve": "ionic-app-scripts serve"
},
"dependencies": {
"#angular/common": "^4.4.6",
"#angular/compiler": "^4.4.6",
"#angular/compiler-cli": "^4.4.6",
"#angular/core": "^4.4.6",
"#angular/forms": "^4.4.6",
"#angular/http": "^4.4.6",
"#angular/platform-browser": "^4.4.6",
"#angular/platform-browser-dynamic": "^4.4.6",
"#ionic-native/admob-free": "^4.4.2",
"#ionic-native/core": "3.12.1",
"#ionic-native/splash-screen": "3.12.1",
"#ionic-native/status-bar": "3.12.1",
"#ionic/app-scripts": "2.1.3",
"#ionic/storage": "2.0.1",
"#ngrx/effects": "^4.1.1",
"#ngrx/store": "^4.1.1",
"#ngrx/store-devtools": "^4.1.1",
"body-parser": "^1.18.2",
"cordova-admob-sdk": "^0.11.1",
"cordova-android": "^6.4.0",
"cordova-plugin-admob-free": "^0.11.0",
"cordova-plugin-console": "^1.1.0",
"cordova-plugin-device": "^1.1.7",
"cordova-plugin-splashscreen": "^4.1.0",
"cordova-plugin-statusbar": "^2.3.0",
"cordova-plugin-whitelist": "^1.3.3",
"cordova-promise-polyfill": "0.0.2",
"cordova-sqlite-storage": "^2.1.2",
"cors": "^2.8.4",
"express": "^4.16.2",
"ionic-angular": "3.6.0",
"ionic-plugin-keyboard": "^2.2.1",
"ionicons": "3.0.0",
"morgan": "^1.9.0",
"rxjs": "5.4.3",
"sw-toolbox": "3.6.0",
"typescript": "2.3.4",
"zone.js": "0.8.12"
},
"devDependencies": {
"ionic": "3.19.1"
},
"description": "An Ionic project",
"cordova": {
"plugins": {
"cordova-sqlite-storage": {},
"cordova-plugin-console": {},
"cordova-plugin-device": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-statusbar": {},
"cordova-plugin-whitelist": {},
"ionic-plugin-keyboard": {},
"cordova-plugin-admob-free": {}
},
"platforms": [
"android"
]
}
}
Any help would be much appreciated.
In the effect you are returning two different types of action using if/else, so the type can not be inferred for the effect. you can use rxjs if operator or use a temp variable. note ngrx now uses pipes with rxjs 6
Here is code showing different ways
//one way
#Effect() fetchAuthInfo$: Observable<Action> = this.actions$
.ofType(fromAuthActions.FETCH_AUTH_INFO)
.map(() => fromPromise(this.storage.get('authInfo')))
.switchMap((data: AuthVM) => {
let result;
if (data) {
result = of(new AuthInfoFetched(data));
} else {
result = of(new AuthenticateWithoutCredentials());
}
return result;
});
//second way
#Effect() fetchAuthInfo$: Observable<Action> = this.actions$
.ofType(fromAuthActions.FETCH_AUTH_INFO)
.map(() => fromPromise(this.storage.get('authInfo')))
.switchMap((data: AuthVM) => Observable.if(() => data,
of(new AuthInfoFetched(data)),
of(new AuthenticateWithoutCredentials())
)
);
//the new effect way in ngrx
#Effect() fetchAuthInfo$ = this.actions$.pipe(
ofType(fromAuthActions.FETCH_AUTH_INFO),
map(() => fromPromise(this.storage.get('authInfo'))),
switchMap((data: AuthVM) => iif(() => data,
of(new AuthInfoFetched(data)),
of(new AuthenticateWithoutCredentials()))
)
);
I also got it working typecasting the returned values to the "Action" type
#Effect() fetchAuthInfo$: Observable<Action> = this.actions$
.ofType(FETCH_AUTH_INFO)
.mergeMap(() => fromPromise(this.storage.get('authInfo')))
.mergeMap((data: AuthVM) => {
if (data) {
return of(<Action>new AuthInfoFetched(data));
} else {
return of(<Action>new AuthenticateWithoutCredentials());
}
});

Webpack cannot find keymirror module with Typescript import

I'm using Typescript, React, and Webpack and struggling to import the keymirror module.
I am using the latest version of typescript.
package.json
{
"name": "Fun",
"version": "1.0.0",
"description": "Dear Webpack Gods, please help.",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "",
"dependencies": {
"eventemitter3": "^1.1.1",
"flux": "^2.0.3",
"keymirror": "^0.1.1",
"react": "^0.13.3",
"ts-loader": "^0.5.0",
"typescript": "^1.6.0-dev.20150812"
},
"devDependencies": {
"css-loader": "^0.16.0",
"style-loader": "^0.12.3"
}
}
webpack.config.js
module.exports = {
entry: './App/app.tsx',
output: {
filename: 'bundle.js'
},
resolve: {
extensions: ['', '.js', '.tsx', '.ts']
},
module: {
loaders: [
{ test: /\.ts(x?)$/, loader: 'ts-loader' },
{ test: /\.css$/, loader: 'style-loader!css-loader' }
]
}
}
tsconfig.json
{
"compilerOptions": {
"target": "ES5",
"module": "commonjs",
"jsx": "react",
"sourceMap": true
},
"files": [
"./typings/tsd.d.ts",
"./App/app.tsx"
]
}
The offending import is located in ./User/Constants.ts
import keyMirror = require('keymirror');
export = keyMirror({
LOGIN_ATTEMPT: null
});
I have tried using the standalone npm module as seen above, as well as attempting to require it from react/lib/keyMirror.
Any ideas?
(EDIT: Yes, I know it's a 12 line module that I could just copy into my code.)
Solution from Basarat (with slight modification)
declare module 'keymirror' {
function keyMirror(obj: Object);
export = keyMirror;
}
import keyMirror = require('keymirror');
You need to tell typescript about it. Basically something like :
declare module 'keymirror' {
var export:any;
export = export;
}
In a file called global.d.ts.
Some docs : http://basarat.gitbooks.io/typescript/content/docs/types/ambient/intro.html