@studiometa/forge-sdk 0.0.1 → 0.2.0

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.
Files changed (50) hide show
  1. package/README.md +178 -0
  2. package/dist/forge.d.ts +93 -0
  3. package/dist/forge.d.ts.map +1 -0
  4. package/dist/index.d.ts +40 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +2049 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/pagination.d.ts +34 -0
  9. package/dist/pagination.d.ts.map +1 -0
  10. package/dist/resources/backups.d.ts +86 -0
  11. package/dist/resources/backups.d.ts.map +1 -0
  12. package/dist/resources/base.d.ts +10 -0
  13. package/dist/resources/base.d.ts.map +1 -0
  14. package/dist/resources/certificates.d.ts +102 -0
  15. package/dist/resources/certificates.d.ts.map +1 -0
  16. package/dist/resources/commands.d.ts +74 -0
  17. package/dist/resources/commands.d.ts.map +1 -0
  18. package/dist/resources/daemons.d.ts +92 -0
  19. package/dist/resources/daemons.d.ts.map +1 -0
  20. package/dist/resources/database-users.d.ts +84 -0
  21. package/dist/resources/database-users.d.ts.map +1 -0
  22. package/dist/resources/databases.d.ts +84 -0
  23. package/dist/resources/databases.d.ts.map +1 -0
  24. package/dist/resources/deployments.d.ts +90 -0
  25. package/dist/resources/deployments.d.ts.map +1 -0
  26. package/dist/resources/firewall-rules.d.ts +84 -0
  27. package/dist/resources/firewall-rules.d.ts.map +1 -0
  28. package/dist/resources/monitors.d.ts +85 -0
  29. package/dist/resources/monitors.d.ts.map +1 -0
  30. package/dist/resources/nginx-templates.d.ts +95 -0
  31. package/dist/resources/nginx-templates.d.ts.map +1 -0
  32. package/dist/resources/recipes.d.ts +99 -0
  33. package/dist/resources/recipes.d.ts.map +1 -0
  34. package/dist/resources/redirect-rules.d.ts +85 -0
  35. package/dist/resources/redirect-rules.d.ts.map +1 -0
  36. package/dist/resources/scheduled-jobs.d.ts +84 -0
  37. package/dist/resources/scheduled-jobs.d.ts.map +1 -0
  38. package/dist/resources/security-rules.d.ts +85 -0
  39. package/dist/resources/security-rules.d.ts.map +1 -0
  40. package/dist/resources/servers.d.ts +199 -0
  41. package/dist/resources/servers.d.ts.map +1 -0
  42. package/dist/resources/sites.d.ts +216 -0
  43. package/dist/resources/sites.d.ts.map +1 -0
  44. package/dist/resources/ssh-keys.d.ts +83 -0
  45. package/dist/resources/ssh-keys.d.ts.map +1 -0
  46. package/dist/test-utils.d.ts +27 -0
  47. package/dist/test-utils.d.ts.map +1 -0
  48. package/dist/test-utils.js +38 -0
  49. package/dist/test-utils.js.map +1 -0
  50. package/package.json +37 -1
