Giter Site home page Giter Site logo

tinker's Introduction

Logo Laravel Tinker

Build Status Total Downloads Latest Stable Version License

Introduction

Laravel Tinker is a powerful REPL for the Laravel framework.

Official Documentation

Documentation for Tinker can be found on the Laravel website.

Contributing

Thank you for considering contributing to Tinker! The contribution guide can be found in the Laravel documentation.

Code of Conduct

In order to ensure that the Laravel community is welcoming to all, please review and abide by the Code of Conduct.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

License

Laravel Tinker is open-sourced software licensed under the MIT license.

tinker's People

Contributors

bobthecow avatar browner12 avatar carusogabriel avatar crynobone avatar driesvints avatar dwightwatson avatar fgilio avatar grahamcampbell avatar henriquebremenkanp avatar huangdijia avatar innocenzi avatar inxilpro avatar jasonvarga avatar jbrooksuk avatar jerguslejko avatar jubeki avatar lucasmichot avatar m1guelpf avatar michaelhume avatar mkarnicki avatar mpociot avatar nunomaduro avatar paras-malhotra avatar pataar avatar peter279k avatar rodrigopedra avatar stanangeloff avatar taylorotwell avatar vendin avatar xico2k avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tinker's Issues

artisan tinker artifact - Laravel queue processes a job only after the next is queued

  • Laravel Version: 5.7.12
  • PHP Version: 7.2.10
  • Database Driver & Version: confirmed with redis, database, sync

Please advise if this is a PsyShell bug and not laravel/framework bug, in which case I can file this issue in a more appropriate place.

Description:

Dispatching jobs from artisan tinker session doesn't work correctly with the queue. Any queued job PREV waits for another job NEXT, at which point PREV is handled (but not NEXT, which waits for yet another job). I fully described the issue on SO and got someone to confirm it.

Steps To Reproduce:

$ laravel new test
$ cd test
$ php artisan make:job TestQueue

Paste the following into the TestQueue class. Nothing fancy, really:

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Support\Facades\Log;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class TestQueue implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $id;

    public function __construct($id)
    {
        Log::info('Creating ' . $id);
        $this->id = $id;
    }

    public function handle()
    {
        Log::info('Running ' . $this->id);
    }
}

Now, regardless of the QUEUE_CONNECTION env var (redis, beanstalkd, even sync), I get the following behavior. Please note I have php artisan queue:work running in a separate terminal, restarted after any .env changes and config is not cached.

$ php artisan tinker

>>> App\Jobs\TestQueue::dispatch(1)

logs:

[2018-10-30 22:38:01] local.INFO: Creating 1

>>> App\Jobs\TestQueue::dispatch(2)

logs:

[2018-10-30 22:38:04] local.INFO: Creating 2
[2018-10-30 22:38:06] local.INFO: Running 1

>>> App\Jobs\TestQueue::dispatch(3)

logs:

[2018-10-30 22:38:22] local.INFO: Creating 3
[2018-10-30 22:38:24] local.INFO: Running 2

If you're testing with sync queue, ensure that sync driver is set to sync and not null in config/queue.php

EDIT: Note this only happens from artisan tinker session. The jobs are handled correctly via web routes.

Tinker lost colors

  • Tinker Version: 2.6.1
  • Laravel Version: 8.47.0
  • PHP Version: 8.0.7
  • Psy Shell: v0.10.8
  • Database Driver & Version:

Description:

Tinker is not using colors, all the text is white only, this issue happened when I installed a latest version of Laravel ( 8.47.0 ),
I went to try some oldest versions of Laravel ( 8.46.0 and older ) tinker worked fine, text was colored fine,
what should we do?

Steps To Reproduce The Issue:

It happens whenever we create a fresh Laravel project with composer

composer create-project laravel/laravel .

Samples

cmd

cmder

mkdir(): Permission denied

I'm having this error on latest Tinker and Laravel, when attempting to call artisan tinker.

In Configuration.php line 352:
                              
  [ErrorException]            
  mkdir(): Permission denied

After some investigations it turned out that Psysh is trying to mkdir /run/user/0/psysh, which is not accessible.

Possibly related to #33

Laravel Vapor support

Right now, tinker can't be used inside Laravel Vapor because in order to run psysh (which tinker uses), it needs to be able to create a runtime directory (which defaults to ~/.config/psysh -- this is not available inside an AWS Lambda). See the runtimeDir option @ https://github.com/bobthecow/psysh/wiki/Config-options.

However, this directory path can be changed by setting the XDG_CONFIG_HOME variable.

Not sure if this should be a tinker feature or a Vapor feature.

Anyway, once this is resolved, people can use php artisan tinker --execute "dump(config('queue'))" or whatever inside their vapor lambdas

Not compatible with Laravel/Lumen 5.1

Because both Laravel and Lumen 5.1 require symfony/var-dumper 2.7, laravel/tinker will not install because it depends on symfony/var-dumper ~3.0.

Steps to reproduce:

  1. Create either a new laravel/laravel or laravel/lumen 5.1.* project
  2. Run: composer require laravel/tinker
  3. Command fails with the following error:
