@phpsandbox/sdk 0.0.14 → 0.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,46 +1,6 @@
1
1
  # PHPSandbox SDK
2
2
 
3
- A comprehensive TypeScript SDK for interacting with cloud-based PHP development environments. The PHPSandbox SDK provides programmatic access to containerized PHP environments with full filesystem, terminal, and development tool integration.
4
-
5
- ## Table of Contents
6
-
7
- - [PHPSandbox SDK](#phpsandbox-sdk)
8
- - [Table of Contents](#table-of-contents)
9
- - [Installation](#installation)
10
- - [Quick Start](#quick-start)
11
- - [Authentication](#authentication)
12
- - [Core Concepts](#core-concepts)
13
- - [Client](#client)
14
- - [NotebookInstance](#notebookinstance)
15
- - [Event-Driven Architecture](#event-driven-architecture)
16
- - [API Reference](#api-reference)
17
- - [Client](#client-1)
18
- - [NotebookApi Methods](#notebookapi-methods)
19
- - [NotebookInstance](#notebookinstance-1)
20
- - [Filesystem](#filesystem)
21
- - [File Search Example](#file-search-example)
22
- - [Terminal](#terminal)
23
- - [Terminal Usage Example](#terminal-usage-example)
24
- - [Container](#container)
25
- - [Language Server Protocol (LSP)](#language-server-protocol-lsp)
26
- - [Composer](#composer)
27
- - [Git](#git)
28
- - [Laravel](#laravel)
29
- - [REPL](#repl)
30
- - [Shell](#shell)
31
- - [Auth](#auth)
32
- - [Logging](#logging)
33
- - [Event System](#event-system)
34
- - [Error Handling](#error-handling)
35
- - [Common Error Types](#common-error-types)
36
- - [Examples](#examples)
37
- - [Complete Laravel Application Setup](#complete-laravel-application-setup)
38
- - [File Processing Pipeline](#file-processing-pipeline)
39
- - [Real-time Development Environment](#real-time-development-environment)
40
- - [TypeScript Support](#typescript-support)
41
- - [Generic Types](#generic-types)
42
- - [Support and Contributing](#support-and-contributing)
43
- - [License](#license)
3
+ TypeScript SDK for working with PHPSandbox notebooks: create environments, edit files, run commands, and stream real-time events.
44
4
 
45
5
  ## Installation
46
6
 
@@ -48,671 +8,222 @@ A comprehensive TypeScript SDK for interacting with cloud-based PHP development
48
8
  npm install @phpsandbox/sdk
49
9
  ```
50
10
 
11
+ Node.js `>=18` is required.
12
+
51
13
  ## Quick Start
52
14
 
53
- ```typescript
15
+ ```ts
54
16
  import { PHPSandbox } from '@phpsandbox/sdk';
55
17
 
56
- // Create a client instance
57
- const client = new PHPSandbox('your-api-token');
58
-
59
- // Create and initialize a new notebook
60
- const notebook = await client.notebook.create('laravel');
18
+ const token = process.env.PHPSANDBOX_TOKEN;
19
+ if (!token) throw new Error('Missing PHPSANDBOX_TOKEN');
61
20
 
62
- // Access various services
63
- const files = notebook.file;
64
- const terminal = notebook.terminal;
65
- const container = notebook.container;
21
+ const client = new PHPSandbox(token);
66
22
 
67
- // Write a PHP file
68
- await files.write('index.php', '<?php echo "Hello World!"; ?>');
23
+ // create() initializes the notebook by default
24
+ const notebook = await client.notebook.create('php');
69
25
 
70
- // Execute a command
71
- const process = await terminal.spawn('php', ['index.php']);
72
- process.output
73
- .getReader()
74
- .read()
75
- .then(({ value }) => {
76
- console.log(value); // "Hello World!"
77
- });
78
- ```
79
-
80
- ## Authentication
26
+ await notebook.file.write('index.php', '<?php echo "Hello from PHPSandbox";');
81
27
 
82
- The SDK requires an API token for authentication:
28
+ const process = await notebook.terminal.spawn('php', ['index.php']);
83
29
 
84
- ```typescript
85
- // Using environment variable (recommended)
86
- const client = new PHPSandbox(process.env.PHPSANDBOX_TOKEN);
30
+ const reader = process.output.getReader();
31
+ let output = '';
32
+ try {
33
+ while (true) {
34
+ const { done, value } = await reader.read();
35
+ if (done) break;
36
+ output += value;
37
+ }
38
+ } finally {
39
+ reader.releaseLock();
40
+ }
87
41
 
88
- // Or direct token
89
- const client = new PHPSandbox('your-token-here');
42
+ await process.exit;
43
+ console.log(output.trim());
90
44
 
91
- // Custom API URL (optional)
92
- const client = new PHPSandbox('token', 'https://api.phpsandbox.io/v1');
45
+ // close websocket resources when done
46
+ notebook.dispose();
93
47
  ```
94
48
 
95
- ## Core Concepts
96
-
97
- ### Client
49
+ ## Authentication
98
50
 
99
- The main entry point for the SDK. Handles authentication and provides access to notebook management.
51
+ Use an API token:
100
52
 
101
- ### NotebookInstance
53
+ ```ts
54
+ import { PHPSandbox } from '@phpsandbox/sdk';
102
55
 
103
- Represents a containerized PHP environment with access to all development tools:
56
+ const client = new PHPSandbox(process.env.PHPSANDBOX_TOKEN!);
57
+ ```
104
58
 
105
- - **Filesystem**: File operations, search, and monitoring
106
- - **Terminal**: Interactive terminal and process execution
107
- - **Container**: Environment management and monitoring
108
- - **LSP**: Language server integration for IDE features
109
- - **Development Tools**: Composer, Git, Laravel tooling, REPL
59
+ Optional constructor args:
110
60
 
111
- ### Event-Driven Architecture
61
+ ```ts
62
+ new PHPSandbox('token', 'https://api.phpsandbox.io/v1', {
63
+ debug: false,
64
+ startClosed: true,
65
+ });
66
+ ```
112
67
 
113
- The SDK uses WebSocket connections for real-time communication and events.
68
+ ## Notebook Lifecycle
114
69
 
115
- ## API Reference
70
+ ```ts
71
+ const client = new PHPSandbox(process.env.PHPSANDBOX_TOKEN!);
116
72
 
117
- ### Client
73
+ const created = await client.notebook.create('laravel');
74
+ const opened = await client.notebook.open('notebook-id');
75
+ await opened.ready();
118
76
 
119
- ```typescript
120
- class PHPSandbox {
121
- constructor(token: string, url?: string, options?: PHPSandboxClientOptions);
77
+ const fetched = await client.notebook.get('notebook-id');
78
+ await fetched.ready();
122
79
 
123
- readonly notebook: NotebookApi;
124
- readonly http: AxiosInstance;
125
- }
80
+ const forked = await created.fork();
81
+ await forked.delete();
126
82
  ```
127
83
 
128
- #### NotebookApi Methods
84
+ Notes:
129
85
 
130
- ```typescript
131
- // Create a new notebook from a template
132
- create(template: string, input?: Partial<CreateNotebookInput>, init?: boolean): Promise<NotebookInstance>
86
+ - `create()` and `fork()` initialize automatically.
87
+ - `open()` and `get()` return a notebook instance; call `await notebook.ready()` before using tools.
133
88
 
134
- // Get existing notebook by ID
135
- get(id: string): Promise<NotebookInstance>
89
+ ## Services At A Glance
136
90
 
137
- // Fork an existing notebook
138
- fork(id: string): Promise<NotebookInstance>
91
+ Each `NotebookInstance` exposes service clients:
139
92
 
140
- // Open and initialize a notebook
141
- open(id: string): Promise<NotebookInstance>
93
+ - `notebook.file` (`Filesystem`)
94
+ - `notebook.terminal` (`Terminal`)
95
+ - `notebook.container` (`Container`)
96
+ - `notebook.shell` (`Shell`)
97
+ - `notebook.composer` (`Composer`)
98
+ - `notebook.git` (`Git`)
99
+ - `notebook.lsp` (`Lsp`)
100
+ - `notebook.repl` (`Repl`)
101
+ - `notebook.laravel` (`Laravel`)
102
+ - `notebook.auth` (`Auth`)
103
+ - `notebook.log` (`Log`)
142
104
 
143
- // Create from existing data
144
- openFromData(data: NotebookData): Promise<NotebookInstance>
145
- ```
105
+ ## Common Operations
146
106
 
147
- ### NotebookInstance
148
-
149
- The core class providing access to all development environment features.
150
-
151
- ```typescript
152
- class NotebookInstance {
153
- // Core services
154
- readonly file: Filesystem;
155
- readonly terminal: Terminal;
156
- readonly container: Container;
157
- readonly lsp: Lsp;
158
- readonly composer: Composer;
159
- readonly git: Git;
160
- readonly laravel: Laravel;
161
- readonly repl: Repl;
162
- readonly shell: Shell;
163
- readonly auth: Auth;
164
- readonly log: Log;
165
-
166
- // Connection management
167
- ready(): Promise<NotebookInitResult>;
168
- connected(): Promise<NotebookInstance>;
169
- reconnect(): void;
170
- dispose(): void;
171
-
172
- // Event handling
173
- listen<T extends keyof Events>(event: T, handler: (data: Events[T]) => void): Disposable;
174
- onDidConnect(handler: () => void): Disposable;
175
- onDidDisconnect(handler: () => void): Disposable;
176
-
177
- // Direct API calls
178
- invoke<T extends keyof Invokable>(
179
- action: T,
180
- data?: Invokable[T]['args'],
181
- options?: CallOption
182
- ): Promise<Invokable[T]['response']>;
183
- }
184
- ```
107
+ ### Files
185
108
 
186
- ### Filesystem
187
-
188
- Comprehensive file system operations with advanced search and monitoring capabilities.
189
-
190
- ```typescript
191
- class Filesystem {
192
- // File operations
193
- readFile(path: string, lineRange?: { lineStart: number; lineEnd: number }): Promise<Uint8Array | ReadFileRangeResult>;
194
- writeFile(path: string, contents: Uint8Array, options: FileWriteOptions): Promise<void>;
195
- info(path: string): Promise<FileInfo>;
196
- stat(path: string): Promise<Stats>;
197
- exists(path: string): Promise<boolean>;
198
-
199
- // Directory operations
200
- createDirectory(path: string): Promise<void>;
201
- readDirectory(path: string, include?: string[], exclude?: string[]): Promise<[string, FileType, number | null][]>;
202
-
203
- // File management
204
- copy(source: string, destination: string, options: FileOverwriteOptions): Promise<void>;
205
- move(from: string, to: string): Promise<boolean>;
206
- rename(from: string, to: string, options: FileOverwriteOptions): Promise<void>;
207
- delete(path: string, options: FileDeleteOptions): Promise<void>;
208
-
209
- // Search capabilities
210
- find(query: string, options?: Partial<FileSearchOptions>): Promise<FileResult[]>;
211
- search(
212
- query: TextSearchQuery,
213
- options?: Partial<TextSearchOptions>,
214
- onMatch?: (result: TextSearchResult | false) => void
215
- ): Promise<[boolean, TextSearchMatch[]]>;
216
-
217
- // File monitoring
218
- watch(path: string, options: WatchOptions, onDidChange: (e: FileChange) => void): FilesystemSubscription;
219
-
220
- // Bulk operations
221
- download(chunk?: (data: Uint8Array) => void, exclude?: string[]): Promise<Blob>;
222
- }
223
- ```
109
+ ```ts
110
+ await notebook.file.write('README.md', '# App');
224
111
 
225
- #### File Search Example
112
+ const raw = await notebook.file.readFile('README.md');
113
+ const text = new TextDecoder().decode(raw);
226
114
 
227
- ```typescript
228
- // Find files by name
229
- const phpFiles = await notebook.file.find('*.php', {
230
- includes: ['src/**'],
115
+ const files = await notebook.file.find('*.php', {
116
+ includes: ['app/**'],
231
117
  excludes: ['vendor/**'],
232
- useIgnoreFiles: true,
233
118
  });
234
119
 
235
- // Full-text search with context
236
120
  const [hasMore, matches] = await notebook.file.search(
237
- { pattern: 'function.*authenticate', isRegExp: true },
238
- { maxResults: 50, beforeContext: 2, afterContext: 2 }
121
+ { pattern: 'class\\s+User', isRegExp: true },
122
+ { maxResults: 20, includes: ['app/**'], excludes: ['vendor/**'] }
239
123
  );
240
124
  ```
241
125
 
242
126
  ### Terminal
243
127
 
244
- Interactive terminal with process execution and stream handling.
245
-
246
- ```typescript
247
- class Terminal {
248
- // Terminal management
249
- create(input: TerminalCreateInput): Promise<Task>;
250
- list(): Promise<Task[]>;
251
- resize(id: string, size: [number, number]): Promise<boolean>;
252
- input(id: string, input: string): Promise<void>;
253
-
254
- // Process execution
255
- spawn(command: string, args: string[], opts?: SpawnOptions): Promise<SandboxProcess & Task>;
256
-
257
- // Event handling
258
- onStarted(handler: (task: Task) => void): void;
259
- onOutput(id: string, handler: (data: TerminalEvents['terminal.output']) => void): void;
260
- listen<T extends keyof TerminalEvents>(event: T, handler: (data: TerminalEvents[T]) => void): Disposable;
261
- }
262
- ```
263
-
264
- #### Terminal Usage Example
128
+ ```ts
129
+ const task = await notebook.terminal.spawn('composer', ['--version']);
265
130
 
266
- ```typescript
267
- // Spawn a process with I/O streams
268
- const process = await notebook.terminal.spawn('composer', ['install'], {
269
- cwd: '/app',
270
- env: { COMPOSER_NO_INTERACTION: '1' },
271
- });
272
-
273
- // Handle output stream
274
- const reader = process.output.getReader();
275
- while (true) {
276
- const { done, value } = await reader.read();
277
- if (done) break;
131
+ task.output.getReader().read().then(({ value }) => {
278
132
  console.log(value);
279
- }
280
-
281
- // Wait for completion
282
- const exitCode = await process.exit;
283
- console.log(`Process exited with code: ${exitCode}`);
284
- ```
285
-
286
- ### Container
287
-
288
- Container lifecycle and resource management.
289
-
290
- ```typescript
291
- class Container {
292
- // Container control
293
- start(): Promise<void>;
294
- stop(): Promise<void>;
295
- state(): Promise<{ state: NotebookState }>;
296
-
297
- // Port management
298
- openedPorts(): Promise<PortInfo[]>;
299
- onPort(handler: (port: PortInfo, type: 'open' | 'close') => void): Disposable;
300
-
301
- // Environment configuration
302
- setPhp(version: string): Promise<{ version: string }>;
133
+ });
303
134
 
304
- // Resource monitoring
305
- listen<T extends keyof ContainerEvents>(event: T, handler: (data: ContainerEvents[T]) => void): void;
306
- }
135
+ const exitCode = await task.exit;
136
+ console.log(exitCode);
307
137
  ```
308
138
 
309
- ### Language Server Protocol (LSP)
310
-
311
- IDE-like features through Language Server Protocol integration.
312
-
313
- ```typescript
314
- class Lsp {
315
- // Connection management
316
- connection(id: string): LspConnection;
317
- start(id: string): Promise<void>;
318
- close(id: string): Promise<void>;
319
-
320
- // Communication
321
- message(id: string, message: string): Promise<void>;
322
-
323
- // Event handling
324
- onResponse(id: string, cb: (data: string) => void): void;
325
- onError(id: string, cb: (message: string) => void): void;
326
- onClose(id: string, cb: (code: number, reason: string) => void): void;
327
- }
139
+ ### Shell
328
140
 
329
- class LspConnection {
330
- send(content: string): Promise<void>;
331
- onMessage(cb: (data: string) => void): void;
332
- onError(cb: (message: string) => void): void;
333
- onClose(cb: (code: number, reason: string) => void): void;
334
- start(): Promise<void>;
335
- dispose(): void;
336
- }
141
+ ```ts
142
+ const result = await notebook.shell.exec('php -v');
143
+ result.throw();
144
+ console.log(result.output);
337
145
  ```
338
146
 
339
147
  ### Composer
340
148
 
341
- PHP dependency management integration.
342
-
343
- ```typescript
344
- class Composer {
345
- // Package management
346
- install(packages?: string[]): Promise<void>;
347
- update(packages?: string[]): Promise<void>;
348
- remove(packages: string[]): Promise<void>;
349
-
350
- // Project operations
351
- init(options?: ComposerInitOptions): Promise<void>;
352
- validate(): Promise<void>;
353
-
354
- // Information
355
- show(package?: string): Promise<object>;
356
- outdated(): Promise<object>;
149
+ ```ts
150
+ await notebook.composer.install({ noInteraction: true });
151
+ await notebook.composer.require({ packages: ['monolog/monolog'] });
357
152
 
358
- // Event handling
359
- listen<T extends keyof ComposerEvents>(event: T, handler: (data: ComposerEvents[T]) => void): Disposable;
360
- }
153
+ const installed = await notebook.composer.packages();
154
+ console.log(installed.map((pkg) => pkg.name));
361
155
  ```
362
156
 
363
157
  ### Git
364
158
 
365
- Version control operations and repository management.
366
-
367
- ```typescript
368
- class Git {
369
- // Repository operations
370
- init(): Promise<void>;
371
- clone(url: string, directory?: string): Promise<void>;
372
-
373
- // Branch management
374
- branch(name?: string): Promise<string[] | void>;
375
- checkout(branch: string): Promise<void>;
376
-
377
- // Staging and commits
378
- add(files: string[]): Promise<void>;
379
- commit(message: string): Promise<void>;
380
- push(remote?: string, branch?: string): Promise<void>;
381
- pull(remote?: string, branch?: string): Promise<void>;
382
-
383
- // Information
384
- status(): Promise<GitStatus>;
385
- log(options?: GitLogOptions): Promise<GitCommit[]>;
386
- diff(options?: GitDiffOptions): Promise<string>;
387
-
388
- // Event handling
389
- listen<T extends keyof GitEvents>(event: T, handler: (data: GitEvents[T]) => void): Disposable;
390
- }
391
- ```
392
-
393
- ### Laravel
394
-
395
- Laravel-specific development tools and utilities.
396
-
397
- ```typescript
398
- class Laravel {
399
- // Artisan commands
400
- artisan(command: string, args?: string[]): Promise<void>
401
-
402
- // Code generation
403
- make(type: string, name: string, options?: object): Promise<void>
404
-
405
- // Database operations
406
- migrate(options?: MigrateOptions): Promise<void>
407
- seed(class?: string): Promise<void>
408
-
409
- // Cache management
410
- cache(action: 'clear' | 'config' | 'route' | 'view'): Promise<void>
411
-
412
- // Event handling
413
- listen<T extends keyof LaravelEvents>(event: T, handler: (data: LaravelEvents[T]) => void): Disposable
414
- }
415
- ```
416
-
417
- ### REPL
418
-
419
- Interactive PHP execution environment.
420
-
421
- ```typescript
422
- class Repl {
423
- // Code execution
424
- execute(code: string): Promise<ReplResult>;
425
-
426
- // Session management
427
- reset(): Promise<void>;
428
-
429
- // Variable inspection
430
- variables(): Promise<object>;
159
+ ```ts
160
+ await notebook.git.checkpoint('Jane Doe <jane@example.com>', 'Initial checkpoint');
431
161
 
432
- // Event handling
433
- listen<T extends keyof ReplEvents>(event: T, handler: (data: ReplEvents[T]) => void): Disposable;
434
- }
435
- ```
436
-
437
- ### Shell
438
-
439
- Shell command execution with customizable environments.
440
-
441
- ```typescript
442
- class Shell {
443
- // Command execution
444
- execute(command: string, options?: ShellOptions): Promise<ShellResult>;
445
-
446
- // Environment management
447
- setEnv(variables: Record<string, string>): Promise<void>;
448
- getEnv(): Promise<Record<string, string>>;
449
-
450
- // Working directory
451
- pwd(): Promise<string>;
452
- cd(directory: string): Promise<void>;
453
-
454
- // Event handling
455
- listen<T extends keyof ShellEvents>(event: T, handler: (data: ShellEvents[T]) => void): Disposable;
456
- }
457
- ```
458
-
459
- ### Auth
460
-
461
- Authentication and authorization services.
462
-
463
- ```typescript
464
- class Auth {
465
- // Token management
466
- login(credentials: LoginCredentials): Promise<AuthResult>;
467
- logout(): Promise<void>;
468
- refresh(): Promise<AuthResult>;
469
-
470
- // User information
471
- user(): Promise<User>;
472
-
473
- // Permissions
474
- can(permission: string): Promise<boolean>;
475
- }
476
- ```
477
-
478
- ### Logging
479
-
480
- Application logging and monitoring.
481
-
482
- ```typescript
483
- class Log {
484
- // Log levels
485
- debug(message: string, context?: object): Promise<void>;
486
- info(message: string, context?: object): Promise<void>;
487
- warning(message: string, context?: object): Promise<void>;
488
- error(message: string, context?: object): Promise<void>;
489
-
490
- // Log retrieval
491
- recent(limit?: number): Promise<LogEntry[]>;
492
- search(query: string, options?: LogSearchOptions): Promise<LogEntry[]>;
162
+ await notebook.git.sync(
163
+ 'https://github.com/acme/my-repo.git',
164
+ 'Jane Doe <jane@example.com>',
165
+ 'main',
166
+ process.env.GITHUB_TOKEN,
167
+ 'pull'
168
+ );
493
169
 
494
- // Event handling
495
- listen<T extends keyof LogEvents>(event: T, handler: (data: LogEvents[T]) => void): Disposable;
496
- }
170
+ const history = await notebook.git.log('main');
171
+ console.log(history[0]);
497
172
  ```
498
173
 
499
- ## Event System
500
-
501
- The SDK provides a comprehensive event system for real-time updates:
502
-
503
- ```typescript
504
- // File system events
505
- notebook.file.watch('/app', { recursive: true }, (change) => {
506
- console.log(`File ${change.path} was ${change.type}`);
507
- });
508
-
509
- // Terminal output
510
- notebook.terminal.onOutput('terminal-id', (data) => {
511
- console.log(data.output);
512
- });
174
+ ### Events
513
175
 
514
- // Container stats
515
- notebook.container.listen('container.stats', (stats) => {
516
- console.log(`CPU: ${stats.cpu.usage}/${stats.cpu.limit}`);
176
+ ```ts
177
+ const disposeConnect = notebook.onDidConnect(() => {
178
+ console.log('connected');
517
179
  });
518
180
 
519
- // Connection events
520
- notebook.onDidConnect(() => {
521
- console.log('Connected to notebook');
522
- });
181
+ const disposeFs = notebook.file.watch(
182
+ '/app',
183
+ { recursive: true, excludes: ['vendor/**', 'node_modules/**'] },
184
+ (change) => {
185
+ console.log(change.type, change.path);
186
+ }
187
+ );
523
188
 
524
- notebook.onDidDisconnect(() => {
525
- console.log('Disconnected from notebook');
526
- });
189
+ // later
190
+ disposeConnect.dispose();
191
+ disposeFs.dispose();
527
192
  ```
528
193
 
529
194
  ## Error Handling
530
195
 
531
- The SDK provides structured error handling with specific error types:
532
-
533
- ```typescript
534
- import { FilesystemError, FilesystemErrorType, ErrorEvent } from '@phpsandbox/sdk';
196
+ ```ts
197
+ import { ApiError, FilesystemError, FilesystemErrorType } from '@phpsandbox/sdk';
535
198
 
536
199
  try {
537
- await notebook.file.readFile('/nonexistent.php');
200
+ await notebook.file.readFile('/does-not-exist.php');
538
201
  } catch (error) {
539
202
  if (error instanceof FilesystemError && error.name === FilesystemErrorType.FileNotFound) {
540
- console.log('File not found');
541
- } else if (error instanceof ErrorEvent) {
542
- console.log(`Error ${error.code}: ${error.message}`);
203
+ console.error('Missing file');
204
+ } else if (error instanceof ApiError) {
205
+ console.error(error.status, error.body);
206
+ } else {
207
+ throw error;
543
208
  }
544
209
  }
545
210
  ```
546
211
 
547
- ### Common Error Types
212
+ ## Browser/CDN Usage
548
213
 
549
- - `FilesystemError`: File system operation errors
550
- - `RateLimitError`: API rate limiting
551
- - `NotebookInitError`: Notebook initialization failures
552
- - `ErrorEvent`: Base error class with error codes
214
+ See `docs/cdn-usage.md` for ESM and script-tag examples.
553
215
 
554
- ## Examples
216
+ ## More Docs
555
217
 
556
- ### Complete Laravel Application Setup
557
-
558
- ```typescript
559
- import { PHPSandbox } from '@phpsandbox/sdk';
560
-
561
- async function setupLaravelApp() {
562
- const client = new PHPSandbox(process.env.PHPSANDBOX_TOKEN);
563
- const notebook = await client.notebook.create('laravel');
564
-
565
- // Wait for container to be ready
566
- await notebook.ready();
567
-
568
- // Install additional dependencies
569
- await notebook.composer.install(['laravel/sanctum', 'laravel/horizon']);
570
-
571
- // Create a new controller
572
- await notebook.laravel.make('controller', 'ApiController', { resource: true });
573
-
574
- // Run migrations
575
- await notebook.laravel.migrate();
576
-
577
- // Set up Git repository
578
- await notebook.git.init();
579
- await notebook.git.add(['.']);
580
- await notebook.git.commit('Initial commit');
581
-
582
- // Start development server
583
- const server = await notebook.terminal.spawn('php', ['artisan', 'serve', '--host=0.0.0.0']);
584
-
585
- // Monitor for open ports
586
- notebook.container.onPort((port, type) => {
587
- if (type === 'open' && port.port === 8000) {
588
- console.log(`Laravel server available at: ${port.url}`);
589
- }
590
- });
591
-
592
- return notebook;
593
- }
594
- ```
595
-
596
- ### File Processing Pipeline
597
-
598
- ```typescript
599
- async function processPhpFiles(notebook: NotebookInstance) {
600
- // Find all PHP files
601
- const phpFiles = await notebook.file.find('*.php', {
602
- includes: ['app/**', 'src/**'],
603
- excludes: ['vendor/**', 'node_modules/**'],
604
- });
605
-
606
- // Process each file
607
- for (const file of phpFiles) {
608
- const content = await notebook.file.readFile(file.path);
609
-
610
- // Run PHP CS Fixer
611
- await notebook.terminal.spawn('php-cs-fixer', ['fix', file.path]);
612
-
613
- // Run static analysis
614
- const analysis = await notebook.terminal.spawn('phpstan', ['analyse', file.path]);
615
-
616
- // Wait for completion
617
- await analysis.exit;
618
- }
619
-
620
- console.log(`Processed ${phpFiles.length} PHP files`);
621
- }
622
- ```
623
-
624
- ### Real-time Development Environment
625
-
626
- ```typescript
627
- async function createDevelopmentEnvironment() {
628
- const client = new PHPSandbox(process.env.PHPSANDBOX_TOKEN);
629
- const notebook = await client.notebook.create('php');
630
-
631
- // Set up file watching
632
- notebook.file.watch('/app', { recursive: true }, (change) => {
633
- console.log(`[${new Date().toISOString()}] ${change.path} ${change.type}`);
634
-
635
- // Auto-reload on PHP file changes
636
- if (change.path.endsWith('.php') && change.type === 'UPDATED') {
637
- notebook.repl.execute(`include '${change.path}';`);
638
- }
639
- });
640
-
641
- // Set up LSP for IDE features
642
- const lspConnection = notebook.lsp.connection('php-lsp');
643
- await lspConnection.start();
644
-
645
- lspConnection.onMessage((message) => {
646
- const data = JSON.parse(message);
647
- if (data.method === 'textDocument/publishDiagnostics') {
648
- console.log('Diagnostics:', data.params.diagnostics);
649
- }
650
- });
651
-
652
- // Monitor container resources
653
- notebook.container.listen('container.stats', (stats) => {
654
- if (stats.memory.usage / stats.memory.limit > 0.8) {
655
- console.warn('High memory usage detected');
656
- }
657
- });
658
-
659
- return notebook;
660
- }
661
- ```
662
-
663
- ## TypeScript Support
664
-
665
- The SDK is built with TypeScript and provides comprehensive type definitions:
666
-
667
- ```typescript
668
- import type {
669
- NotebookInstance,
670
- FileInfo,
671
- Stats,
672
- TextSearchQuery,
673
- TerminalCreateInput,
674
- ContainerStats,
675
- Events,
676
- FilesystemEvents,
677
- } from '@phpsandbox/sdk';
678
-
679
- // Type-safe event handling
680
- notebook.listen('fs.watch', (change: Events['fs.watch']) => {
681
- // change is properly typed as FileChange
682
- console.log(change.path, change.type);
683
- });
684
-
685
- // Type-safe API calls
686
- const stats: Stats = await notebook.file.stat('/app/composer.json');
687
- const info: FileInfo = await notebook.file.info('/app/index.php');
688
- ```
689
-
690
- ### Generic Types
691
-
692
- ```typescript
693
- // Custom event handlers
694
- type CustomEventHandler<T extends keyof Events> = (data: Events[T]) => void;
695
-
696
- // Action types
697
- type FileSystemActions = FilesystemActions;
698
- type TerminalActions = TerminalActions;
699
-
700
- // Disposable pattern
701
- const disposable: Disposable = notebook.onDidConnect(() => {
702
- console.log('Connected');
703
- });
704
-
705
- // Clean up when done
706
- disposable.dispose();
707
- ```
218
+ - Getting started walkthrough: `docs/getting-started.md`
219
+ - API overview: `docs/api-summary.md`
220
+ - Examples: `examples/README.md`
708
221
 
709
- ## Support and Contributing
222
+ ## Support
710
223
 
711
- - **Documentation**: [https://docs.phpsandbox.io](https://docs.phpsandbox.io)
712
- - **API Reference**: [https://api.phpsandbox.io/docs](https://api.phpsandbox.io/docs)
713
- - **Issues**: [GitHub Issues](https://github.com/phpsandbox/sdk/issues)
714
- - **Examples**: [GitHub Examples](https://github.com/phpsandbox/examples)
224
+ - Issues: https://github.com/phpsandbox/sdk/issues
225
+ - Product docs: https://docs.phpsandbox.io
715
226
 
716
227
  ## License
717
228
 
718
- MIT License - see LICENSE file for details.
229
+ MIT