package/README.md ADDED
@@ -0,0 +1,178 @@
1
+ # @studiometa/forge-sdk
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@studiometa/forge-sdk?style=flat&colorB=3e63dd&colorA=414853)](https://www.npmjs.com/package/@studiometa/forge-sdk)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat&colorB=3e63dd&colorA=414853)](https://opensource.org/licenses/MIT)
5
+
6
+ **The missing TypeScript SDK for Laravel Forge.** Fluent, chainable, fully-typed API client.
7
+
8
+ The official Forge SDK exists only in PHP (`laravel/forge-sdk`). This package fills the gap with a modern TypeScript SDK that mirrors the Forge URL structure in a fluent, chainable API.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install @studiometa/forge-sdk
14
+ ```
15
+
16
+ ## Quick Start
17
+
18
+ ```typescript
19
+ import { Forge } from "@studiometa/forge-sdk";
20
+
21
+ const forge = new Forge("your-api-token");
22
+
23
+ // List all servers
24
+ const servers = await forge.servers.list();
25
+
26
+ // Get a specific server
27
+ const server = await forge.servers.get(123);
28
+
29
+ // Deploy a site
30
+ await forge.server(123).site(456).deploy();
31
+
32
+ // Get environment variables
33
+ const env = await forge.server(123).site(456).env.get();
34
+
35
+ // Update environment
36
+ await forge.server(123).site(456).env.update("APP_ENV=production\nAPP_DEBUG=false");
37
+ ```
38
+
39
+ ## API Reference
40
+
41
+ ### Servers
42
+
43
+ ```typescript
44
+ // Collection operations
45
+ forge.servers.list() // List all servers
46
+ forge.servers.get(id) // Get a server
47
+ forge.servers.create({ ... }) // Create a server
48
+ forge.servers.update(id, { ... }) // Update a server
49
+ forge.servers.delete(id) // Delete a server
50
+ forge.servers.reboot(id) // Reboot a server
51
+
52
+ // Resource with nested access
53
+ forge.server(id).get() // Get server details
54
+ forge.server(id).reboot() // Reboot server
55
+ forge.server(id).delete() // Delete server
56
+ forge.server(id).sites.list() // List sites on server
57
+ forge.server(id).databases.list() // List databases
58
+ forge.server(id).daemons.list() // List daemons
59
+ ```
60
+
61
+ ### Sites
62
+
63
+ ```typescript
64
+ // Collection operations
65
+ forge.server(id).sites.list() // List all sites
66
+ forge.server(id).sites.get(siteId) // Get a site
67
+ forge.server(id).sites.create({ domain: 'example.com', project_type: 'php' })
68
+ forge.server(id).sites.update(siteId, { ... })
69
+ forge.server(id).sites.delete(siteId)
70
+
71
+ // Resource with nested access
72
+ forge.server(id).site(siteId).get() // Get site details
73
+ forge.server(id).site(siteId).deploy() // Deploy site
74
+ forge.server(id).site(siteId).delete() // Delete site
75
+ forge.server(id).site(siteId).env.get() // Get .env content
76
+ forge.server(id).site(siteId).env.update('...') // Update .env
77
+ forge.server(id).site(siteId).nginx.get() // Get Nginx config
78
+ forge.server(id).site(siteId).nginx.update('...') // Update Nginx
79
+ ```
80
+
81
+ ### Deployments
82
+
83
+ ```typescript
84
+ forge.server(id).site(siteId).deployments.list(); // List deployments
85
+ forge.server(id).site(siteId).deployments.get(depId); // Get deployment
86
+ forge.server(id).site(siteId).deployments.output(depId); // Get output
87
+ forge.server(id).site(siteId).deployments.script(); // Get deploy script
88
+ forge.server(id).site(siteId).deployments.updateScript("npm run build");
89
+ ```
90
+
91
+ ### Certificates
92
+
93
+ ```typescript
94
+ forge.server(id).site(siteId).certificates.list();
95
+ forge.server(id).site(siteId).certificates.get(certId);
96
+ forge.server(id).site(siteId).certificates.create({ type: "new", domain: "example.com" });
97
+ forge.server(id).site(siteId).certificates.letsEncrypt(["example.com"]);
98
+ forge.server(id).site(siteId).certificates.activate(certId);
99
+ forge.server(id).site(siteId).certificates.delete(certId);
100
+ ```
101
+
102
+ ### Databases
103
+
104
+ ```typescript
105
+ forge.server(id).databases.list();
106
+ forge.server(id).databases.get(dbId);
107
+ forge.server(id).databases.create({ name: "myapp", user: "admin", password: "secret" });
108
+ forge.server(id).databases.delete(dbId);
109
+ ```
110
+
111
+ ### Daemons (Background Processes)
112
+
113
+ ```typescript
114
+ forge.server(id).daemons.list();
115
+ forge.server(id).daemons.get(daemonId);
116
+ forge.server(id).daemons.create({ command: "php artisan queue:work", user: "forge" });
117
+ forge.server(id).daemons.restart(daemonId);
118
+ forge.server(id).daemons.delete(daemonId);
119
+ ```
120
+
121
+ ### User
122
+
123
+ ```typescript
124
+ const user = await forge.user();
125
+ console.log(user.name, user.email);
126
+ ```
127
+
128
+ ## Comparison with PHP SDK
129
+
130
+ | Feature | PHP (`laravel/forge-sdk`) | TypeScript (`@studiometa/forge-sdk`) |
131
+ | --------------- | ------------------------- | ------------------------------------ |
132
+ | Language | PHP | TypeScript/JavaScript |
133
+ | API style | Method calls | Fluent chainable |
134
+ | Type safety | PHPDoc | Full TypeScript types |
135
+ | Node.js support | ❌ | ✅ Native |
136
+ | GitHub Actions | Via PHP setup | Native `npm install` |
137
+ | Rate limiting | Manual | Built-in (60 req/min) |
138
+ | Error types | Generic | Typed `ForgeApiError` |
139
+
140
+ ## Testing
141
+
142
+ The SDK supports dependency injection for testing:
143
+
144
+ ```typescript
145
+ const mockFetch = async (url, init) => {
146
+ return new Response(JSON.stringify({ servers: [] }), {
147
+ headers: { "content-type": "application/json" },
148
+ });
149
+ };
150
+
151
+ const forge = new Forge("test-token", { fetch: mockFetch });
152
+ const servers = await forge.servers.list(); // Uses mock fetch
153
+ ```
154
+
155
+ ## GitHub Actions Example
156
+
157
+ ```typescript
158
+ import { Forge } from "@studiometa/forge-sdk";
159
+
160
+ const forge = new Forge(process.env.FORGE_API_TOKEN);
161
+
162
+ // Deploy after successful CI
163
+ const sites = await forge.server(123).sites.list();
164
+ const site = sites.find((s) => s.name === "myapp.com");
165
+ if (site) {
166
+ await forge.server(123).site(site.id).deploy();
167
+ console.log("Deployment triggered!");
168
+ }
169
+ ```
170
+
171
+ ## Requirements
172
+
173
+ - **Node.js 18+** (uses native `fetch`)
174
+ - **Laravel Forge account** with API token
175
+
176
+ ## License
177
+
178
+ MIT © [Studio Meta](https://www.studiometa.fr)
@@ -0,0 +1,93 @@
1
+ import type { ForgeOptions, ForgeUser } from "@studiometa/forge-api";
2
+ import { HttpClient } from "@studiometa/forge-api";
3
+ import { ServersCollection, ServerResource } from "./resources/servers.ts";
4
+ import { RecipesCollection } from "./resources/recipes.ts";
5
+ /**
6
+ * Laravel Forge TypeScript SDK.
7
+ *
8
+ * Provides a fluent, chainable API for managing Laravel Forge servers,
9
+ * sites, deployments, and more.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import { Forge } from '@studiometa/forge-sdk';
14
+ *
15
+ * const forge = new Forge('your-api-token');
16
+ *
17
+ * // List all servers
18
+ * const servers = await forge.servers.list();
19
+ *
20
+ * // Deploy a site
21
+ * await forge.server(123).site(456).deploy();
22
+ *
23
+ * // Get environment variables
24
+ * const env = await forge.server(123).site(456).env.get();
25
+ *
26
+ * // Manage databases
27
+ * const dbs = await forge.server(123).databases.list();
28
+ * ```
29
+ */
30
+ export declare class Forge {
31
+ /** @internal */
32
+ readonly client: HttpClient;
33
+ /** Server operations (list, get, create, update, delete, reboot). */
34
+ readonly servers: ServersCollection;
35
+ /** Recipe operations (list, get, create, delete, run). */
36
+ readonly recipes: RecipesCollection;
37
+ /**
38
+ * Create a new Forge SDK instance.
39
+ *
40
+ * @param token Your Laravel Forge API token.
41
+ * @param options Optional configuration (custom fetch, base URL, rate limiting).
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * // Basic usage
46
+ * const forge = new Forge('your-api-token');
47
+ *
48
+ * // With custom options
49
+ * const forge = new Forge('your-api-token', {
50
+ * baseUrl: 'https://custom-forge-instance.com/api/v1',
51
+ * });
52
+ *
53
+ * // With mock fetch for testing
54
+ * const forge = new Forge('test-token', { fetch: mockFetch });
55
+ * ```
56
+ */
57
+ constructor(token: string, options?: ForgeOptions);
58
+ /**
59
+ * Access a specific server by ID, with nested resources.
60
+ *
61
+ * Returns a `ServerResource` that provides access to sites, databases,
62
+ * daemons, and other server-level resources.
63
+ *
64
+ * @param serverId The server ID.
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * // List sites on a server
69
+ * const sites = await forge.server(123).sites.list();
70
+ *
71
+ * // Access a specific site
72
+ * const site = await forge.server(123).site(456);
73
+ *
74
+ * // Deploy a site
75
+ * await forge.server(123).site(456).deploy();
76
+ *
77
+ * // Manage databases
78
+ * const dbs = await forge.server(123).databases.list();
79
+ * ```
80
+ */
81
+ server(serverId: number): ServerResource;
82
+ /**
83
+ * Get the currently authenticated user.
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * const user = await forge.user();
88
+ * console.log(user.name, user.email);
89
+ * ```
90
+ */
91
+ user(): Promise<ForgeUser>;
92
+ }
93
+ //# sourceMappingURL=forge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forge.d.ts","sourceRoot":"","sources":["../src/forge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAgB,MAAM,uBAAuB,CAAC;AAEnF,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,KAAK;IAChB,gBAAgB;IAChB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAE5B,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IAEpC,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IAEpC;;;;;;;;;;;;;;;;;;;OAmBG;gBACS,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;IAMjD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc;IAIxC;;;;;;;;OAQG;IACG,IAAI,IAAI,OAAO,CAAC,SAAS,CAAC;CAIjC"}
@@ -0,0 +1,40 @@
1
+ export { Forge } from "./forge.ts";
2
+ export { BaseCollection } from "./resources/base.ts";
3
+ export { AsyncPaginatedIterator } from "./pagination.ts";
4
+ export type { PageFetcher } from "./pagination.ts";
5
+ export { BackupsCollection } from "./resources/backups.ts";
6
+ export type { BackupConfigListOptions } from "./resources/backups.ts";
7
+ export { CertificatesCollection } from "./resources/certificates.ts";
8
+ export type { CertificateListOptions } from "./resources/certificates.ts";
9
+ export { CommandsCollection } from "./resources/commands.ts";
10
+ export type { CommandListOptions } from "./resources/commands.ts";
11
+ export { DaemonsCollection } from "./resources/daemons.ts";
12
+ export type { DaemonListOptions } from "./resources/daemons.ts";
13
+ export { DatabasesCollection } from "./resources/databases.ts";
14
+ export type { DatabaseListOptions } from "./resources/databases.ts";
15
+ export { DatabaseUsersCollection } from "./resources/database-users.ts";
16
+ export type { DatabaseUserListOptions } from "./resources/database-users.ts";
17
+ export { DeploymentsCollection } from "./resources/deployments.ts";
18
+ export type { DeploymentListOptions } from "./resources/deployments.ts";
19
+ export { FirewallRulesCollection } from "./resources/firewall-rules.ts";
20
+ export type { FirewallRuleListOptions } from "./resources/firewall-rules.ts";
21
+ export { MonitorsCollection } from "./resources/monitors.ts";
22
+ export type { MonitorListOptions } from "./resources/monitors.ts";
23
+ export { NginxTemplatesCollection } from "./resources/nginx-templates.ts";
24
+ export type { NginxTemplateListOptions } from "./resources/nginx-templates.ts";
25
+ export { RecipesCollection } from "./resources/recipes.ts";
26
+ export type { RecipeListOptions, RunRecipeOptions } from "./resources/recipes.ts";
27
+ export { RedirectRulesCollection } from "./resources/redirect-rules.ts";
28
+ export type { RedirectRuleListOptions } from "./resources/redirect-rules.ts";
29
+ export { ScheduledJobsCollection } from "./resources/scheduled-jobs.ts";
30
+ export type { ScheduledJobListOptions } from "./resources/scheduled-jobs.ts";
31
+ export { SecurityRulesCollection } from "./resources/security-rules.ts";
32
+ export type { SecurityRuleListOptions } from "./resources/security-rules.ts";
33
+ export { ServersCollection, ServerResource } from "./resources/servers.ts";
34
+ export type { ServerListOptions } from "./resources/servers.ts";
35
+ export { SshKeysCollection } from "./resources/ssh-keys.ts";
36
+ export type { SshKeyListOptions } from "./resources/ssh-keys.ts";
37
+ export { SiteEnvResource, SiteNginxResource, SiteResource, SitesCollection, } from "./resources/sites.ts";
38
+ export type { SiteListOptions } from "./resources/sites.ts";
39
+ export type { CreateBackupConfigData, CreateCertificateData, CreateCommandData, CreateDaemonData, CreateDatabaseData, CreateDatabaseUserData, CreateFirewallRuleData, CreateMonitorData, CreateNginxTemplateData, CreateRecipeData, CreateRedirectRuleData, CreateScheduledJobData, CreateSecurityRuleData, CreateServerData, CreateSiteData, CreateSshKeyData, ForgeBackup, ForgeBackupConfig, ForgeCertificate, ForgeCommand, ForgeDaemon, ForgeDatabase, ForgeDatabaseUser, ForgeDeployment, ForgeFirewallRule, ForgeMonitor, ForgeNginxTemplate, ForgeOptions, ForgeRecipe, ForgeRedirectRule, ForgeScheduledJob, ForgeSecurityRule, ForgeServer, ForgeSite, ForgeSshKey, ForgeUser, } from "@studiometa/forge-api";
40
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}