$ composer require laravel/tinker                             
Using version ^1.0 for laravel/tinker
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Conclusion: don't install laravel/tinker v1.0.1
    - Conclusion: remove symfony/var-dumper v2.7.28
    - Installation request for laravel/tinker ^1.0 -> satisfiable by laravel/tinker[v1.0.0, v1.0.1].
    - Conclusion: don't install symfony/var-dumper v2.7.28
    - laravel/tinker v1.0.0 requires symfony/var-dumper ~3.0 -> satisfiable by symfony/var-dumper[v3.0.0, v3.0.1, v3.0.2, v3.0.3, v3.0.4, v3.0.5, v3.0.6, v3.0.7, v3.0.8, v3.0.9, v3.1.0, v3.1.1, v3.1.10, v3.1.2, v3.1.3, v3.1.4, v3.1.5, v3.1.6, v3.1.7, v3.1.8, v3.1.9, v3.2.0, v3.2.1, v3.2.2, v3.2.3, v3.2.4, v3.2.5, v3.2.6, v3.2.7, v3.2.8, v3.2.9, v3.3.0, v3.3.1, v3.3.2].
    - Can only install one of: symfony/var-dumper[v3.0.0, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.0.1, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.0.2, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.0.3, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.0.4, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.0.5, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.0.6, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.0.7, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.0.8, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.0.9, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.1.0, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.1.1, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.1.10, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.1.2, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.1.3, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.1.4, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.1.5, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.1.6, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.1.7, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.1.8, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.1.9, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.2.0, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.2.1, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.2.2, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.2.3, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.2.4, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.2.5, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.2.6, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.2.7, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.2.8, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.2.9, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.3.0, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.3.1, v2.7.28].
    - Can only install one of: symfony/var-dumper[v3.3.2, v2.7.28].
    - Installation request for symfony/var-dumper (locked at v2.7.28) -> satisfiable by symfony/var-dumper[v2.7.28].


Installation failed, reverting ./composer.json to its original content.

Tinker close with error after using []

  • Tinker Version: 0.9.12
  • Laravel Version: 7.0.4
  • PHP Version: 7.2.19
  • Database Driver & Version:

Description:

Getting "Symfony\Component\ErrorHandler\Error\FatalError" when using only one command.

Steps To Reproduce:

open tinker, write

$user[]
press enter

$user[]

Symfony\Component\ErrorHandler\Error\FatalError

Cannot use [] for reading

at C:\laragon\www\Woodchuck\vendor\psy\psysh\src\ExecutionLoopClosure.php:55
51| // Convert all errors to exceptions
52| \set_error_handler([$psysh, 'handleError']);
53|
54| // Evaluate the current code buffer

55| $_ = eval($psysh->onExecute($psysh->flushCode() ?: ExecutionClosure::NOOP_INPUT));
56| } catch (\Throwable $_e) {
57| // Clean up on our way out.
58| \restore_error_handler();
59| if (\ob_get_level() > 0) {

Whoops\Exception\ErrorException

Cannot use [] for reading

at C:\laragon\www\Woodchuck\vendor\psy\psysh\src\ExecutionLoopClosure.php:55
51| // Convert all errors to exceptions
52| \set_error_handler([$psysh, 'handleError']);
53|
54| // Evaluate the current code buffer

55| $_ = eval($psysh->onExecute($psysh->flushCode() ?: ExecutionClosure::NOOP_INPUT));
56| } catch (\Throwable $_e) {
57| // Clean up on our way out.
58| \restore_error_handler();
59| if (\ob_get_level() > 0) {

1 C:\laragon\www\Woodchuck\vendor\filp\whoops\src\Whoops\Run.php:408
Whoops\Run::handleError("Cannot use [] for reading", "C:\laragon\www\Woodchuck\vendor\psy\psysh\src\ExecutionLoopClosure.php(55) : eval()'d code")

2 [internal]:0
Whoops\Run::handleShutdown()

Unexpected? behaviour dispatching to queues.

Found some unexpected behaviour when dispatching jobs within tinker - namely jobs are dispatched the loop after you call them.

I don’t know enough about queues (or tinker!) to know why.

Psy Shell v0.8.11 (PHP 7.1.8 — cli) by Justin Hileman
>>> App\Jobs\TestJob::dispatch(1);
=> Illuminate\Foundation\Bus\PendingDispatch {#831}
>>> App\Jobs\ TestJob::dispatch(2);
string(23) "TestJob(1) actually queued"
=> Illuminate\Foundation\Bus\PendingDispatch {#825}
>>> App\Jobs\ TestJob::dispatch(3);
string(23) "TestJob(2) actually queued"
=> Illuminate\Foundation\Bus\PendingDispatch {#834}
>>> App\Jobs\ TestJob::dispatch(4);
string(23) "TestJob(3) actually queued"
=> Illuminate\Foundation\Bus\PendingDispatch {#846}
>>> $nop = true
=> true
>>> 3
=> 3
>>> sleep(1)
=> 0
>>> exit
string(23) "TestJob(4) actually queued"
Exit:  Goodbye.

The dispatching of jobs is delayed, and if you exit from tinker right after a dispatch() then the job (usually!) isn’t dispatched. (except it was in the test above!)

It's the same in Laravel 5.4 and 5.5.

Tinker does not fully respect -q and -n flags

  • Tinker Version: 1.0.8
  • PHP Version: 7.1.19

Description:

Tinker with either the -q (quiet) or the -n (no interaction) does not fully respect these options. Use case is an include file that echos stuff as part of a build process, but it cannot be run headless.

Steps To Reproduce:

> php artisan tinker -q
prints prompt >>> and the Exit: Goodbye. message.

> php artisan tinker -n
waits for interaction before exiting.

File hello_world.php:

<?php echo('Hello world!');

> php artisan tinker -qn hello_world.php
pauses until exit is typed in shell.

Model Accessor not working

I have the following code in freshly installed Laravel application,


namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function getNameAttribute($name)
    {
        return $name . ' Changed';
    }
}

I have a test route which returns all users

Route::get('/test', function (){
   return \App\User::all();
});

And when I visit the route I do get the results as expected

[
{
"id": 2,
"name": "Delfina Bogisich Changed",
"email": "[email protected]",
"created_at": "2018-01-08 05:27:31",
"updated_at": "2018-01-08 05:27:31"
},
{
"id": 3,
"name": "Curt McCullough II Changed",
"email": "[email protected]",
"created_at": "2018-01-08 05:27:35",
"updated_at": "2018-01-08 05:27:35"
}
]

But in tinker

php artisan tinker

screenshot from 2018-01-08 11-06-39

PHP Warning after logging in using Auth in Tinker

  • Tinker Version: 2.4.2
  • Laravel Version: 7.25.0
  • PHP Version: 7.2.33
  • Database Driver & Version: Mysql 8.0.21-0ubuntu0.20.04.4

Description:

when I login using Auth::login in Tinker, I get a warning:

PHP Warning:  unlink({path}/storage/framework/sessions/3p6YqECrq3EAMP4Hdz2X5IBdw4cfRG30bLNpY9z4): 
No such file or directory in {path}/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php on line 220

After the warning, everything works, I can use my usual queries that need a logged-in user. So this is not a high prio thing.
Seems there is no session present to be removed.

Steps To Reproduce:

  1. start tinker artisan tinker
  2. login user
$u = User::find(1);
Auth::login($u);

Vendor path is hardcoded

Hi,

I had to make a Frankenstein – stitch together Rails app and Laravel app. Because of similar directory structure I decided to put Laravel app in subdirectory laravel, but for Laravel I re-used the vendor directory that was already in the root directory. I moved /laravel/public/index.php to /public/index.php and modified the paths in it. I modified /laravel/bootstrap/app.php file. I moved /laravel/artisan file to /artisan and modified the paths in it. I moved /laravel/.env file to /.env. I moved /laravel/resources to /resources. I moved /laravel/storage to /storage. I think that was it. And it works! 🎉

But when I tried to call php artisan tinker, it threw me this error:
Command "tinker" is not defined.

So I did a little research and found out that I had to add Laravel\Tinker\TinkerServiceProvider::class to the list of providers in config/app.php. I guess that normally artisan just scans the vendor directory for tinker and, if it finds it, it adds it automatically? Because it works for normal installation. Am I right? 🤔

After I added that service provider, it threw me this error:
Laravel\Tinker\ClassAliasAutoloader::__construct(): Failed opening required 'D:\project\laravel\vendor/composer/autoload_classmap.php' (include_path='.;C:\php\pear')
I will tell you again – there is no /laravel/vendor directory, I am re-using /vendor directory.

It turns out that the vendor directory is hardcoded:

$path = $this->getLaravel()->basePath().DIRECTORY_SEPARATOR.'vendor/composer/autoload_classmap.php';

in this file:
https://github.com/laravel/tinker/blob/v1.0.8/src/Console/TinkerCommand.php#L57

So, because the base_path is /laravel and not /, it can't find the vendor directory in it...

I ended up making custom TinkerServiceProvider that extends the original one and making custom TinkerCommand that extends the original one, but with:

$path = $this->getLaravel()->basePath().DIRECTORY_SEPARATOR.'../vendor/composer/autoload_classmap.php';

Can the vendor directory be configured in some config/tinker.php file or detected somehow from Composer or Laravel itself? This is the point of the issue. ⚠️

If someone is interested, this is how I changed the location of .env, storage and public paths (that are still located in the root directory of the project) in the /laravel/bootstrap/app.php file:

$app = new Illuminate\Foundation\Application(
    $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);

$app->useEnvironmentPath(dirname(__DIR__, 2));
$app->useStoragePath(dirname(__DIR__, 2).DIRECTORY_SEPARATOR.'storage');
$app->instance('path.public', dirname(__DIR__, 2).DIRECTORY_SEPARATOR.'public');

SomeClass::class doesn't return fully qualified class name when class is aliased

If I have a class App\User and I type User::class in the artisan console, it first outputs [!] Aliasing 'User' to 'App\User' for this Tinker session. then returns User instead of App\User.

This leads to unexpected behaviour in certain situations in tinker like when authorizing using policies $user->can('create', User::class) will always return false

Whitelist vendor classes for aliasing

I'm frequently using Tinker to deal with classes from a package, but the aliasing doesn't happen for classes within vendor.

How about config array that whitelists some classes (and/or namespaces).

'alias' => [
   'Statamic\Entries\Entry',
]

I'm happy to PR this myself, but just wanted to ask before doing so.

Use isset() method

isset(1);
PHP Parse error: Syntax error, unexpected T_LNUMBER on line 1

Tinker not updating

  • Tinker Version: 0.9.9
  • Laravel Version: 5.7.26
  • PHP Version: 7.2.12

Description:

When I try to check out my data binded with eloquent relations, tinker cannot update the models, that's why, I gotta quit from it, clear cache and again run it, re-run what I ran before,

Steps To Reproduce:

Before

Before

After

It's even not working after clearing the cache. I'm using one-to-one relation

After
After 2

I've been testing it with just tinker, but without tinker everything works perfectly

How to cancel current running operation

Sometimes the piece of code I run takes a lot of time to complete its execution. I usually find my bug in mid way, but I have to wait till the whole command executed successfully.

Unfortunately termination commands like Ctrl + C exits the whole tinker completely. How can I only stop the current running command only and not the complete tinker session.

Thanks in Advance,
Sukhwinder

Support Laravel Vapor

➜  backend git:(feat/vapor-work) ✗ vapor command  

 What command would you like to execute:
 > tinker

==> Executing Function...

Status Code: 1

Output:

[2019-10-04 13:54:50] staging.ERROR: Writing to //.config/psysh is not allowed. {"exception":"[object] (ErrorException(code: 0): Writing to //.config/psysh is not allowed. at /var/task/vendor/psy/psysh/src/ConfigPaths.php:228)
[stacktrace]
#0 /var/task/vendor/sentry/sentry/src/ErrorHandler.php(386): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(1024, 'Writing to //.c...', '/var/task/vendo...', 228)
#1 [internal function]: Sentry\\ErrorHandler->handleError(1024, 'Writing to //.c...', '/var/task/vendo...', 228, Array)
#2 /var/task/vendor/psy/psysh/src/ConfigPaths.php(228): trigger_error('Writing to //.c...', 1024)
#3 /var/task/vendor/psy/psysh/src/Configuration.php(376): Psy\\ConfigPaths::touchFileWithMkdir('//.config/psysh...')
#4 /var/task/vendor/psy/psysh/src/Configuration.php(405): Psy\\Configuration->setHistoryFile('//.config/psysh...')
#5 /var/task/vendor/psy/psysh/src/Configuration.php(542): Psy\\Configuration->getHistoryFile()
#6 /var/task/vendor/psy/psysh/src/Shell.php(90): Psy\\Configuration->getReadline()
#7 /var/task/vendor/laravel/tinker/src/Console/TinkerCommand.php(53): Psy\\Shell->__construct(Object(Psy\\Configuration))
#8 [internal function]: Laravel\\Tinker\\Console\\TinkerCommand->handle()
#9 /var/task/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(32): call_user_func_array(Array, Array)
#10 /var/task/vendor/laravel/framework/src/Illuminate/Support/helpers.php(522): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#11 /var/task/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(90): value(Object(Closure))
#12 /var/task/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(34): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#13 /var/task/vendor/laravel/framework/src/Illuminate/Container/Container.php(591): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#14 /var/task/vendor/laravel/framework/src/Illuminate/Console/Command.php(202): Illuminate\\Container\\Container->call(Array)
#15 /var/task/vendor/symfony/console/Command/Command.php(255): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#16 /var/task/vendor/laravel/framework/src/Illuminate/Console/Command.php(189): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#17 /var/task/vendor/symfony/console/Application.php(915): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 /var/task/vendor/symfony/console/Application.php(272): Symfony\\Component\\Console\\Application->doRunCommand(Object(Laravel\\Tinker\\Console\\TinkerCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#19 /var/task/vendor/symfony/console/Application.php(148): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#20 /var/task/vendor/laravel/framework/src/Illuminate/Console/Application.php(90): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#21 /var/task/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(131): Illuminate\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#22 /var/task/artisan(37): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#23 {main}
"} 

   ErrorException  : Writing to //.config/psysh is not allowed.

  at /var/task/vendor/psy/psysh/src/ConfigPaths.php:228
    224|             @\mkdir($dir, 0700, true);
    225|         }
    226| 
    227|         if (!\is_dir($dir) || !\is_writable($dir)) {
  > 228|             \trigger_error(\sprintf('Writing to %s is not allowed.', $dir), E_USER_NOTICE);
    229| 
    230|             return false;
    231|         }
    232|

  Exception trace:

  1   trigger_error("Writing to //.config/psysh is not allowed.")
      /var/task/vendor/psy/psysh/src/ConfigPaths.php:228

  2   Psy\ConfigPaths::touchFileWithMkdir("//.config/psysh/psysh_history")
      /var/task/vendor/psy/psysh/src/Configuration.php:376

  Please use the argument -v to see more details.

Function Logs:

Alias only models

I often have projects where e.g. a Livewire component "User" is aliased before the model with the same name. That means that I have to type the namespace for the user model or enter every model manually in the config.
I basically only ever need models aliased.
Would a PR with something like the following in ClassAliasAutoloader be accepted?

if(config('tinker.only_models') 
    && !(new \ReflectionClass($class))->isSubclassOf(\Illuminate\Database\Eloquent\Model::class)) {
    return false;
}

Tinker startup time will go up a little, but
a) this time will be saved as soon as I have to enter the first model namespace
b) it's only optional and disabled by default

Thanks!

Contextual binding doesn't appear to work in tinker

  • Tinker Version: 2.6.1
  • Laravel Version: 8.60.0
  • PHP Version: 7.4.23
  • Database Driver & Version:

Description:

When using contextual binding on classes tinker does not provide the arguments correctly to the class.

Steps To Reproduce:

Repository: https://github.com/yamut/binding

Relevant files:
https://github.com/yamut/binding/blob/master/app/Services/FooService.php
https://github.com/yamut/binding/blob/master/app/Providers/AppServiceProvider.php
https://github.com/yamut/binding/blob/master/routes/web.php

Documentation:
https://laravel.com/docs/8.x/container#binding-primitives

Tinker:

Psy Shell v0.10.8 (PHP 7.4.23 — cli) by Justin Hileman
>>> app()->make(FooService::class)
[!] Aliasing 'FooService' to 'App\Services\FooService' for this Tinker session.
Illuminate\Contracts\Container\BindingResolutionException with message 'Unresolvable dependency resolving [Parameter #0 [ <required> int $a ]] in class App\Services\FooService'

When loading index using php artisan serve the output is 1 as expected.

Edit:

Running the binding in tinker does cause this to work.

Psy Shell v0.10.8 (PHP 7.4.23 — cli) by Justin Hileman
>>> app()->when(FooService::class)->needs('$a')->give(1);
=> null
>>> app()->make(FooService::class)
[!] Aliasing 'FooService' to 'App\Services\FooService' for this Tinker session.
=> App\Services\FooService {#3454
     +a: 1,
   }

This made me question if AppServiceProvider is run in tinker, which it does appear to be.
Added $_SERVER['foo'] = 'bar'; to AppServiceProvider::register, and it is accessible from tinker.

Psy Shell v0.10.8 (PHP 7.4.23 — cli) by Justin Hileman
>>> $_SERVER['foo']
=> "bar"

After update php version to 7.4.0 , php artisan tinker command got error

  • Tinker Version: "laravel/tinker": "^2.5",
  • Laravel Version: 8.*
  • PHP Version: 7.4.0beta4
  • Database Driver & Version: mysql 5.7.27

Description:

error info:
Psy Shell v0.10.5 (PHP 7.4.0beta4 — cli) by Justin Hileman
ErrorException with message 'Unbinding $this of closure is deprecated'

Steps To Reproduce:

How to use japanese character in laravel/tinker?

In my ubuntu i can input japanese character in my terminal. But when i try insert some japanese character with tinker it's look like tinker not support it. I mean when i try type some japanese example 'わたし' (in japanese input we need enter after type some word, because by default we get some suggestion word, so we hit enter to select the word). But after enter no word shown in terminal. Any configuration to fix this? Thanks. Sory for bad english.

Using --execute option produces no output

  • Tinker Version: v2.5.0
  • Laravel Version: 8.15.0
  • PHP Version: 7.4.12
  • Database Driver & Version:

Description:

The execute option seems to not be working when used. It doesn't give an output when you use the option.

Steps To Reproduce:

Run php artisan tinker --execute="[1, 2, 3, 4]"

Error Handling in Tinker

  • Tinker Version: v2.4.0
  • Laravel Version: v7.12.0
  • PHP Version: v7.4.7
  • Database Driver & Version: PDO Driver for MySQL (?)

Description:

Error handler for Tinker is taken from psy/psysh:v0.10.4, instead using Laravel Framework's "src/Illuminate/Foundation/Bootstrap/HandleExceptions.php".
This leads to me not noticing Bugs, that will throw an ErrorException in Production 😆
Did not look this up, but i think that used to be different.

Steps To Reproduce:

trigger_error('notice', E_USER_NOTICE);

Output (result) not given upon submitting a code line

Not sure if it has to do with a recent Tinker update, but currently upon submitting a line (pressing Enter), the result, or PHP output, is not shown.

Example (no result is being outputted after line is run)

Psy Shell v0.8.16 (PHP 7.2.4 — cli) by Justin Hileman
>>> my_func()
>>> 

Expected (note the "bool(false)" part which is the PHP result/output)

Psy Shell v0.8.16 (PHP 7.2.4 — cli) by Justin Hileman
>>> my_func()
bool(false)
>>> 

Am I missing something? Is there a setting I need to update?

Change Config Path psysh

Hy,
I have problem after run tinker in my server. Error like this

 [ErrorException]
  Writing to /home/117544.cloudwaysapps.com/gykhzmvvcd/.config/psysh is not a
  llowed.

Can not create config folder for psysh, can help me for solution? or i must change config path for psysh? but how ...

Thanks,

Tinker get too much slow after upgrading PHP to 7.4

  • Tinker Version: 2.0.0
  • Laravel Version: 6.6.1
  • PHP Version: 7.4.0
  • OS: MacOS Catalina 10.15.1

Description:

Tinker get too much slow, after upgrading php on.
it takes about 10~15 seconds to start running, and the same delay to response to any php code, but the same code is running perfectly in Laravel itself.

Steps To Reproduce:

php artisan tinker

assert always returns true

  • Tinker Version: 1.0.10
  • Laravel Version: 6.18.31
  • PHP Version: 7.4.3
  • Database Driver & Version: 5.7.29

Description:

assert() always returns true.

Steps To Reproduce:

Run this code, it always returns true

/var/www/html# php artisan tinker
Psy Shell v0.9.12 (PHP 7.4.3 — cli) by Justin Hileman
>>> $test = null;
=> null
>>> assert($test instanceof PDO);
=> true
>>>

Error while migrating from Laravel tinker console

  • Laravel Version: 5.5.33
  • PHP Version: 7.1.10
  • Database Driver & Version: sqlite/postgres tested

While this works fine

Route::get('/', function () {
    \Artisan::call('migrate:fresh');
    return "ok";
});

Running

\Artisan::call('migrate:fresh');
\Artisan::call('migrate');
....

in tinker console results in all kinds of errors.

Steps to reproduce and clues as described here: https://stackoverflow.com/questions/48527840/error-while-migrating-from-laravel-tinker-console-sqlite

Should psy/psysh be require-dev?

I'm probably biased due to my current situation, and/or don't fully understand composer with --production.

I am trying to get my Laravel Spark application ready for production in a secure environment. Psy/psysh came up with a security issue after doing composer install --production on the project to prepare it for a security audit. I am trying to think of a use case for tinker to be used in production, and it would seem (to me anyway) that psy/psysh would be better suited to require-dev.

Am I misunderstanding how composer works? Or would it make sense to move psy/psysh to require-dev?

PendingDispatch never dispatches if not assigned to a variable in Tinker

This inconsistency took me a while to wrap my head around.

>>> dispatch(new App\Jobs\TestJob)
=> Illuminate\Foundation\Bus\PendingDispatch {#1328}
>>> exit

Expected: PendingDispatch is dispatched when the object is destructed.
Actual: Doesn't dispatch.

>>> $pending = dispatch(new App\Jobs\TestJob)
=> Illuminate\Foundation\Bus\PendingDispatch {#1328}
>>> exit

This will dispatch.

Message could use improvement to save developers time

I was tinkering with a new project I am working on (trying to verify relationships work - debugging one that doesnt). I closed the tinker window, renamed a database table. Upon returning, I have had a few cryptic messages such as the following:


`| ~/Laravel/ob-jobs @ Lees-MBP (leebrown)
| => php artisan tinker

[Symfony\Component\Debug\Exception\FatalThrowableError]
Parse error: syntax error, unexpected '=>' (T_DOUBLE_ARROW), expecting ')'

`

It would really be nice if the error handler could indicate in which file the error occurred. Might save (less experienced people like me) a lot of hunting...

Suggestion: Multiple line support

It would be fantastic if tinker supported multiple line statements... because then you could just cut and paste from your code rather than having to remove newline chars before pasting... for example
rather than this:

$d=DeviceCamera::with(['device'=>function($query){$query->select('devices.id as device_id', 'name as camera_name', 'slug as webcam_name')->groupBy('devices.id');},'device.device'=>function($query){$query->select('id','id as camera_id', 'camera_lens_type_id', 'settings',DB::raw("cast(settings->>'viewport_order' as int) as viewport_order"))->groupBy('id');},'deployments'=>function($query){$query->select('deployments.id as deployment_id','vessel_id')->groupBy('vessel_id')->groupBy('deployments.id');},'videos'=>function($query){$query->select('videos.id as video_id','server_id as vid_server_id',DB::raw("max(video_duration) as video_duration"),DB::raw('max(size) as size'),DB::raw('min(video_start_timestamp) as video_start_timestamp'),DB::raw('max(video_end_timestamp) as video_end_timestamp'),DB::raw('(array_agg(video_path))[1] as video_path'),'video_name')->groupBy('server_id')->groupBy('video_name');},'videos.server.device'=>function($query){$query->select('id as server_id',DB::raw("(array_agg(settings->>'fqdn'))[1] as fqdn"),DB::raw("(array_agg(settings->>'rtmp_path'))[1] as rtmp_path"));}])->get();

I could have this

$d = DeviceCamera::with([
    'device'  => function ($query) {
        $query->select(
            'devices.id as device_id', 'name as camera_name', 'slug as webcam_name'
        )->groupBy('devices.id');
    },
    'device.device' => function ($query) {
        $query->select(
            'id', 'id as camera_id', 'camera_lens_type_id', 'settings',
            DB::raw("cast(settings->>'viewport_order' as int) as viewport_order")
        )->groupBy('id');
    },
    'deployments' => function ($query) {
        $query->select(
            'deployments.id as deployment_id', 'vessel_id'
        )->groupBy('vessel_id')->groupBy('deployments.id');
    },
    'videos' => function ($query) {
        $query->select(
            'videos.id as video_id',
            'server_id as vid_server_id',
            DB::raw("max(video_duration) as video_duration"),
            DB::raw('max(size) as size'),
            DB::raw('min(video_start_timestamp) as video_start_timestamp'),
            DB::raw('max(video_end_timestamp) as video_end_timestamp'),
            DB::raw('(array_agg(video_path))[1] as video_path'),
            'video_name'
        )->groupBy('server_id')->groupBy('video_name');
    },
    'videos.server.device' => function ($query) {
        $query->select(
            'id as server_id',
            DB::raw("(array_agg(settings->>'fqdn'))[1] as fqdn"),
            DB::raw("(array_agg(settings->>'rtmp_path'))[1] as rtmp_path")
        );
    }])->get();

Attempting to get helpers documentation failed, like dock head.

  • Tinker Version: 2.4.0
  • Laravel Version: 7.5.2
  • PHP Version: 7.4.4
  • Database Driver & Version:

Description:

An attempt to get documentation, like dock head, in the tinker results in the following error: TypeError: Argument 1 passed to Symfony/Component/Console/Formatter/OutputFormatter::escape() must be of the type string, null given

Steps To Reproduce:

$ php artisan tinker
Psy Shell v0.10.3 (PHP 7.4.4 — cli) by Justin Hileman
>>> doc head
TypeError: Argument 1 passed to Symfony/Component/Console/Formatter/OutputFormatter::escape() must be of the type string, null given
>>> doc last
TypeError: Argument 1 passed to Symfony/Component/Console/Formatter/OutputFormatter::escape() must be of the type string, null given
>>> doc count
function count($var, $mode = unknown)
...
works correctly
...

Reboot command

When the code is changed with a Tinker session opened, we have to exit Tinker and open it again for it to recognise the changes made. That's a pain point.

It would be nice to have a reboot() command to force Tinker to reinitialize the session taking into account the changes made.

Directory not empty

Environment

Laravel version: 5.4.36
Tinker version: ^1.0
PHP version: 7.0.9

Problem

Cannot access tinker

This problem is also experienced by other people:
https://stackoverflow.com/q/46801515/5156885
https://stackoverflow.com/q/46792892/5156885

Steps to Replicate

Type php artisan tinker in cmd

Error

ErrorException: rmdir(C:\Users\JC\AppData\Local\Temp\php-xdg-runtime-dir-fallback-): Directory not empty in C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\dnoegel\php-xdg-base-dir\src\Xdg.php:110

Stack Trace

#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'rmdir(C:\\Users\\...', 'C:\\wamp\\www\\Mag...', 110, Array)
#1 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\dnoegel\php-xdg-base-dir\src\Xdg.php(110): rmdir('C:\\Users\\JC\\App...')
#2 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\psy\psysh\src\Psy\ConfigPaths.php(139): XdgBaseDir\Xdg->getRuntimeDir(false)
#3 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\psy\psysh\src\Psy\Configuration.php(348): Psy\ConfigPaths::getRuntimeDir()
#4 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\psy\psysh\src\Psy\Shell.php(173): Psy\Configuration->getRuntimeDir()
#5 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\symfony\console\Application.php(1163): Psy\Shell->getDefaultCommands()
#6 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\symfony\console\Application.php(431): Symfony\Component\Console\Application->init()
#7 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\psy\psysh\src\Psy\Shell.php(134): Symfony\Component\Console\Application->add(Object(Illuminate\Foundation\Console\ClearCompiledCommand))
#8 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\symfony\console\Application.php(415): Psy\Shell->add(Object(Illuminate\Foundation\Console\ClearCompiledCommand))
#9 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\laravel\tinker\src\Console\TinkerCommand.php(54): Symfony\Component\Console\Application->addCommands(Array)
#10 [internal function]: Laravel\Tinker\Console\TinkerCommand->handle()
#11 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(29): call_user_func_array(Array, Array)
#12 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(87): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#13 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(31): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#14 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\laravel\framework\src\Illuminate\Container\Container.php(539): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#15 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\laravel\framework\src\Illuminate\Console\Command.php(182): Illuminate\Container\Container->call(Array)
#16 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\symfony\console\Command\Command.php(262): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#17 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\laravel\framework\src\Illuminate\Console\Command.php(167): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#18 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\symfony\console\Application.php(888): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#19 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\symfony\console\Application.php(224): Symfony\Component\Console\Application->doRunCommand(Object(Laravel\Tinker\Console\TinkerCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#20 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\symfony\console\Application.php(125): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#21 C:\wamp\www\MagisGit\MagisCMS_Staging\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php(122): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#22 C:\wamp\www\MagisGit\MagisCMS_Staging\artisan(35): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#23 {main}  

Temporary work-around

The temporary workaround is to delete the contents of the php-xdg-runtime-dir-fallback- folder (which is usually just the psysh folder). However, it does not seem the right solution as we would be deleting it every time we want to access php artisan tinker

This seems to be a fairly recent problem, as the timestamp of the two links (https://stackoverflow.com/q/46801515/5156885 and https://stackoverflow.com/q/46792892/5156885) as of this writing is 9 hours and 23 hours ago, respectively.

Add migrate:install to white listed commands

Hi,

Since the migrate command depends on migrate:install in order to prepare the database when first run, if running code that executes a call to migrate within tinker (on a fresh db) a Symfony/Component/Console/Exception/NamespaceNotFoundException with message 'There are no commands defined in the "migrate" namespace.' is the result.

Adding migrate:install to the whitelisted commands resolves this.

N.B. Adding \Illuminate\Database\Console\Migrations\InstallCommand::class to config/tinker.php results in a BindingResolutionException: Target [Illuminate\Database\Migrations\MigrationRepositoryInterface] is not instantiable while building [Illuminate\Database\Console\Migrations\InstallCommand].

Thanks for all you do!

Not working after upgrade to PHP 7.3.0

  • Laravel Version: 5.7.16
  • PHP Version: 7.3.0

Please advise if this is a PsyShell bug, in which case I will file this issue at their repo.

After upgrading PHP to 7.3.0 - latest version (and Xdebug to 2.7.0beta1 latest version compatible with PHP 7.3, in case it matters), tinker is no longer working. It launches correctly but I after I input a command it just exits with no error, nothing written to log file and status code 0.

Command "tinker" is not defined.

Using Laravel Framework 5.4.23

and

name     : laravel/tinker
descrip. : Powerful REPL for the Laravel framework.
keywords : REPL, Tinker, laravel, psysh
versions : * v1.0.0
type     : library
license  : MIT License (MIT) (OSI approved) https://spdx.org/licenses/MIT.html#licenseText
source   : [git] https://github.com/laravel/tinker.git 3d5b675b55b24ccbf86395964042dbe061d5a965
dist     : [zip] https://api.github.com/repos/laravel/tinker/zipball/3d5b675b55b24ccbf86395964042dbe061d5a965 3d5b675b55b24ccbf86395964042dbe061d5a965
names    : laravel/tinker

autoload
psr-4
Laravel\Tinker\ => src/

requires
illuminate/console ~5.1
illuminate/contracts ~5.1
illuminate/support ~5.1
php >=5.5.9
psy/psysh 0.7.*|0.8.*
symfony/var-dumper ~3.0

requires (dev)
phpunit/phpunit ~4.0|~5.0

suggests
illuminate/database The Illuminate Database package (~5.1).

when i do php artisan tinker as described on Repo's README.md file i got this error:

[Symfony\Component\Console\Exception\CommandNotFoundException]
  Command "tinker" is not defined.

i tried this on an empty project from scratch and tinker is working - not on my current project

Models don't display hidden/appended attributes

When displaying a models attributes, items added with $append are not displayed.

This is because $get->attributes() (here) doesn't return them.

The only sane way I can think to do this is to iterate over the appends array and add them to the $appends array before iterating for the results.

Here's a patch that will show the appended elements, as well as fixes what looks to be a minor bug in that it only showed visible attributes before — highlighting visible/hidden/appended differently:

diff --git a/src/TinkerCaster.php b/src/TinkerCaster.php
--- a/src/TinkerCaster.php	(date 1613706042053)
+++ b/src/TinkerCaster.php	(date 1613706042053)
@@ -109,11 +109,33 @@
         $visible = array_flip(
             $model->getVisible() ?: array_diff(array_keys($attributes), $model->getHidden())
         );
+        $hidden = array_flip($model->getHidden());
+
+        $appends = (function() {
+            return array_combine($this->appends, $this->appends);
+        })->bindTo($model, $model)();
+        foreach ($appends as $appended) {
+            $attributes[$appended] = $model->{$appended};
+        }
 
         $results = [];
 
-        foreach (array_intersect_key($attributes, $visible) as $key => $value) {
-            $results[(isset($visible[$key]) ? Caster::PREFIX_VIRTUAL : Caster::PREFIX_PROTECTED).$key] = $value;
+        foreach ($attributes as $key => $value) {
+            $prefix = '';
+
+            if (isset($visible[$key])) {
+                $prefix = Caster::PREFIX_VIRTUAL;
+            }
+
+            if (isset($hidden[$key])) {
+                $prefix = Caster::PREFIX_PROTECTED;
+            }
+
+            $results[$prefix.$key] = $value;
         }
 
         return $results;

This output for a standard User model (faker data, with UUID keys), which hides password and remember_token attributes, and also has an is_deleted attribute appended:

image

(Apologies for not submitting a PR, I couldn't figure out which branch to best use)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.