gigadrive 2.2.0 → 2.3.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.
- package/dist/index.cjs +745 -223
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +706 -184
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -24,15 +24,15 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// src/index.ts
|
|
27
|
-
var
|
|
27
|
+
var import_cli15 = require("@effect/cli");
|
|
28
28
|
var import_platform_node = require("@effect/platform-node");
|
|
29
29
|
var import_network_config2 = require("@gigadrive/network-config");
|
|
30
|
-
var
|
|
30
|
+
var import_effect29 = require("effect");
|
|
31
31
|
|
|
32
32
|
// package.json
|
|
33
33
|
var package_default = {
|
|
34
34
|
name: "gigadrive",
|
|
35
|
-
version: "2.
|
|
35
|
+
version: "2.3.0",
|
|
36
36
|
repository: {
|
|
37
37
|
type: "git",
|
|
38
38
|
url: "https://github.com/Gigadrive/sdk.git",
|
|
@@ -158,6 +158,31 @@ var ApplicationNotFoundError = class extends import_effect.Schema.TaggedError()(
|
|
|
158
158
|
}
|
|
159
159
|
) {
|
|
160
160
|
};
|
|
161
|
+
var EnvFileReadError = class extends import_effect.Schema.TaggedError()("EnvFileReadError", {
|
|
162
|
+
message: import_effect.Schema.String,
|
|
163
|
+
cause: import_effect.Schema.optional(import_effect.Schema.String)
|
|
164
|
+
}) {
|
|
165
|
+
};
|
|
166
|
+
var EnvFileWriteError = class extends import_effect.Schema.TaggedError()("EnvFileWriteError", {
|
|
167
|
+
message: import_effect.Schema.String,
|
|
168
|
+
cause: import_effect.Schema.optional(import_effect.Schema.String)
|
|
169
|
+
}) {
|
|
170
|
+
};
|
|
171
|
+
var DevCredentialsStoreReadError = class extends import_effect.Schema.TaggedError()(
|
|
172
|
+
"DevCredentialsStoreReadError",
|
|
173
|
+
{
|
|
174
|
+
message: import_effect.Schema.String
|
|
175
|
+
}
|
|
176
|
+
) {
|
|
177
|
+
};
|
|
178
|
+
var DevCredentialsStoreWriteError = class extends import_effect.Schema.TaggedError()(
|
|
179
|
+
"DevCredentialsStoreWriteError",
|
|
180
|
+
{
|
|
181
|
+
message: import_effect.Schema.String,
|
|
182
|
+
cause: import_effect.Schema.optional(import_effect.Schema.String)
|
|
183
|
+
}
|
|
184
|
+
) {
|
|
185
|
+
};
|
|
161
186
|
var ConfigNotFoundError = class extends import_effect.Schema.TaggedError()("ConfigNotFoundError", {
|
|
162
187
|
message: import_effect.Schema.String,
|
|
163
188
|
directory: import_effect.Schema.String
|
|
@@ -323,6 +348,10 @@ var ProjectLink = import_effect2.Schema.Struct({
|
|
|
323
348
|
applicationId: import_effect2.Schema.String,
|
|
324
349
|
organizationId: import_effect2.Schema.optional(import_effect2.Schema.String)
|
|
325
350
|
});
|
|
351
|
+
var DevKeyEntry = import_effect2.Schema.Struct({
|
|
352
|
+
apiKeyId: import_effect2.Schema.String
|
|
353
|
+
});
|
|
354
|
+
var DevKeyStore = import_effect2.Schema.Record({ key: import_effect2.Schema.String, value: DevKeyEntry });
|
|
326
355
|
|
|
327
356
|
// src/services/auth-storage.ts
|
|
328
357
|
var AuthStorageService = class extends import_effect3.Effect.Service()("AuthStorageService", {
|
|
@@ -403,7 +432,11 @@ var AuthStorageService = class extends import_effect3.Effect.Service()("AuthStor
|
|
|
403
432
|
var import_effect4 = require("effect");
|
|
404
433
|
var OAuthEnvConfig = import_effect4.Config.all({
|
|
405
434
|
issuerUrl: import_effect4.Config.string("GIGADRIVE_NETWORK_OAUTH_ISSUER_URL").pipe(import_effect4.Config.withDefault("https://idp.gigadrive.de")),
|
|
406
|
-
|
|
435
|
+
// Default is the first-party CLI's public OAuth client (seeded in the Network
|
|
436
|
+
// repo). Override with GIGADRIVE_NETWORK_OAUTH_CLIENT_ID per environment.
|
|
437
|
+
clientId: import_effect4.Config.string("GIGADRIVE_NETWORK_OAUTH_CLIENT_ID").pipe(
|
|
438
|
+
import_effect4.Config.withDefault("0195c11c-0000-7000-8000-000000000001")
|
|
439
|
+
)
|
|
407
440
|
});
|
|
408
441
|
var OpenIdDiscoveryDocument = import_effect4.Schema.Struct({
|
|
409
442
|
issuer: import_effect4.Schema.optional(import_effect4.Schema.String),
|
|
@@ -411,7 +444,33 @@ var OpenIdDiscoveryDocument = import_effect4.Schema.Struct({
|
|
|
411
444
|
token_endpoint: import_effect4.Schema.optional(import_effect4.Schema.String),
|
|
412
445
|
userinfo_endpoint: import_effect4.Schema.optional(import_effect4.Schema.String)
|
|
413
446
|
});
|
|
414
|
-
var
|
|
447
|
+
var CLI_SCOPES = [
|
|
448
|
+
// Identity / OIDC
|
|
449
|
+
"offline_access",
|
|
450
|
+
"openid",
|
|
451
|
+
"profile",
|
|
452
|
+
"email",
|
|
453
|
+
// Network API capabilities
|
|
454
|
+
"network:applications:read",
|
|
455
|
+
"network:env_vars:read",
|
|
456
|
+
"network:env_vars:write",
|
|
457
|
+
"network:env_vars:delete",
|
|
458
|
+
"network:deployments:read",
|
|
459
|
+
"network:deployments:write",
|
|
460
|
+
"network:deployments:trigger",
|
|
461
|
+
"network:ai_gateway:chat",
|
|
462
|
+
"network:ai_gateway:models",
|
|
463
|
+
"network:ai_gateway:usage:read",
|
|
464
|
+
"network:ai_gateway:budgets:read",
|
|
465
|
+
"network:ai_gateway:budgets:write",
|
|
466
|
+
"network:ai_gateway:policies:read",
|
|
467
|
+
"network:ai_gateway:policies:write",
|
|
468
|
+
// Provisioning local-dev API credentials
|
|
469
|
+
"platform:api_keys:read",
|
|
470
|
+
"platform:api_keys:write",
|
|
471
|
+
"platform:api_keys:delete"
|
|
472
|
+
];
|
|
473
|
+
var DEFAULT_SCOPE = CLI_SCOPES.join(" ");
|
|
415
474
|
var OAuthConfigService = class extends import_effect4.Effect.Service()("OAuthConfigService", {
|
|
416
475
|
accessors: true,
|
|
417
476
|
effect: import_effect4.Effect.gen(function* () {
|
|
@@ -1555,7 +1614,230 @@ var deploymentsCommand = deploymentsBase.pipe(
|
|
|
1555
1614
|
|
|
1556
1615
|
// src/commands/env/index.ts
|
|
1557
1616
|
var import_cli7 = require("@effect/cli");
|
|
1617
|
+
var import_effect19 = require("effect");
|
|
1618
|
+
|
|
1619
|
+
// src/services/env-file.ts
|
|
1620
|
+
var import_platform6 = require("@effect/platform");
|
|
1558
1621
|
var import_effect16 = require("effect");
|
|
1622
|
+
|
|
1623
|
+
// src/lib/dotenv.ts
|
|
1624
|
+
var DEFAULT_ENV_HEADER = "# Generated by `gigadrive env pull` \u2014 do not edit by hand.";
|
|
1625
|
+
var UNQUOTED_SAFE = /^[A-Za-z0-9_.\-/@:+]*$/;
|
|
1626
|
+
var formatEnvValue = (value) => {
|
|
1627
|
+
if (UNQUOTED_SAFE.test(value)) {
|
|
1628
|
+
return value;
|
|
1629
|
+
}
|
|
1630
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
|
|
1631
|
+
return `"${escaped}"`;
|
|
1632
|
+
};
|
|
1633
|
+
var serializeEnv = (entries, opts) => {
|
|
1634
|
+
const header = opts?.header ?? DEFAULT_ENV_HEADER;
|
|
1635
|
+
if (entries.length === 0) {
|
|
1636
|
+
return `${header}
|
|
1637
|
+
`;
|
|
1638
|
+
}
|
|
1639
|
+
const body = entries.map((e) => `${e.key}=${formatEnvValue(e.value)}`).join("\n");
|
|
1640
|
+
return `${header}
|
|
1641
|
+
${body}
|
|
1642
|
+
`;
|
|
1643
|
+
};
|
|
1644
|
+
var parseEnv = (content) => {
|
|
1645
|
+
const result = {};
|
|
1646
|
+
for (const rawLine of content.split("\n")) {
|
|
1647
|
+
const line = rawLine.trim();
|
|
1648
|
+
if (line.length === 0 || line.startsWith("#")) {
|
|
1649
|
+
continue;
|
|
1650
|
+
}
|
|
1651
|
+
const eq = line.indexOf("=");
|
|
1652
|
+
if (eq <= 0) {
|
|
1653
|
+
continue;
|
|
1654
|
+
}
|
|
1655
|
+
const key = line.slice(0, eq).trim();
|
|
1656
|
+
let value = line.slice(eq + 1).trim();
|
|
1657
|
+
if (value.length >= 2 && value.startsWith('"') && value.endsWith('"')) {
|
|
1658
|
+
value = value.slice(1, -1).replace(/\\(\\|"|n|r|t)/g, (_, ch) => {
|
|
1659
|
+
switch (ch) {
|
|
1660
|
+
case "n":
|
|
1661
|
+
return "\n";
|
|
1662
|
+
case "r":
|
|
1663
|
+
return "\r";
|
|
1664
|
+
case "t":
|
|
1665
|
+
return " ";
|
|
1666
|
+
case '"':
|
|
1667
|
+
return '"';
|
|
1668
|
+
default:
|
|
1669
|
+
return "\\";
|
|
1670
|
+
}
|
|
1671
|
+
});
|
|
1672
|
+
}
|
|
1673
|
+
result[key] = value;
|
|
1674
|
+
}
|
|
1675
|
+
return result;
|
|
1676
|
+
};
|
|
1677
|
+
|
|
1678
|
+
// src/services/env-file.ts
|
|
1679
|
+
var EnvFileService = class extends import_effect16.Effect.Service()("EnvFileService", {
|
|
1680
|
+
accessors: true,
|
|
1681
|
+
effect: import_effect16.Effect.gen(function* () {
|
|
1682
|
+
const fs = yield* import_platform6.FileSystem.FileSystem;
|
|
1683
|
+
const pathService = yield* import_platform6.Path.Path;
|
|
1684
|
+
const exists = import_effect16.Effect.fn("EnvFileService.exists")(function* (filePath) {
|
|
1685
|
+
return yield* fs.exists(filePath).pipe(import_effect16.Effect.mapError(() => new EnvFileReadError({ message: `Failed to check whether ${filePath} exists` })));
|
|
1686
|
+
});
|
|
1687
|
+
const read = import_effect16.Effect.fn("EnvFileService.read")(function* (filePath) {
|
|
1688
|
+
const present = yield* exists(filePath);
|
|
1689
|
+
if (!present) return import_effect16.Option.none();
|
|
1690
|
+
const contents = yield* fs.readFileString(filePath, "utf8").pipe(import_effect16.Effect.mapError(() => new EnvFileReadError({ message: `Failed to read ${filePath}` })));
|
|
1691
|
+
return import_effect16.Option.some(contents);
|
|
1692
|
+
});
|
|
1693
|
+
const write = import_effect16.Effect.fn("EnvFileService.write")(function* (filePath, entries, opts) {
|
|
1694
|
+
const dir = pathService.dirname(filePath);
|
|
1695
|
+
yield* fs.makeDirectory(dir, { recursive: true }).pipe(
|
|
1696
|
+
import_effect16.Effect.mapError(
|
|
1697
|
+
(error) => new EnvFileWriteError({ message: `Failed to create directory for ${filePath}`, cause: String(error) })
|
|
1698
|
+
)
|
|
1699
|
+
);
|
|
1700
|
+
yield* fs.writeFileString(filePath, serializeEnv(entries, opts), { mode: 384 }).pipe(
|
|
1701
|
+
import_effect16.Effect.mapError(
|
|
1702
|
+
(error) => new EnvFileWriteError({ message: `Failed to write ${filePath}`, cause: String(error) })
|
|
1703
|
+
)
|
|
1704
|
+
);
|
|
1705
|
+
yield* fs.chmod(filePath, 384).pipe(
|
|
1706
|
+
import_effect16.Effect.mapError(
|
|
1707
|
+
(error) => new EnvFileWriteError({ message: `Failed to secure ${filePath}`, cause: String(error) })
|
|
1708
|
+
)
|
|
1709
|
+
);
|
|
1710
|
+
});
|
|
1711
|
+
const ensureGitignored = import_effect16.Effect.fn("EnvFileService.ensureGitignored")(function* (dir, entry) {
|
|
1712
|
+
const gitignorePath = pathService.join(dir, ".gitignore");
|
|
1713
|
+
const existing = yield* read(gitignorePath);
|
|
1714
|
+
const current = import_effect16.Option.getOrElse(existing, () => "");
|
|
1715
|
+
const alreadyIgnored = current.split("\n").some((line) => line.trim() === entry);
|
|
1716
|
+
if (alreadyIgnored) {
|
|
1717
|
+
return false;
|
|
1718
|
+
}
|
|
1719
|
+
const separator = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
|
|
1720
|
+
yield* fs.writeFileString(gitignorePath, `${current}${separator}${entry}
|
|
1721
|
+
`).pipe(
|
|
1722
|
+
import_effect16.Effect.mapError(
|
|
1723
|
+
(error) => new EnvFileWriteError({ message: "Failed to update .gitignore", cause: String(error) })
|
|
1724
|
+
)
|
|
1725
|
+
);
|
|
1726
|
+
return true;
|
|
1727
|
+
});
|
|
1728
|
+
return { exists, read, write, ensureGitignored };
|
|
1729
|
+
})
|
|
1730
|
+
}) {
|
|
1731
|
+
};
|
|
1732
|
+
|
|
1733
|
+
// src/services/local-credentials.ts
|
|
1734
|
+
var import_effect18 = require("effect");
|
|
1735
|
+
var os3 = __toESM(require("os"), 1);
|
|
1736
|
+
|
|
1737
|
+
// src/services/dev-credentials-store.ts
|
|
1738
|
+
var import_platform7 = require("@effect/platform");
|
|
1739
|
+
var import_effect17 = require("effect");
|
|
1740
|
+
var os2 = __toESM(require("os"), 1);
|
|
1741
|
+
var DevCredentialsStore = class extends import_effect17.Effect.Service()("DevCredentialsStore", {
|
|
1742
|
+
accessors: true,
|
|
1743
|
+
effect: import_effect17.Effect.gen(function* () {
|
|
1744
|
+
const fs = yield* import_platform7.FileSystem.FileSystem;
|
|
1745
|
+
const pathService = yield* import_platform7.Path.Path;
|
|
1746
|
+
const homeDir = os2.homedir();
|
|
1747
|
+
const storeDir = pathService.join(homeDir, ".gigadrive");
|
|
1748
|
+
const storeFile = pathService.join(storeDir, "dev-keys.json");
|
|
1749
|
+
const ensureDirectory = import_effect17.Effect.gen(function* () {
|
|
1750
|
+
yield* fs.makeDirectory(storeDir, { recursive: true }).pipe(
|
|
1751
|
+
import_effect17.Effect.mapError(
|
|
1752
|
+
(error) => new DevCredentialsStoreWriteError({ message: "Failed to create ~/.gigadrive", cause: String(error) })
|
|
1753
|
+
)
|
|
1754
|
+
);
|
|
1755
|
+
yield* fs.chmod(storeDir, 448).pipe(
|
|
1756
|
+
import_effect17.Effect.mapError(
|
|
1757
|
+
(error) => new DevCredentialsStoreWriteError({
|
|
1758
|
+
message: "Failed to set ~/.gigadrive permissions",
|
|
1759
|
+
cause: String(error)
|
|
1760
|
+
})
|
|
1761
|
+
)
|
|
1762
|
+
);
|
|
1763
|
+
});
|
|
1764
|
+
const load = import_effect17.Effect.gen(function* () {
|
|
1765
|
+
const present = yield* fs.exists(storeFile).pipe(import_effect17.Effect.mapError(() => new DevCredentialsStoreReadError({ message: "Failed to check dev-keys.json" })));
|
|
1766
|
+
if (!present) return {};
|
|
1767
|
+
const data = yield* fs.readFileString(storeFile, "utf8").pipe(import_effect17.Effect.mapError(() => new DevCredentialsStoreReadError({ message: "Failed to read dev-keys.json" })));
|
|
1768
|
+
const json = yield* import_effect17.Effect.try({
|
|
1769
|
+
try: () => JSON.parse(data),
|
|
1770
|
+
catch: () => new DevCredentialsStoreReadError({ message: "dev-keys.json contains invalid JSON" })
|
|
1771
|
+
});
|
|
1772
|
+
return yield* import_effect17.Schema.decodeUnknown(DevKeyStore)(json).pipe(
|
|
1773
|
+
import_effect17.Effect.mapError(() => new DevCredentialsStoreReadError({ message: "dev-keys.json has an invalid schema" }))
|
|
1774
|
+
);
|
|
1775
|
+
});
|
|
1776
|
+
const get = import_effect17.Effect.fn("DevCredentialsStore.get")(function* (applicationId) {
|
|
1777
|
+
const store = yield* load;
|
|
1778
|
+
const entry = store[applicationId];
|
|
1779
|
+
return entry ? import_effect17.Option.some(entry) : import_effect17.Option.none();
|
|
1780
|
+
});
|
|
1781
|
+
const set = import_effect17.Effect.fn("DevCredentialsStore.set")(function* (applicationId, entry) {
|
|
1782
|
+
const store = yield* load;
|
|
1783
|
+
const next = { ...store, [applicationId]: entry };
|
|
1784
|
+
yield* ensureDirectory;
|
|
1785
|
+
yield* fs.writeFileString(storeFile, `${JSON.stringify(next, null, 2)}
|
|
1786
|
+
`, { mode: 384 }).pipe(
|
|
1787
|
+
import_effect17.Effect.mapError(
|
|
1788
|
+
(error) => new DevCredentialsStoreWriteError({ message: "Failed to write dev-keys.json", cause: String(error) })
|
|
1789
|
+
)
|
|
1790
|
+
);
|
|
1791
|
+
});
|
|
1792
|
+
return { get, set };
|
|
1793
|
+
})
|
|
1794
|
+
}) {
|
|
1795
|
+
};
|
|
1796
|
+
|
|
1797
|
+
// src/services/local-credentials.ts
|
|
1798
|
+
var DEV_KEY_SCOPES = ["network:env_vars:read"];
|
|
1799
|
+
var ApiBaseUrl2 = import_effect18.Config.string("GIGADRIVE_API_BASE_URL").pipe(import_effect18.Config.withDefault("https://api.gigadrive.network"));
|
|
1800
|
+
var credentialEntries = (clientId, clientSecret, baseUrl) => [
|
|
1801
|
+
{ key: "GIGADRIVE_CLIENT_ID", value: clientId },
|
|
1802
|
+
{ key: "GIGADRIVE_CLIENT_SECRET", value: clientSecret },
|
|
1803
|
+
{ key: "GIGADRIVE_API_BASE_URL", value: baseUrl }
|
|
1804
|
+
];
|
|
1805
|
+
var LocalCredentialsService = class extends import_effect18.Effect.Service()("LocalCredentialsService", {
|
|
1806
|
+
accessors: true,
|
|
1807
|
+
dependencies: [ApiClientService.Default, DevCredentialsStore.Default],
|
|
1808
|
+
effect: import_effect18.Effect.gen(function* () {
|
|
1809
|
+
const apiClient = yield* ApiClientService;
|
|
1810
|
+
const store = yield* DevCredentialsStore;
|
|
1811
|
+
const baseUrl = yield* ApiBaseUrl2;
|
|
1812
|
+
const keyName = (applicationId) => `cli-dev:${os3.hostname()}:${applicationId}`;
|
|
1813
|
+
const provision = import_effect18.Effect.fn("LocalCredentialsService.provision")(function* (input) {
|
|
1814
|
+
const stored = yield* store.get(input.applicationId);
|
|
1815
|
+
const existing = input.existingContent ? parseEnv(input.existingContent) : {};
|
|
1816
|
+
const existingClientId = existing["GIGADRIVE_CLIENT_ID"];
|
|
1817
|
+
const existingClientSecret = existing["GIGADRIVE_CLIENT_SECRET"];
|
|
1818
|
+
const canReuse = !input.rotate && existingClientId !== void 0 && existingClientSecret !== void 0 && import_effect18.Option.isSome(stored) && stored.value.apiKeyId === existingClientId;
|
|
1819
|
+
if (canReuse) {
|
|
1820
|
+
return credentialEntries(existingClientId, existingClientSecret, baseUrl);
|
|
1821
|
+
}
|
|
1822
|
+
if (import_effect18.Option.isSome(stored)) {
|
|
1823
|
+
yield* apiClient.request((client) => client.apiKeys.delete(stored.value.apiKeyId)).pipe(import_effect18.Effect.catchTag("ApiRequestError", () => import_effect18.Effect.void));
|
|
1824
|
+
}
|
|
1825
|
+
const created = yield* apiClient.request(
|
|
1826
|
+
(client) => client.apiKeys.create({
|
|
1827
|
+
name: keyName(input.applicationId),
|
|
1828
|
+
applicationId: input.applicationId,
|
|
1829
|
+
scopes: DEV_KEY_SCOPES
|
|
1830
|
+
})
|
|
1831
|
+
);
|
|
1832
|
+
yield* store.set(input.applicationId, { apiKeyId: created.id });
|
|
1833
|
+
return credentialEntries(created.id, created.secret, baseUrl);
|
|
1834
|
+
});
|
|
1835
|
+
return { provision };
|
|
1836
|
+
})
|
|
1837
|
+
}) {
|
|
1838
|
+
};
|
|
1839
|
+
|
|
1840
|
+
// src/commands/env/index.ts
|
|
1559
1841
|
var appOption3 = import_cli7.Options.text("app").pipe(
|
|
1560
1842
|
import_cli7.Options.withAlias("a"),
|
|
1561
1843
|
import_cli7.Options.withDescription("Operate on this application (overrides the linked application)"),
|
|
@@ -1578,51 +1860,70 @@ var keyValueArg = import_cli7.Args.text({ name: "key=value" }).pipe(
|
|
|
1578
1860
|
import_cli7.Args.withDescription("Variable assignment, e.g. DATABASE_URL=postgres://user:pass@host/db")
|
|
1579
1861
|
);
|
|
1580
1862
|
var keyOrIdArg = import_cli7.Args.text({ name: "key-or-id" }).pipe(import_cli7.Args.withDescription("Variable key or ID to remove"));
|
|
1581
|
-
var
|
|
1582
|
-
|
|
1863
|
+
var fileArg = import_cli7.Args.text({ name: "file" }).pipe(
|
|
1864
|
+
import_cli7.Args.withDescription("Output file to write (default: .env.local)"),
|
|
1865
|
+
import_cli7.Args.optional
|
|
1866
|
+
);
|
|
1867
|
+
var environmentOption = import_cli7.Options.text("environment").pipe(
|
|
1868
|
+
import_cli7.Options.withAlias("e"),
|
|
1869
|
+
import_cli7.Options.withDescription("Environment slug to resolve overrides for (e.g. preview). Omit for the local baseline"),
|
|
1870
|
+
import_cli7.Options.optional
|
|
1871
|
+
);
|
|
1872
|
+
var yesOption = import_cli7.Options.boolean("yes").pipe(
|
|
1873
|
+
import_cli7.Options.withAlias("y"),
|
|
1874
|
+
import_cli7.Options.withDescription("Overwrite an existing file without confirmation")
|
|
1875
|
+
);
|
|
1876
|
+
var withCredentialsOption = import_cli7.Options.boolean("with-credentials").pipe(
|
|
1877
|
+
import_cli7.Options.withDescription("Also provision API-key credentials so the local app can call the API as this application")
|
|
1878
|
+
);
|
|
1879
|
+
var rotateOption = import_cli7.Options.boolean("rotate").pipe(
|
|
1880
|
+
import_cli7.Options.withDescription("Force a fresh API key when provisioning credentials, revoking the previous one")
|
|
1881
|
+
);
|
|
1882
|
+
var resolveScope = (app, org) => import_effect19.Effect.gen(function* () {
|
|
1883
|
+
if (import_effect19.Option.isSome(org)) {
|
|
1583
1884
|
return { kind: "organization", id: org.value };
|
|
1584
1885
|
}
|
|
1585
1886
|
const projectLink = yield* ProjectLinkService;
|
|
1586
|
-
const id = yield*
|
|
1587
|
-
onSome: (value) =>
|
|
1588
|
-
onNone: () => projectLink.resolve(process.cwd()).pipe(
|
|
1887
|
+
const id = yield* import_effect19.Option.match(app, {
|
|
1888
|
+
onSome: (value) => import_effect19.Effect.succeed(value),
|
|
1889
|
+
onNone: () => projectLink.resolve(process.cwd()).pipe(import_effect19.Effect.map((link) => link.applicationId))
|
|
1589
1890
|
});
|
|
1590
1891
|
return { kind: "application", id };
|
|
1591
1892
|
});
|
|
1592
1893
|
var envListCommand = import_cli7.Command.make(
|
|
1593
1894
|
"list",
|
|
1594
1895
|
{ app: appOption3, org: orgOption4 },
|
|
1595
|
-
({ app, org }) =>
|
|
1896
|
+
({ app, org }) => import_effect19.Effect.gen(function* () {
|
|
1596
1897
|
const apiClient = yield* ApiClientService;
|
|
1597
1898
|
const scope = yield* resolveScope(app, org);
|
|
1598
1899
|
const { items } = yield* apiClient.request(
|
|
1599
1900
|
(client) => scope.kind === "organization" ? client.organizations.envVars.list(scope.id) : client.applications.envVars.list(scope.id)
|
|
1600
1901
|
);
|
|
1601
1902
|
if (items.length === 0) {
|
|
1602
|
-
yield*
|
|
1903
|
+
yield* import_effect19.Console.log("No environment variables set.");
|
|
1603
1904
|
return;
|
|
1604
1905
|
}
|
|
1605
1906
|
for (const v of items) {
|
|
1606
|
-
yield*
|
|
1907
|
+
yield* import_effect19.Console.log(`${v.key}=${v.sensitive ? "***" : v.value ?? ""}`);
|
|
1607
1908
|
}
|
|
1608
1909
|
}).pipe(
|
|
1609
|
-
|
|
1610
|
-
NotAuthenticatedError: (err) =>
|
|
1611
|
-
|
|
1910
|
+
import_effect19.Effect.catchTags({
|
|
1911
|
+
NotAuthenticatedError: (err) => import_effect19.Console.error('You are not logged in. Run "gigadrive login" to authenticate.').pipe(
|
|
1912
|
+
import_effect19.Effect.andThen(import_effect19.Effect.fail(err))
|
|
1612
1913
|
),
|
|
1613
|
-
ApiRequestError: (err) =>
|
|
1614
|
-
ProjectNotLinkedError: (err) =>
|
|
1615
|
-
ProjectLinkReadError: (err) =>
|
|
1914
|
+
ApiRequestError: (err) => import_effect19.Console.error(`Failed to list environment variables: ${err.message}`).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err))),
|
|
1915
|
+
ProjectNotLinkedError: (err) => import_effect19.Console.error(err.message).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err))),
|
|
1916
|
+
ProjectLinkReadError: (err) => import_effect19.Console.error(err.message).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err)))
|
|
1616
1917
|
})
|
|
1617
1918
|
)
|
|
1618
1919
|
);
|
|
1619
1920
|
var envSetCommand = import_cli7.Command.make(
|
|
1620
1921
|
"set",
|
|
1621
1922
|
{ keyValue: keyValueArg, app: appOption3, org: orgOption4, sensitive: sensitiveOption, env: envIdOption },
|
|
1622
|
-
({ keyValue, app, org, sensitive, env }) =>
|
|
1923
|
+
({ keyValue, app, org, sensitive, env }) => import_effect19.Effect.gen(function* () {
|
|
1623
1924
|
const separator = keyValue.indexOf("=");
|
|
1624
1925
|
if (separator <= 0) {
|
|
1625
|
-
return yield*
|
|
1926
|
+
return yield* import_effect19.Effect.fail(
|
|
1626
1927
|
new InvalidEnvVarFormatError({
|
|
1627
1928
|
message: 'Invalid format. Use KEY=VALUE, e.g. "gigadrive env set DATABASE_URL=postgres://...".'
|
|
1628
1929
|
})
|
|
@@ -1632,27 +1933,27 @@ var envSetCommand = import_cli7.Command.make(
|
|
|
1632
1933
|
const value = keyValue.slice(separator + 1);
|
|
1633
1934
|
const apiClient = yield* ApiClientService;
|
|
1634
1935
|
const scope = yield* resolveScope(app, org);
|
|
1635
|
-
const environmentId =
|
|
1936
|
+
const environmentId = import_effect19.Option.getOrUndefined(env);
|
|
1636
1937
|
const created = yield* apiClient.request(
|
|
1637
1938
|
(client) => scope.kind === "organization" ? client.organizations.envVars.create(scope.id, { key, value, sensitive }) : client.applications.envVars.create(scope.id, { key, value, sensitive, environmentId })
|
|
1638
1939
|
);
|
|
1639
|
-
yield*
|
|
1940
|
+
yield* import_effect19.Console.log(`Set ${created.key}.`);
|
|
1640
1941
|
}).pipe(
|
|
1641
|
-
|
|
1642
|
-
InvalidEnvVarFormatError: (err) =>
|
|
1643
|
-
NotAuthenticatedError: (err) =>
|
|
1644
|
-
|
|
1942
|
+
import_effect19.Effect.catchTags({
|
|
1943
|
+
InvalidEnvVarFormatError: (err) => import_effect19.Console.error(err.message).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err))),
|
|
1944
|
+
NotAuthenticatedError: (err) => import_effect19.Console.error('You are not logged in. Run "gigadrive login" to authenticate.').pipe(
|
|
1945
|
+
import_effect19.Effect.andThen(import_effect19.Effect.fail(err))
|
|
1645
1946
|
),
|
|
1646
|
-
ApiRequestError: (err) =>
|
|
1647
|
-
ProjectNotLinkedError: (err) =>
|
|
1648
|
-
ProjectLinkReadError: (err) =>
|
|
1947
|
+
ApiRequestError: (err) => import_effect19.Console.error(`Failed to set environment variable: ${err.message}`).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err))),
|
|
1948
|
+
ProjectNotLinkedError: (err) => import_effect19.Console.error(err.message).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err))),
|
|
1949
|
+
ProjectLinkReadError: (err) => import_effect19.Console.error(err.message).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err)))
|
|
1649
1950
|
})
|
|
1650
1951
|
)
|
|
1651
1952
|
);
|
|
1652
1953
|
var envRmCommand = import_cli7.Command.make(
|
|
1653
1954
|
"rm",
|
|
1654
1955
|
{ keyOrId: keyOrIdArg, app: appOption3, org: orgOption4 },
|
|
1655
|
-
({ keyOrId, app, org }) =>
|
|
1956
|
+
({ keyOrId, app, org }) => import_effect19.Effect.gen(function* () {
|
|
1656
1957
|
const apiClient = yield* ApiClientService;
|
|
1657
1958
|
const scope = yield* resolveScope(app, org);
|
|
1658
1959
|
const { items } = yield* apiClient.request(
|
|
@@ -1660,32 +1961,106 @@ var envRmCommand = import_cli7.Command.make(
|
|
|
1660
1961
|
);
|
|
1661
1962
|
const target = items.find((v) => v.id === keyOrId || v.key === keyOrId);
|
|
1662
1963
|
if (target === void 0) {
|
|
1663
|
-
return yield*
|
|
1964
|
+
return yield* import_effect19.Effect.fail(
|
|
1664
1965
|
new EnvVarNotFoundError({ message: `No environment variable matching "${keyOrId}".` })
|
|
1665
1966
|
);
|
|
1666
1967
|
}
|
|
1667
1968
|
yield* apiClient.request(
|
|
1668
1969
|
(client) => scope.kind === "organization" ? client.organizations.envVars.delete(scope.id, target.id) : client.applications.envVars.delete(scope.id, target.id)
|
|
1669
1970
|
);
|
|
1670
|
-
yield*
|
|
1971
|
+
yield* import_effect19.Console.log(`Removed ${target.key}.`);
|
|
1972
|
+
}).pipe(
|
|
1973
|
+
import_effect19.Effect.catchTags({
|
|
1974
|
+
EnvVarNotFoundError: (err) => import_effect19.Console.error(err.message).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err))),
|
|
1975
|
+
NotAuthenticatedError: (err) => import_effect19.Console.error('You are not logged in. Run "gigadrive login" to authenticate.').pipe(
|
|
1976
|
+
import_effect19.Effect.andThen(import_effect19.Effect.fail(err))
|
|
1977
|
+
),
|
|
1978
|
+
ApiRequestError: (err) => import_effect19.Console.error(`Failed to remove environment variable: ${err.message}`).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err))),
|
|
1979
|
+
ProjectNotLinkedError: (err) => import_effect19.Console.error(err.message).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err))),
|
|
1980
|
+
ProjectLinkReadError: (err) => import_effect19.Console.error(err.message).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err)))
|
|
1981
|
+
})
|
|
1982
|
+
)
|
|
1983
|
+
);
|
|
1984
|
+
var envPullCommand = import_cli7.Command.make(
|
|
1985
|
+
"pull",
|
|
1986
|
+
{
|
|
1987
|
+
file: fileArg,
|
|
1988
|
+
app: appOption3,
|
|
1989
|
+
environment: environmentOption,
|
|
1990
|
+
yes: yesOption,
|
|
1991
|
+
withCredentials: withCredentialsOption,
|
|
1992
|
+
rotate: rotateOption
|
|
1993
|
+
},
|
|
1994
|
+
({ file, app, environment, yes, withCredentials, rotate }) => import_effect19.Effect.gen(function* () {
|
|
1995
|
+
const apiClient = yield* ApiClientService;
|
|
1996
|
+
const projectLink = yield* ProjectLinkService;
|
|
1997
|
+
const envFile = yield* EnvFileService;
|
|
1998
|
+
const applicationId = yield* import_effect19.Option.match(app, {
|
|
1999
|
+
onSome: (value) => import_effect19.Effect.succeed(value),
|
|
2000
|
+
onNone: () => projectLink.resolve(process.cwd()).pipe(import_effect19.Effect.map((link) => link.applicationId))
|
|
2001
|
+
});
|
|
2002
|
+
const target = import_effect19.Option.getOrElse(file, () => ".env.local");
|
|
2003
|
+
const environmentSlug = import_effect19.Option.getOrUndefined(environment);
|
|
2004
|
+
const { items, omittedSensitive } = yield* apiClient.request(
|
|
2005
|
+
(client) => client.applications.envVars.pull(applicationId, environmentSlug ? { environment: environmentSlug } : void 0)
|
|
2006
|
+
);
|
|
2007
|
+
const existing = yield* envFile.read(target);
|
|
2008
|
+
if (import_effect19.Option.isSome(existing) && !yes) {
|
|
2009
|
+
const overwrite = yield* import_cli7.Prompt.run(
|
|
2010
|
+
import_cli7.Prompt.confirm({ message: `${target} already exists. Overwrite?`, initial: false })
|
|
2011
|
+
);
|
|
2012
|
+
if (!overwrite) {
|
|
2013
|
+
return yield* import_effect19.Console.log("Cancelled.");
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
let credentialEntries2 = [];
|
|
2017
|
+
if (withCredentials) {
|
|
2018
|
+
const localCredentials = yield* LocalCredentialsService;
|
|
2019
|
+
credentialEntries2 = yield* localCredentials.provision({
|
|
2020
|
+
applicationId,
|
|
2021
|
+
rotate,
|
|
2022
|
+
existingContent: import_effect19.Option.getOrUndefined(existing)
|
|
2023
|
+
});
|
|
2024
|
+
}
|
|
2025
|
+
const entries = [...items.map((v) => ({ key: v.key, value: v.value })), ...credentialEntries2];
|
|
2026
|
+
yield* envFile.write(target, entries);
|
|
2027
|
+
const gitignored = yield* envFile.ensureGitignored(process.cwd(), target);
|
|
2028
|
+
yield* import_effect19.Console.log(
|
|
2029
|
+
`Pulled ${items.length} environment variable(s)${withCredentials ? " and API credentials" : ""} to ${target}.`
|
|
2030
|
+
);
|
|
2031
|
+
if (omittedSensitive > 0) {
|
|
2032
|
+
yield* import_effect19.Console.log(
|
|
2033
|
+
`Skipped ${omittedSensitive} sensitive variable(s); secrets live only in production/preview environments.`
|
|
2034
|
+
);
|
|
2035
|
+
}
|
|
2036
|
+
if (gitignored) {
|
|
2037
|
+
yield* import_effect19.Console.log(`Added ${target} to .gitignore.`);
|
|
2038
|
+
}
|
|
1671
2039
|
}).pipe(
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
2040
|
+
import_effect19.Effect.catchTags({
|
|
2041
|
+
// Ctrl+C during the overwrite prompt is a deliberate cancel — exit 0.
|
|
2042
|
+
QuitException: () => import_effect19.Console.log("Cancelled."),
|
|
2043
|
+
NotAuthenticatedError: (err) => import_effect19.Console.error('You are not logged in. Run "gigadrive login" to authenticate.').pipe(
|
|
2044
|
+
import_effect19.Effect.andThen(import_effect19.Effect.fail(err))
|
|
1676
2045
|
),
|
|
1677
|
-
ApiRequestError: (err) =>
|
|
1678
|
-
ProjectNotLinkedError: (err) =>
|
|
1679
|
-
ProjectLinkReadError: (err) =>
|
|
2046
|
+
ApiRequestError: (err) => import_effect19.Console.error(`Failed to pull environment variables: ${err.message}`).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err))),
|
|
2047
|
+
ProjectNotLinkedError: (err) => import_effect19.Console.error(err.message).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err))),
|
|
2048
|
+
ProjectLinkReadError: (err) => import_effect19.Console.error(err.message).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err))),
|
|
2049
|
+
EnvFileReadError: (err) => import_effect19.Console.error(err.message).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err))),
|
|
2050
|
+
EnvFileWriteError: (err) => import_effect19.Console.error(err.message).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err))),
|
|
2051
|
+
DevCredentialsStoreReadError: (err) => import_effect19.Console.error(err.message).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err))),
|
|
2052
|
+
DevCredentialsStoreWriteError: (err) => import_effect19.Console.error(err.message).pipe(import_effect19.Effect.andThen(import_effect19.Effect.fail(err)))
|
|
1680
2053
|
})
|
|
1681
2054
|
)
|
|
1682
2055
|
);
|
|
1683
|
-
var envBase = import_cli7.Command.make("env", {}, () =>
|
|
1684
|
-
var envCommand = envBase.pipe(
|
|
2056
|
+
var envBase = import_cli7.Command.make("env", {}, () => import_effect19.Effect.void);
|
|
2057
|
+
var envCommand = envBase.pipe(
|
|
2058
|
+
import_cli7.Command.withSubcommands([envListCommand, envSetCommand, envRmCommand, envPullCommand])
|
|
2059
|
+
);
|
|
1685
2060
|
|
|
1686
2061
|
// src/commands/link/index.ts
|
|
1687
2062
|
var import_cli8 = require("@effect/cli");
|
|
1688
|
-
var
|
|
2063
|
+
var import_effect20 = require("effect");
|
|
1689
2064
|
var appOption4 = import_cli8.Options.text("app").pipe(
|
|
1690
2065
|
import_cli8.Options.withAlias("a"),
|
|
1691
2066
|
import_cli8.Options.withDescription("Application ID to link (skips the interactive picker)"),
|
|
@@ -1699,26 +2074,26 @@ var orgOption5 = import_cli8.Options.text("org").pipe(
|
|
|
1699
2074
|
var linkCommand = import_cli8.Command.make(
|
|
1700
2075
|
"link",
|
|
1701
2076
|
{ app: appOption4, org: orgOption5 },
|
|
1702
|
-
({ app, org }) =>
|
|
2077
|
+
({ app, org }) => import_effect20.Effect.gen(function* () {
|
|
1703
2078
|
const apiClient = yield* ApiClientService;
|
|
1704
2079
|
const projectLink = yield* ProjectLinkService;
|
|
1705
2080
|
const cwd = process.cwd();
|
|
1706
|
-
const organizationId =
|
|
2081
|
+
const organizationId = import_effect20.Option.getOrUndefined(org);
|
|
1707
2082
|
const { items: apps } = yield* apiClient.request((client) => client.applications.list({ organizationId }));
|
|
1708
2083
|
if (apps.length === 0) {
|
|
1709
|
-
return yield*
|
|
2084
|
+
return yield* import_effect20.Effect.fail(
|
|
1710
2085
|
new NoApplicationsFoundError({
|
|
1711
2086
|
message: 'No applications found. Create one in the Gigadrive console, then run "gigadrive link" again.'
|
|
1712
2087
|
})
|
|
1713
2088
|
);
|
|
1714
2089
|
}
|
|
1715
|
-
const explicitAppId =
|
|
2090
|
+
const explicitAppId = import_effect20.Option.getOrUndefined(app);
|
|
1716
2091
|
let applicationId;
|
|
1717
2092
|
let linkedOrganizationId;
|
|
1718
2093
|
if (explicitAppId !== void 0) {
|
|
1719
2094
|
const match = apps.find((a) => a.id === explicitAppId);
|
|
1720
2095
|
if (match === void 0) {
|
|
1721
|
-
return yield*
|
|
2096
|
+
return yield* import_effect20.Effect.fail(
|
|
1722
2097
|
new ApplicationNotFoundError({
|
|
1723
2098
|
message: `Application "${explicitAppId}" was not found among your applications.`
|
|
1724
2099
|
})
|
|
@@ -1740,106 +2115,106 @@ var linkCommand = import_cli8.Command.make(
|
|
|
1740
2115
|
linkedOrganizationId = chosen.organization.id;
|
|
1741
2116
|
}
|
|
1742
2117
|
yield* projectLink.save(cwd, { applicationId, organizationId: linkedOrganizationId });
|
|
1743
|
-
yield*
|
|
1744
|
-
yield*
|
|
2118
|
+
yield* import_effect20.Console.log(`Linked this directory to application ${applicationId}.`);
|
|
2119
|
+
yield* import_effect20.Console.log('Tip: add ".gigadrive/" to your .gitignore.');
|
|
1745
2120
|
}).pipe(
|
|
1746
|
-
|
|
2121
|
+
import_effect20.Effect.catchTags({
|
|
1747
2122
|
// Ctrl+C during the picker is a deliberate cancel — exit 0.
|
|
1748
|
-
QuitException: () =>
|
|
1749
|
-
NotAuthenticatedError: (err) =>
|
|
1750
|
-
|
|
2123
|
+
QuitException: () => import_effect20.Console.log("Cancelled."),
|
|
2124
|
+
NotAuthenticatedError: (err) => import_effect20.Console.error('You are not logged in. Run "gigadrive login" to authenticate.').pipe(
|
|
2125
|
+
import_effect20.Effect.andThen(import_effect20.Effect.fail(err))
|
|
1751
2126
|
),
|
|
1752
|
-
ApiRequestError: (err) =>
|
|
1753
|
-
NoApplicationsFoundError: (err) =>
|
|
1754
|
-
ApplicationNotFoundError: (err) =>
|
|
1755
|
-
ProjectLinkWriteError: (err) =>
|
|
2127
|
+
ApiRequestError: (err) => import_effect20.Console.error(`Failed to list applications: ${err.message}`).pipe(import_effect20.Effect.andThen(import_effect20.Effect.fail(err))),
|
|
2128
|
+
NoApplicationsFoundError: (err) => import_effect20.Console.error(err.message).pipe(import_effect20.Effect.andThen(import_effect20.Effect.fail(err))),
|
|
2129
|
+
ApplicationNotFoundError: (err) => import_effect20.Console.error(err.message).pipe(import_effect20.Effect.andThen(import_effect20.Effect.fail(err))),
|
|
2130
|
+
ProjectLinkWriteError: (err) => import_effect20.Console.error(err.message).pipe(import_effect20.Effect.andThen(import_effect20.Effect.fail(err)))
|
|
1756
2131
|
})
|
|
1757
2132
|
)
|
|
1758
2133
|
);
|
|
1759
2134
|
var unlinkCommand = import_cli8.Command.make(
|
|
1760
2135
|
"unlink",
|
|
1761
2136
|
{},
|
|
1762
|
-
() =>
|
|
2137
|
+
() => import_effect20.Effect.gen(function* () {
|
|
1763
2138
|
const projectLink = yield* ProjectLinkService;
|
|
1764
2139
|
yield* projectLink.remove(process.cwd());
|
|
1765
|
-
yield*
|
|
2140
|
+
yield* import_effect20.Console.log("Unlinked this directory.");
|
|
1766
2141
|
}).pipe(
|
|
1767
|
-
|
|
1768
|
-
ProjectLinkWriteError: (err) =>
|
|
2142
|
+
import_effect20.Effect.catchTags({
|
|
2143
|
+
ProjectLinkWriteError: (err) => import_effect20.Console.error(err.message).pipe(import_effect20.Effect.andThen(import_effect20.Effect.fail(err)))
|
|
1769
2144
|
})
|
|
1770
2145
|
)
|
|
1771
2146
|
);
|
|
1772
2147
|
|
|
1773
2148
|
// src/commands/login/index.ts
|
|
1774
2149
|
var import_cli9 = require("@effect/cli");
|
|
1775
|
-
var
|
|
2150
|
+
var import_effect21 = require("effect");
|
|
1776
2151
|
var loginCommand = import_cli9.Command.make(
|
|
1777
2152
|
"login",
|
|
1778
2153
|
{},
|
|
1779
|
-
() =>
|
|
1780
|
-
yield*
|
|
2154
|
+
() => import_effect21.Effect.gen(function* () {
|
|
2155
|
+
yield* import_effect21.Console.log("Initiating login...");
|
|
1781
2156
|
const auth = yield* AuthService;
|
|
1782
2157
|
yield* auth.login;
|
|
1783
|
-
const info = yield* auth.getUserInfo.pipe(
|
|
2158
|
+
const info = yield* auth.getUserInfo.pipe(import_effect21.Effect.catchAll(() => import_effect21.Effect.succeed({})));
|
|
1784
2159
|
const name = auth.inferUserName(info);
|
|
1785
|
-
yield*
|
|
2160
|
+
yield* import_effect21.Console.log(`You are now logged in as ${name}.`);
|
|
1786
2161
|
}).pipe(
|
|
1787
|
-
|
|
1788
|
-
LoginFlowError: (err) =>
|
|
1789
|
-
TokenExchangeError: (err) =>
|
|
1790
|
-
OAuthDiscoveryError: (err) =>
|
|
1791
|
-
AuthStorageWriteError: (err) =>
|
|
2162
|
+
import_effect21.Effect.catchTags({
|
|
2163
|
+
LoginFlowError: (err) => import_effect21.Console.error(`Login failed: ${err.message}`),
|
|
2164
|
+
TokenExchangeError: (err) => import_effect21.Console.error(`Login failed: ${err.message}`),
|
|
2165
|
+
OAuthDiscoveryError: (err) => import_effect21.Console.error(`Login failed: ${err.message}`),
|
|
2166
|
+
AuthStorageWriteError: (err) => import_effect21.Console.error(`Failed to save credentials: ${err.message}`)
|
|
1792
2167
|
})
|
|
1793
2168
|
)
|
|
1794
2169
|
);
|
|
1795
2170
|
|
|
1796
2171
|
// src/commands/logout/index.ts
|
|
1797
2172
|
var import_cli10 = require("@effect/cli");
|
|
1798
|
-
var
|
|
2173
|
+
var import_effect22 = require("effect");
|
|
1799
2174
|
var logoutCommand = import_cli10.Command.make(
|
|
1800
2175
|
"logout",
|
|
1801
2176
|
{},
|
|
1802
|
-
() =>
|
|
2177
|
+
() => import_effect22.Effect.gen(function* () {
|
|
1803
2178
|
const auth = yield* AuthService;
|
|
1804
2179
|
yield* auth.logout;
|
|
1805
|
-
yield*
|
|
2180
|
+
yield* import_effect22.Console.log("Logged out.");
|
|
1806
2181
|
}).pipe(
|
|
1807
|
-
|
|
1808
|
-
AuthStorageWriteError: (err) =>
|
|
2182
|
+
import_effect22.Effect.catchTags({
|
|
2183
|
+
AuthStorageWriteError: (err) => import_effect22.Console.error(`Failed to log out: ${err.message}`).pipe(import_effect22.Effect.andThen(import_effect22.Effect.fail(err)))
|
|
1809
2184
|
})
|
|
1810
2185
|
)
|
|
1811
2186
|
);
|
|
1812
2187
|
|
|
1813
2188
|
// src/commands/platform/index.ts
|
|
1814
2189
|
var import_cli12 = require("@effect/cli");
|
|
1815
|
-
var
|
|
2190
|
+
var import_effect26 = require("effect");
|
|
1816
2191
|
|
|
1817
2192
|
// src/commands/platform/deploy/index.ts
|
|
1818
2193
|
var import_cli11 = require("@effect/cli");
|
|
1819
|
-
var
|
|
2194
|
+
var import_platform9 = require("@effect/platform");
|
|
1820
2195
|
var import_commons = require("@gigadrive/commons");
|
|
1821
|
-
var
|
|
1822
|
-
var
|
|
2196
|
+
var import_effect25 = require("effect");
|
|
2197
|
+
var os4 = __toESM(require("os"), 1);
|
|
1823
2198
|
|
|
1824
2199
|
// src/services/archive.ts
|
|
1825
|
-
var
|
|
2200
|
+
var import_platform8 = require("@effect/platform");
|
|
1826
2201
|
var import_build_utils3 = require("@gigadrive/build-utils");
|
|
1827
2202
|
var import_archiver = __toESM(require("archiver"), 1);
|
|
1828
|
-
var
|
|
2203
|
+
var import_effect23 = require("effect");
|
|
1829
2204
|
var import_ignore = __toESM(require("ignore"), 1);
|
|
1830
2205
|
var nodeFs = __toESM(require("fs"), 1);
|
|
1831
2206
|
var nodeFsPromises = __toESM(require("fs/promises"), 1);
|
|
1832
2207
|
var IGNORE_FILE_NAMES = [".gigadriveignore", ".vercelignore", ".dockerignore", ".nowignore"];
|
|
1833
2208
|
var readIgnoreFile = (fs, ignorePath) => fs.readFileString(ignorePath, "utf8").pipe(
|
|
1834
|
-
|
|
1835
|
-
|
|
2209
|
+
import_effect23.Effect.map((content) => content.split("\n").filter((line) => line.trim() !== "")),
|
|
2210
|
+
import_effect23.Effect.catchAll(() => import_effect23.Effect.succeed([]))
|
|
1836
2211
|
);
|
|
1837
|
-
var collectIgnorePatterns = (fs, pathService, dir, baseDir, ignoreRules) =>
|
|
1838
|
-
const items = yield* fs.readDirectory(dir).pipe(
|
|
2212
|
+
var collectIgnorePatterns = (fs, pathService, dir, baseDir, ignoreRules) => import_effect23.Effect.gen(function* () {
|
|
2213
|
+
const items = yield* fs.readDirectory(dir).pipe(import_effect23.Effect.mapError(() => new ArchiveCreateError({ message: `Failed to read directory: ${dir}` })));
|
|
1839
2214
|
for (const item of items) {
|
|
1840
2215
|
const fullPath = pathService.join(dir, item);
|
|
1841
2216
|
const relativePath = pathService.relative(baseDir, fullPath);
|
|
1842
|
-
const stat = yield*
|
|
2217
|
+
const stat = yield* import_effect23.Effect.tryPromise({
|
|
1843
2218
|
try: () => nodeFsPromises.lstat(fullPath),
|
|
1844
2219
|
catch: () => new ArchiveCreateError({ message: `Failed to stat: ${fullPath}` })
|
|
1845
2220
|
});
|
|
@@ -1859,8 +2234,8 @@ var collectIgnorePatterns = (fs, pathService, dir, baseDir, ignoreRules) => impo
|
|
|
1859
2234
|
yield* collectIgnorePatterns(fs, pathService, fullPath, baseDir, ignoreRules);
|
|
1860
2235
|
}
|
|
1861
2236
|
}
|
|
1862
|
-
}).pipe(
|
|
1863
|
-
var initializeIgnoreRules = (fs, pathService, baseDir) =>
|
|
2237
|
+
}).pipe(import_effect23.Effect.catchAll(() => import_effect23.Effect.void));
|
|
2238
|
+
var initializeIgnoreRules = (fs, pathService, baseDir) => import_effect23.Effect.gen(function* () {
|
|
1864
2239
|
const ignoreRules = (0, import_ignore.default)();
|
|
1865
2240
|
ignoreRules.add([".git/", "**/.DS_Store", "**/Thumbs.db"]);
|
|
1866
2241
|
for (const ignoreFileName of IGNORE_FILE_NAMES) {
|
|
@@ -1875,14 +2250,14 @@ var initializeIgnoreRules = (fs, pathService, baseDir) => import_effect20.Effect
|
|
|
1875
2250
|
yield* collectIgnorePatterns(fs, pathService, baseDir, baseDir, ignoreRules);
|
|
1876
2251
|
return ignoreRules;
|
|
1877
2252
|
});
|
|
1878
|
-
var getFilesToInclude = (fs, pathService, dir, ignoreRules) =>
|
|
2253
|
+
var getFilesToInclude = (fs, pathService, dir, ignoreRules) => import_effect23.Effect.gen(function* () {
|
|
1879
2254
|
const filesToInclude = [];
|
|
1880
|
-
const walkDir = (currentDir) =>
|
|
1881
|
-
const items = yield* fs.readDirectory(currentDir).pipe(
|
|
2255
|
+
const walkDir = (currentDir) => import_effect23.Effect.gen(function* () {
|
|
2256
|
+
const items = yield* fs.readDirectory(currentDir).pipe(import_effect23.Effect.mapError(() => new ArchiveCreateError({ message: `Failed to read directory: ${currentDir}` })));
|
|
1882
2257
|
for (const item of items) {
|
|
1883
2258
|
const fullPath = pathService.join(currentDir, item);
|
|
1884
2259
|
const relativePath = pathService.relative(dir, fullPath);
|
|
1885
|
-
const stat = yield*
|
|
2260
|
+
const stat = yield* import_effect23.Effect.tryPromise({
|
|
1886
2261
|
try: () => nodeFsPromises.lstat(fullPath),
|
|
1887
2262
|
catch: () => new ArchiveCreateError({ message: `Failed to stat: ${fullPath}` })
|
|
1888
2263
|
});
|
|
@@ -1896,21 +2271,21 @@ var getFilesToInclude = (fs, pathService, dir, ignoreRules) => import_effect20.E
|
|
|
1896
2271
|
}
|
|
1897
2272
|
}
|
|
1898
2273
|
}
|
|
1899
|
-
}).pipe(
|
|
2274
|
+
}).pipe(import_effect23.Effect.catchAll(() => import_effect23.Effect.void));
|
|
1900
2275
|
yield* walkDir(dir);
|
|
1901
2276
|
return filesToInclude;
|
|
1902
2277
|
});
|
|
1903
|
-
var ArchiveService = class extends
|
|
2278
|
+
var ArchiveService = class extends import_effect23.Effect.Service()("ArchiveService", {
|
|
1904
2279
|
accessors: true,
|
|
1905
|
-
effect:
|
|
1906
|
-
const fs = yield*
|
|
1907
|
-
const pathService = yield*
|
|
1908
|
-
const createZipArchive =
|
|
1909
|
-
yield*
|
|
1910
|
-
yield*
|
|
1911
|
-
yield*
|
|
2280
|
+
effect: import_effect23.Effect.gen(function* () {
|
|
2281
|
+
const fs = yield* import_platform8.FileSystem.FileSystem;
|
|
2282
|
+
const pathService = yield* import_platform8.Path.Path;
|
|
2283
|
+
const createZipArchive = import_effect23.Effect.fn("ArchiveService.createZipArchive")(function* (inputDir, outputFile, options = {}) {
|
|
2284
|
+
yield* import_effect23.Effect.annotateCurrentSpan("inputDir", inputDir);
|
|
2285
|
+
yield* import_effect23.Effect.annotateCurrentSpan("outputFile", outputFile);
|
|
2286
|
+
yield* import_effect23.Effect.log("Creating zip archive", { inputDir, outputFile });
|
|
1912
2287
|
const ignoreRules = options.useIgnoreFiles !== false ? yield* initializeIgnoreRules(fs, pathService, inputDir) : (0, import_ignore.default)();
|
|
1913
|
-
const filesToInclude = options.whitelist ? yield*
|
|
2288
|
+
const filesToInclude = options.whitelist ? yield* import_effect23.Effect.tryPromise({
|
|
1914
2289
|
try: () => Promise.all(
|
|
1915
2290
|
options.whitelist.map((file) => (0, import_build_utils3.getFilesForPattern)(file, inputDir, options.excludeFiles ?? []))
|
|
1916
2291
|
),
|
|
@@ -1918,25 +2293,25 @@ var ArchiveService = class extends import_effect20.Effect.Service()("ArchiveServ
|
|
|
1918
2293
|
message: "Failed to resolve whitelist patterns",
|
|
1919
2294
|
cause: error instanceof Error ? error.message : String(error)
|
|
1920
2295
|
})
|
|
1921
|
-
}) : yield*
|
|
2296
|
+
}) : yield* import_effect23.Effect.gen(function* () {
|
|
1922
2297
|
if (options.excludeFiles && options.excludeFiles.length > 0) {
|
|
1923
2298
|
ignoreRules.add(options.excludeFiles);
|
|
1924
2299
|
}
|
|
1925
2300
|
return yield* getFilesToInclude(fs, pathService, inputDir, ignoreRules).pipe(
|
|
1926
|
-
|
|
2301
|
+
import_effect23.Effect.map((files) => [files])
|
|
1927
2302
|
);
|
|
1928
2303
|
});
|
|
1929
|
-
const archiveExists = yield* fs.exists(outputFile).pipe(
|
|
2304
|
+
const archiveExists = yield* fs.exists(outputFile).pipe(import_effect23.Effect.catchAll(() => import_effect23.Effect.succeed(false)));
|
|
1930
2305
|
if (archiveExists) {
|
|
1931
2306
|
yield* fs.remove(outputFile).pipe(
|
|
1932
|
-
|
|
2307
|
+
import_effect23.Effect.mapError(
|
|
1933
2308
|
(error) => new ArchiveCreateError({
|
|
1934
2309
|
message: `Failed to remove existing archive: ${String(error)}`
|
|
1935
2310
|
})
|
|
1936
2311
|
)
|
|
1937
2312
|
);
|
|
1938
2313
|
}
|
|
1939
|
-
yield*
|
|
2314
|
+
yield* import_effect23.Effect.tryPromise({
|
|
1940
2315
|
try: () => new Promise((resolve, reject) => {
|
|
1941
2316
|
const output = nodeFs.createWriteStream(outputFile);
|
|
1942
2317
|
const archive = (0, import_archiver.default)("zip", { zlib: { level: 9 } });
|
|
@@ -1955,14 +2330,14 @@ var ArchiveService = class extends import_effect20.Effect.Service()("ArchiveServ
|
|
|
1955
2330
|
})
|
|
1956
2331
|
});
|
|
1957
2332
|
const fileInfo = yield* fs.stat(outputFile).pipe(
|
|
1958
|
-
|
|
2333
|
+
import_effect23.Effect.mapError(
|
|
1959
2334
|
(error) => new ArchiveCreateError({
|
|
1960
2335
|
message: `Failed to stat archive: ${String(error)}`
|
|
1961
2336
|
})
|
|
1962
2337
|
)
|
|
1963
2338
|
);
|
|
1964
2339
|
const size = Number(fileInfo.size);
|
|
1965
|
-
yield*
|
|
2340
|
+
yield* import_effect23.Effect.log("Archive created", { size });
|
|
1966
2341
|
return { path: outputFile, size };
|
|
1967
2342
|
});
|
|
1968
2343
|
return { createZipArchive };
|
|
@@ -1971,32 +2346,32 @@ var ArchiveService = class extends import_effect20.Effect.Service()("ArchiveServ
|
|
|
1971
2346
|
};
|
|
1972
2347
|
|
|
1973
2348
|
// src/services/deployment-api.ts
|
|
1974
|
-
var
|
|
1975
|
-
var DeploymentApiService = class extends
|
|
2349
|
+
var import_effect24 = require("effect");
|
|
2350
|
+
var DeploymentApiService = class extends import_effect24.Effect.Service()("DeploymentApiService", {
|
|
1976
2351
|
accessors: true,
|
|
1977
2352
|
dependencies: [ApiClientService.Default],
|
|
1978
|
-
effect:
|
|
2353
|
+
effect: import_effect24.Effect.gen(function* () {
|
|
1979
2354
|
const apiClient = yield* ApiClientService;
|
|
1980
2355
|
const getClient = apiClient.getClient.pipe(
|
|
1981
|
-
|
|
2356
|
+
import_effect24.Effect.mapError((err) => new DeploymentAuthError({ message: `Authentication failed: ${err.message}` }))
|
|
1982
2357
|
);
|
|
1983
|
-
const createDeployment =
|
|
1984
|
-
yield*
|
|
1985
|
-
yield*
|
|
2358
|
+
const createDeployment = import_effect24.Effect.fn("DeploymentApiService.createDeployment")(function* (applicationId) {
|
|
2359
|
+
yield* import_effect24.Effect.annotateCurrentSpan("applicationId", applicationId);
|
|
2360
|
+
yield* import_effect24.Effect.log("Creating deployment", { applicationId });
|
|
1986
2361
|
const client = yield* getClient;
|
|
1987
|
-
const deployment = yield*
|
|
2362
|
+
const deployment = yield* import_effect24.Effect.tryPromise({
|
|
1988
2363
|
try: () => client.deployments.create({ applicationId }),
|
|
1989
2364
|
catch: (error) => new DeploymentCreateError({
|
|
1990
2365
|
message: `Failed to create deployment: ${error instanceof Error ? error.message : String(error)}`
|
|
1991
2366
|
})
|
|
1992
2367
|
});
|
|
1993
|
-
yield*
|
|
2368
|
+
yield* import_effect24.Effect.log("Deployment created", { deploymentId: deployment.id });
|
|
1994
2369
|
return deployment.id;
|
|
1995
2370
|
});
|
|
1996
|
-
const startMultipartUpload =
|
|
1997
|
-
yield*
|
|
2371
|
+
const startMultipartUpload = import_effect24.Effect.fn("DeploymentApiService.startMultipartUpload")(function* (deploymentId) {
|
|
2372
|
+
yield* import_effect24.Effect.annotateCurrentSpan("deploymentId", deploymentId);
|
|
1998
2373
|
const client = yield* getClient;
|
|
1999
|
-
const result = yield*
|
|
2374
|
+
const result = yield* import_effect24.Effect.tryPromise({
|
|
2000
2375
|
try: () => client.deployments.startUpload(deploymentId),
|
|
2001
2376
|
catch: (error) => new UploadStartError({
|
|
2002
2377
|
message: `Failed to start multipart upload: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -2004,9 +2379,9 @@ var DeploymentApiService = class extends import_effect21.Effect.Service()("Deplo
|
|
|
2004
2379
|
});
|
|
2005
2380
|
return result.uploadId;
|
|
2006
2381
|
});
|
|
2007
|
-
const getPresignedUrl =
|
|
2382
|
+
const getPresignedUrl = import_effect24.Effect.fn("DeploymentApiService.getPresignedUrl")(function* (deploymentId, uploadId, partNumber) {
|
|
2008
2383
|
const client = yield* getClient;
|
|
2009
|
-
const result = yield*
|
|
2384
|
+
const result = yield* import_effect24.Effect.tryPromise({
|
|
2010
2385
|
try: () => client.deployments.getPresignedUrl(deploymentId, uploadId, partNumber),
|
|
2011
2386
|
catch: (error) => new PresignedUrlError({
|
|
2012
2387
|
message: `Failed to get presigned URL: ${error instanceof Error ? error.message : String(error)}`,
|
|
@@ -2015,11 +2390,11 @@ var DeploymentApiService = class extends import_effect21.Effect.Service()("Deplo
|
|
|
2015
2390
|
});
|
|
2016
2391
|
return result.url;
|
|
2017
2392
|
});
|
|
2018
|
-
const uploadPart =
|
|
2019
|
-
yield*
|
|
2020
|
-
yield*
|
|
2393
|
+
const uploadPart = import_effect24.Effect.fn("DeploymentApiService.uploadPart")(function* (presignedUrl, data, partNumber) {
|
|
2394
|
+
yield* import_effect24.Effect.annotateCurrentSpan("partNumber", partNumber);
|
|
2395
|
+
yield* import_effect24.Effect.annotateCurrentSpan("size", data.length);
|
|
2021
2396
|
const client = yield* getClient;
|
|
2022
|
-
const result = yield*
|
|
2397
|
+
const result = yield* import_effect24.Effect.tryPromise({
|
|
2023
2398
|
try: () => client.deployments.uploadPart(presignedUrl, data, partNumber),
|
|
2024
2399
|
catch: (error) => new UploadPartError({
|
|
2025
2400
|
message: `Failed to upload part ${partNumber}: ${error instanceof Error ? error.message : String(error)}`,
|
|
@@ -2028,21 +2403,21 @@ var DeploymentApiService = class extends import_effect21.Effect.Service()("Deplo
|
|
|
2028
2403
|
});
|
|
2029
2404
|
return result;
|
|
2030
2405
|
});
|
|
2031
|
-
const completeUpload =
|
|
2032
|
-
yield*
|
|
2033
|
-
yield*
|
|
2406
|
+
const completeUpload = import_effect24.Effect.fn("DeploymentApiService.completeUpload")(function* (deploymentId, uploadId, parts) {
|
|
2407
|
+
yield* import_effect24.Effect.annotateCurrentSpan("deploymentId", deploymentId);
|
|
2408
|
+
yield* import_effect24.Effect.annotateCurrentSpan("partsCount", parts.length);
|
|
2034
2409
|
const client = yield* getClient;
|
|
2035
|
-
yield*
|
|
2410
|
+
yield* import_effect24.Effect.tryPromise({
|
|
2036
2411
|
try: () => client.deployments.completeUpload(deploymentId, uploadId, parts),
|
|
2037
2412
|
catch: (error) => new UploadCompleteError({
|
|
2038
2413
|
message: `Failed to complete upload: ${error instanceof Error ? error.message : String(error)}`
|
|
2039
2414
|
})
|
|
2040
2415
|
});
|
|
2041
|
-
yield*
|
|
2416
|
+
yield* import_effect24.Effect.log("Upload completed successfully");
|
|
2042
2417
|
});
|
|
2043
|
-
const getDeploymentStatus =
|
|
2418
|
+
const getDeploymentStatus = import_effect24.Effect.fn("DeploymentApiService.getDeploymentStatus")(function* (deploymentId) {
|
|
2044
2419
|
const client = yield* getClient;
|
|
2045
|
-
const deployment = yield*
|
|
2420
|
+
const deployment = yield* import_effect24.Effect.tryPromise({
|
|
2046
2421
|
try: () => client.deployments.get(deploymentId),
|
|
2047
2422
|
catch: (error) => new DeploymentStatusError({
|
|
2048
2423
|
message: `Failed to get deployment status: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -2050,9 +2425,9 @@ var DeploymentApiService = class extends import_effect21.Effect.Service()("Deplo
|
|
|
2050
2425
|
});
|
|
2051
2426
|
return deployment.status;
|
|
2052
2427
|
});
|
|
2053
|
-
const getLogs =
|
|
2428
|
+
const getLogs = import_effect24.Effect.fn("DeploymentApiService.getLogs")(function* (deploymentId, options) {
|
|
2054
2429
|
const client = yield* getClient;
|
|
2055
|
-
const result = yield*
|
|
2430
|
+
const result = yield* import_effect24.Effect.tryPromise({
|
|
2056
2431
|
try: () => client.deployments.getLogs(deploymentId, options),
|
|
2057
2432
|
catch: (error) => new DeploymentLogsFetchError({
|
|
2058
2433
|
message: `Failed to get logs: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -2060,9 +2435,9 @@ var DeploymentApiService = class extends import_effect21.Effect.Service()("Deplo
|
|
|
2060
2435
|
});
|
|
2061
2436
|
return result;
|
|
2062
2437
|
});
|
|
2063
|
-
const getHostnames =
|
|
2438
|
+
const getHostnames = import_effect24.Effect.fn("DeploymentApiService.getHostnames")(function* (deploymentId) {
|
|
2064
2439
|
const client = yield* getClient;
|
|
2065
|
-
const result = yield*
|
|
2440
|
+
const result = yield* import_effect24.Effect.tryPromise({
|
|
2066
2441
|
try: () => client.deployments.getHostnames(deploymentId),
|
|
2067
2442
|
catch: (error) => new DeploymentHostnamesFetchError({
|
|
2068
2443
|
message: `Failed to get hostnames: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -2093,86 +2468,86 @@ var appOption5 = import_cli11.Options.text("app").pipe(
|
|
|
2093
2468
|
var deployCommand = import_cli11.Command.make(
|
|
2094
2469
|
"deploy",
|
|
2095
2470
|
{ app: appOption5 },
|
|
2096
|
-
({ app }) =>
|
|
2471
|
+
({ app }) => import_effect25.Effect.gen(function* () {
|
|
2097
2472
|
const projectConfig = yield* ProjectConfigService;
|
|
2098
2473
|
const deploymentApi = yield* DeploymentApiService;
|
|
2099
2474
|
const archiveService = yield* ArchiveService;
|
|
2100
2475
|
const projectLink = yield* ProjectLinkService;
|
|
2101
|
-
const pathService = yield*
|
|
2476
|
+
const pathService = yield* import_platform9.Path.Path;
|
|
2102
2477
|
const cwd = process.cwd();
|
|
2103
|
-
const applicationId = yield*
|
|
2104
|
-
onSome: (id) =>
|
|
2105
|
-
onNone: () => projectLink.resolve(cwd).pipe(
|
|
2478
|
+
const applicationId = yield* import_effect25.Option.match(app, {
|
|
2479
|
+
onSome: (id) => import_effect25.Effect.succeed(id),
|
|
2480
|
+
onNone: () => projectLink.resolve(cwd).pipe(import_effect25.Effect.map((link) => link.applicationId))
|
|
2106
2481
|
});
|
|
2107
|
-
yield*
|
|
2482
|
+
yield* import_effect25.Effect.log("Starting deploy command");
|
|
2108
2483
|
const { config } = yield* projectConfig.resolve(cwd);
|
|
2109
|
-
yield*
|
|
2484
|
+
yield* import_effect25.Console.log("Creating deployment...");
|
|
2110
2485
|
const deploymentId = yield* deploymentApi.createDeployment(applicationId);
|
|
2111
|
-
yield*
|
|
2112
|
-
yield*
|
|
2113
|
-
const archivePath = pathService.join(
|
|
2486
|
+
yield* import_effect25.Console.log(`Deployment ID: ${deploymentId}`);
|
|
2487
|
+
yield* import_effect25.Console.log("Creating archive...");
|
|
2488
|
+
const archivePath = pathService.join(os4.tmpdir(), `project-${Date.now()}.zip`);
|
|
2114
2489
|
const archive = yield* archiveService.createZipArchive(config.userArchive?.rootOverwrite || cwd, archivePath, {
|
|
2115
2490
|
whitelist: config.userArchive?.fileWhitelist,
|
|
2116
2491
|
excludeFiles: config.excludeFiles,
|
|
2117
2492
|
useIgnoreFiles: false,
|
|
2118
2493
|
useManagedIgnore: false
|
|
2119
2494
|
});
|
|
2120
|
-
yield*
|
|
2121
|
-
yield*
|
|
2495
|
+
yield* import_effect25.Console.log(`Archive created (${(0, import_commons.formatFileSize)(archive.size)})`);
|
|
2496
|
+
yield* import_effect25.Console.log("Uploading archive...");
|
|
2122
2497
|
yield* uploadArchive(deploymentId, archivePath, archive.size);
|
|
2123
|
-
yield*
|
|
2124
|
-
yield*
|
|
2498
|
+
yield* import_effect25.Console.log("Upload complete.");
|
|
2499
|
+
yield* import_effect25.Console.log("The deployment pipeline is now being provisioned. This may take a few seconds.");
|
|
2125
2500
|
yield* pollDeployment(deploymentId);
|
|
2126
2501
|
}).pipe(
|
|
2127
|
-
|
|
2128
|
-
ProjectNotLinkedError: (err) =>
|
|
2129
|
-
ProjectLinkReadError: (err) =>
|
|
2130
|
-
ConfigNotFoundError: (err) =>
|
|
2131
|
-
ConfigParseError: (err) =>
|
|
2132
|
-
ConfigValidationError: (err) =>
|
|
2502
|
+
import_effect25.Effect.catchTags({
|
|
2503
|
+
ProjectNotLinkedError: (err) => import_effect25.Console.error(err.message).pipe(import_effect25.Effect.andThen(import_effect25.Effect.fail(err))),
|
|
2504
|
+
ProjectLinkReadError: (err) => import_effect25.Console.error(err.message).pipe(import_effect25.Effect.andThen(import_effect25.Effect.fail(err))),
|
|
2505
|
+
ConfigNotFoundError: (err) => import_effect25.Console.error(err.message).pipe(import_effect25.Effect.andThen(import_effect25.Effect.fail(err))),
|
|
2506
|
+
ConfigParseError: (err) => import_effect25.Console.error(`Config parse error: ${err.message}`).pipe(import_effect25.Effect.andThen(import_effect25.Effect.fail(err))),
|
|
2507
|
+
ConfigValidationError: (err) => import_effect25.Effect.gen(function* () {
|
|
2133
2508
|
for (const e of err.errors) {
|
|
2134
|
-
yield*
|
|
2509
|
+
yield* import_effect25.Console.error(e);
|
|
2135
2510
|
}
|
|
2136
|
-
yield*
|
|
2137
|
-
}).pipe(
|
|
2138
|
-
DeploymentCreateError: (err) =>
|
|
2139
|
-
ArchiveCreateError: (err) =>
|
|
2140
|
-
UploadStartError: (err) =>
|
|
2141
|
-
UploadPartError: (err) =>
|
|
2142
|
-
UploadCompleteError: (err) =>
|
|
2143
|
-
PresignedUrlError: (err) =>
|
|
2144
|
-
DeploymentAuthError: (err) =>
|
|
2145
|
-
DeploymentFailedError: (err) =>
|
|
2511
|
+
yield* import_effect25.Console.error(err.message);
|
|
2512
|
+
}).pipe(import_effect25.Effect.andThen(import_effect25.Effect.fail(err))),
|
|
2513
|
+
DeploymentCreateError: (err) => import_effect25.Console.error(`Deployment creation failed: ${err.message}`).pipe(import_effect25.Effect.andThen(import_effect25.Effect.fail(err))),
|
|
2514
|
+
ArchiveCreateError: (err) => import_effect25.Console.error(`Archive creation failed: ${err.message}`).pipe(import_effect25.Effect.andThen(import_effect25.Effect.fail(err))),
|
|
2515
|
+
UploadStartError: (err) => import_effect25.Console.error(`Upload failed: ${err.message}`).pipe(import_effect25.Effect.andThen(import_effect25.Effect.fail(err))),
|
|
2516
|
+
UploadPartError: (err) => import_effect25.Console.error(`Upload failed: ${err.message}`).pipe(import_effect25.Effect.andThen(import_effect25.Effect.fail(err))),
|
|
2517
|
+
UploadCompleteError: (err) => import_effect25.Console.error(`Upload failed: ${err.message}`).pipe(import_effect25.Effect.andThen(import_effect25.Effect.fail(err))),
|
|
2518
|
+
PresignedUrlError: (err) => import_effect25.Console.error(`Upload failed: ${err.message}`).pipe(import_effect25.Effect.andThen(import_effect25.Effect.fail(err))),
|
|
2519
|
+
DeploymentAuthError: (err) => import_effect25.Console.error(`Authentication failed: ${err.message}`).pipe(import_effect25.Effect.andThen(import_effect25.Effect.fail(err))),
|
|
2520
|
+
DeploymentFailedError: (err) => import_effect25.Console.error(err.message).pipe(import_effect25.Effect.andThen(import_effect25.Effect.fail(err)))
|
|
2146
2521
|
})
|
|
2147
2522
|
)
|
|
2148
2523
|
);
|
|
2149
|
-
var uploadArchive = (deploymentId, archivePath, fileSize) =>
|
|
2524
|
+
var uploadArchive = (deploymentId, archivePath, fileSize) => import_effect25.Effect.gen(function* () {
|
|
2150
2525
|
const deploymentApi = yield* DeploymentApiService;
|
|
2151
|
-
const fs = yield*
|
|
2526
|
+
const fs = yield* import_platform9.FileSystem.FileSystem;
|
|
2152
2527
|
const uploadId = yield* deploymentApi.startMultipartUpload(deploymentId);
|
|
2153
2528
|
const FILE_CHUNK_SIZE = 10 * 1024 * 1024;
|
|
2154
2529
|
const numChunks = Math.ceil(fileSize / FILE_CHUNK_SIZE);
|
|
2155
|
-
yield*
|
|
2156
|
-
const parts = yield*
|
|
2530
|
+
yield* import_effect25.Effect.log("Starting multipart upload", { uploadId, numChunks, fileSize });
|
|
2531
|
+
const parts = yield* import_effect25.Effect.all(
|
|
2157
2532
|
Array.from({ length: numChunks }, (_, i) => {
|
|
2158
2533
|
const partNumber = i + 1;
|
|
2159
2534
|
const start = i * FILE_CHUNK_SIZE;
|
|
2160
2535
|
const bytesToRead = partNumber < numChunks ? FILE_CHUNK_SIZE : fileSize - start;
|
|
2161
|
-
return
|
|
2536
|
+
return import_effect25.Effect.gen(function* () {
|
|
2162
2537
|
const presignedUrl = yield* deploymentApi.getPresignedUrl(deploymentId, uploadId, partNumber);
|
|
2163
|
-
const chunkData = yield*
|
|
2164
|
-
|
|
2538
|
+
const chunkData = yield* import_effect25.Stream.runCollect(fs.stream(archivePath, { offset: start, bytesToRead })).pipe(
|
|
2539
|
+
import_effect25.Effect.map((chunks) => {
|
|
2165
2540
|
const arrays = Array.from(chunks);
|
|
2166
2541
|
return Buffer.concat(arrays);
|
|
2167
2542
|
}),
|
|
2168
|
-
|
|
2543
|
+
import_effect25.Effect.mapError(
|
|
2169
2544
|
(error) => new UploadPartError({
|
|
2170
2545
|
message: `Failed to read chunk ${partNumber}: ${String(error)}`,
|
|
2171
2546
|
partNumber
|
|
2172
2547
|
})
|
|
2173
2548
|
)
|
|
2174
2549
|
);
|
|
2175
|
-
yield*
|
|
2550
|
+
yield* import_effect25.Effect.log(`Uploading part ${partNumber}/${numChunks}`, { size: chunkData.length });
|
|
2176
2551
|
return yield* deploymentApi.uploadPart(presignedUrl, chunkData, partNumber);
|
|
2177
2552
|
});
|
|
2178
2553
|
}),
|
|
@@ -2180,20 +2555,20 @@ var uploadArchive = (deploymentId, archivePath, fileSize) => import_effect22.Eff
|
|
|
2180
2555
|
);
|
|
2181
2556
|
yield* deploymentApi.completeUpload(deploymentId, uploadId, parts);
|
|
2182
2557
|
});
|
|
2183
|
-
var pollDeployment = (deploymentId) =>
|
|
2558
|
+
var pollDeployment = (deploymentId) => import_effect25.Effect.gen(function* () {
|
|
2184
2559
|
const deploymentApi = yield* DeploymentApiService;
|
|
2185
2560
|
let lastStatus = "PENDING";
|
|
2186
2561
|
let logOffset = 0;
|
|
2187
|
-
yield*
|
|
2188
|
-
yield*
|
|
2189
|
-
|
|
2190
|
-
const newStatus = yield* deploymentApi.getDeploymentStatus(deploymentId).pipe(
|
|
2562
|
+
yield* import_effect25.Console.log("Status: Pending");
|
|
2563
|
+
yield* import_effect25.Effect.repeat(
|
|
2564
|
+
import_effect25.Effect.gen(function* () {
|
|
2565
|
+
const newStatus = yield* deploymentApi.getDeploymentStatus(deploymentId).pipe(import_effect25.Effect.catchTag("DeploymentStatusError", () => import_effect25.Effect.succeed(lastStatus)));
|
|
2191
2566
|
if (newStatus !== lastStatus) {
|
|
2192
2567
|
lastStatus = newStatus;
|
|
2193
2568
|
const label = newStatus.charAt(0) + newStatus.slice(1).toLowerCase();
|
|
2194
|
-
yield*
|
|
2569
|
+
yield* import_effect25.Console.log(`Status: ${label}`);
|
|
2195
2570
|
}
|
|
2196
|
-
const logsPage = yield* deploymentApi.getLogs(deploymentId, { offset: logOffset, limit: 100 }).pipe(
|
|
2571
|
+
const logsPage = yield* deploymentApi.getLogs(deploymentId, { offset: logOffset, limit: 100 }).pipe(import_effect25.Effect.catchTag("DeploymentLogsFetchError", () => import_effect25.Effect.succeed(null)));
|
|
2197
2572
|
if (logsPage) {
|
|
2198
2573
|
for (const logEntry of logsPage.items) {
|
|
2199
2574
|
logOffset++;
|
|
@@ -2201,68 +2576,211 @@ var pollDeployment = (deploymentId) => import_effect22.Effect.gen(function* () {
|
|
|
2201
2576
|
}
|
|
2202
2577
|
}
|
|
2203
2578
|
if (newStatus === "ACTIVE") {
|
|
2204
|
-
const hostnames = yield* deploymentApi.getHostnames(deploymentId).pipe(
|
|
2579
|
+
const hostnames = yield* deploymentApi.getHostnames(deploymentId).pipe(import_effect25.Effect.catchTag("DeploymentHostnamesFetchError", () => import_effect25.Effect.succeed([])));
|
|
2205
2580
|
const active = hostnames.find((h) => h.active) ?? hostnames.at(0);
|
|
2206
2581
|
if (active) {
|
|
2207
|
-
yield*
|
|
2582
|
+
yield* import_effect25.Console.log(`Deployed to https://${active.hostname}`);
|
|
2208
2583
|
} else {
|
|
2209
|
-
yield*
|
|
2584
|
+
yield* import_effect25.Console.log("Deployment is live.");
|
|
2210
2585
|
}
|
|
2211
|
-
return yield*
|
|
2586
|
+
return yield* import_effect25.Effect.fail("done");
|
|
2212
2587
|
}
|
|
2213
2588
|
if (newStatus === "FAILED") {
|
|
2214
|
-
return yield*
|
|
2589
|
+
return yield* import_effect25.Effect.fail(
|
|
2215
2590
|
new DeploymentFailedError({
|
|
2216
2591
|
message: "The deployment failed. Please check the logs for more information."
|
|
2217
2592
|
})
|
|
2218
2593
|
);
|
|
2219
2594
|
}
|
|
2220
2595
|
}),
|
|
2221
|
-
|
|
2596
|
+
import_effect25.Schedule.addDelay(import_effect25.Schedule.forever, () => import_effect25.Duration.seconds(1))
|
|
2222
2597
|
).pipe(
|
|
2223
|
-
|
|
2224
|
-
if (err === "done") return
|
|
2225
|
-
return
|
|
2598
|
+
import_effect25.Effect.catchAll((err) => {
|
|
2599
|
+
if (err === "done") return import_effect25.Effect.void;
|
|
2600
|
+
return import_effect25.Effect.fail(err);
|
|
2226
2601
|
})
|
|
2227
2602
|
);
|
|
2228
2603
|
});
|
|
2229
2604
|
var printLog = (logEntry) => {
|
|
2230
2605
|
switch (logEntry.type) {
|
|
2231
2606
|
case "ERROR":
|
|
2232
|
-
return
|
|
2607
|
+
return import_effect25.Console.error(logEntry.message);
|
|
2233
2608
|
case "WARN":
|
|
2234
|
-
return
|
|
2609
|
+
return import_effect25.Console.warn(logEntry.message);
|
|
2235
2610
|
default:
|
|
2236
|
-
return
|
|
2611
|
+
return import_effect25.Console.log(logEntry.message);
|
|
2237
2612
|
}
|
|
2238
2613
|
};
|
|
2239
2614
|
|
|
2240
2615
|
// src/commands/platform/index.ts
|
|
2241
|
-
var platformBase = import_cli12.Command.make("platform", {}, () =>
|
|
2616
|
+
var platformBase = import_cli12.Command.make("platform", {}, () => import_effect26.Effect.void);
|
|
2242
2617
|
var platformCommand = platformBase.pipe(import_cli12.Command.withSubcommands([deployCommand]));
|
|
2243
2618
|
|
|
2244
|
-
// src/commands/
|
|
2619
|
+
// src/commands/setup/index.ts
|
|
2245
2620
|
var import_cli13 = require("@effect/cli");
|
|
2246
|
-
var
|
|
2247
|
-
var
|
|
2621
|
+
var import_effect27 = require("effect");
|
|
2622
|
+
var fileArg2 = import_cli13.Args.text({ name: "file" }).pipe(
|
|
2623
|
+
import_cli13.Args.withDescription("Output file to write (default: .env.local)"),
|
|
2624
|
+
import_cli13.Args.optional
|
|
2625
|
+
);
|
|
2626
|
+
var appOption6 = import_cli13.Options.text("app").pipe(
|
|
2627
|
+
import_cli13.Options.withAlias("a"),
|
|
2628
|
+
import_cli13.Options.withDescription("Application ID to set up (skips the interactive picker)"),
|
|
2629
|
+
import_cli13.Options.optional
|
|
2630
|
+
);
|
|
2631
|
+
var orgOption6 = import_cli13.Options.text("org").pipe(
|
|
2632
|
+
import_cli13.Options.withAlias("o"),
|
|
2633
|
+
import_cli13.Options.withDescription("Only list applications belonging to this organization ID when picking"),
|
|
2634
|
+
import_cli13.Options.optional
|
|
2635
|
+
);
|
|
2636
|
+
var environmentOption2 = import_cli13.Options.text("environment").pipe(
|
|
2637
|
+
import_cli13.Options.withAlias("e"),
|
|
2638
|
+
import_cli13.Options.withDescription("Environment slug to resolve overrides for (e.g. preview)"),
|
|
2639
|
+
import_cli13.Options.optional
|
|
2640
|
+
);
|
|
2641
|
+
var yesOption2 = import_cli13.Options.boolean("yes").pipe(
|
|
2642
|
+
import_cli13.Options.withAlias("y"),
|
|
2643
|
+
import_cli13.Options.withDescription("Overwrite an existing file without confirmation")
|
|
2644
|
+
);
|
|
2645
|
+
var rotateOption2 = import_cli13.Options.boolean("rotate").pipe(
|
|
2646
|
+
import_cli13.Options.withDescription("Force a fresh API key, revoking the previous one")
|
|
2647
|
+
);
|
|
2648
|
+
var setupCommand = import_cli13.Command.make(
|
|
2649
|
+
"setup",
|
|
2650
|
+
{
|
|
2651
|
+
file: fileArg2,
|
|
2652
|
+
app: appOption6,
|
|
2653
|
+
org: orgOption6,
|
|
2654
|
+
environment: environmentOption2,
|
|
2655
|
+
yes: yesOption2,
|
|
2656
|
+
rotate: rotateOption2
|
|
2657
|
+
},
|
|
2658
|
+
({ file, app, org, environment, yes, rotate }) => import_effect27.Effect.gen(function* () {
|
|
2659
|
+
const apiClient = yield* ApiClientService;
|
|
2660
|
+
const projectLink = yield* ProjectLinkService;
|
|
2661
|
+
const envFile = yield* EnvFileService;
|
|
2662
|
+
const localCredentials = yield* LocalCredentialsService;
|
|
2663
|
+
const cwd = process.cwd();
|
|
2664
|
+
const existingLink = yield* projectLink.load(cwd);
|
|
2665
|
+
let applicationId;
|
|
2666
|
+
if (import_effect27.Option.isSome(existingLink)) {
|
|
2667
|
+
applicationId = existingLink.value.applicationId;
|
|
2668
|
+
if (import_effect27.Option.isSome(app) || import_effect27.Option.isSome(org)) {
|
|
2669
|
+
yield* import_effect27.Console.log(
|
|
2670
|
+
`Note: this directory is already linked to ${applicationId}; ignoring --app/--org. Run "gigadrive unlink" first to target a different application.`
|
|
2671
|
+
);
|
|
2672
|
+
}
|
|
2673
|
+
} else {
|
|
2674
|
+
const organizationId = import_effect27.Option.getOrUndefined(org);
|
|
2675
|
+
const { items: apps } = yield* apiClient.request((client) => client.applications.list({ organizationId }));
|
|
2676
|
+
if (apps.length === 0) {
|
|
2677
|
+
return yield* import_effect27.Effect.fail(
|
|
2678
|
+
new NoApplicationsFoundError({
|
|
2679
|
+
message: 'No applications found. Create one in the Gigadrive console, then run "gigadrive setup" again.'
|
|
2680
|
+
})
|
|
2681
|
+
);
|
|
2682
|
+
}
|
|
2683
|
+
const explicitAppId = import_effect27.Option.getOrUndefined(app);
|
|
2684
|
+
let chosen;
|
|
2685
|
+
if (explicitAppId !== void 0) {
|
|
2686
|
+
const match = apps.find((a) => a.id === explicitAppId);
|
|
2687
|
+
if (match === void 0) {
|
|
2688
|
+
return yield* import_effect27.Effect.fail(
|
|
2689
|
+
new ApplicationNotFoundError({
|
|
2690
|
+
message: `Application "${explicitAppId}" was not found among your applications.`
|
|
2691
|
+
})
|
|
2692
|
+
);
|
|
2693
|
+
}
|
|
2694
|
+
chosen = match;
|
|
2695
|
+
} else if (apps.length === 1) {
|
|
2696
|
+
chosen = apps[0];
|
|
2697
|
+
} else {
|
|
2698
|
+
chosen = yield* import_cli13.Prompt.run(
|
|
2699
|
+
import_cli13.Prompt.select({
|
|
2700
|
+
message: "Select an application to set up",
|
|
2701
|
+
choices: apps.map((a) => ({ title: `${a.name} (${a.organization.name})`, value: a }))
|
|
2702
|
+
})
|
|
2703
|
+
);
|
|
2704
|
+
}
|
|
2705
|
+
applicationId = chosen.id;
|
|
2706
|
+
yield* projectLink.save(cwd, { applicationId, organizationId: chosen.organization.id });
|
|
2707
|
+
yield* import_effect27.Console.log(`Linked this directory to application ${applicationId}.`);
|
|
2708
|
+
}
|
|
2709
|
+
const target = import_effect27.Option.getOrElse(file, () => ".env.local");
|
|
2710
|
+
const environmentSlug = import_effect27.Option.getOrUndefined(environment);
|
|
2711
|
+
const { items, omittedSensitive } = yield* apiClient.request(
|
|
2712
|
+
(client) => client.applications.envVars.pull(applicationId, environmentSlug ? { environment: environmentSlug } : void 0)
|
|
2713
|
+
);
|
|
2714
|
+
const existing = yield* envFile.read(target);
|
|
2715
|
+
if (import_effect27.Option.isSome(existing) && !yes) {
|
|
2716
|
+
const overwrite = yield* import_cli13.Prompt.run(
|
|
2717
|
+
import_cli13.Prompt.confirm({ message: `${target} already exists. Overwrite?`, initial: false })
|
|
2718
|
+
);
|
|
2719
|
+
if (!overwrite) {
|
|
2720
|
+
return yield* import_effect27.Console.log("Cancelled.");
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
const credentialEntries2 = yield* localCredentials.provision({
|
|
2724
|
+
applicationId,
|
|
2725
|
+
rotate,
|
|
2726
|
+
existingContent: import_effect27.Option.getOrUndefined(existing)
|
|
2727
|
+
});
|
|
2728
|
+
const entries = [...items.map((v) => ({ key: v.key, value: v.value })), ...credentialEntries2];
|
|
2729
|
+
yield* envFile.write(target, entries);
|
|
2730
|
+
const gitignored = yield* envFile.ensureGitignored(cwd, target);
|
|
2731
|
+
yield* import_effect27.Console.log("\nLocal dev environment ready.");
|
|
2732
|
+
yield* import_effect27.Console.log(` \u2022 Wrote ${items.length} variable(s) and API credentials to ${target}.`);
|
|
2733
|
+
if (omittedSensitive > 0) {
|
|
2734
|
+
yield* import_effect27.Console.log(
|
|
2735
|
+
` \u2022 Skipped ${omittedSensitive} sensitive variable(s) (only production/preview hold secrets).`
|
|
2736
|
+
);
|
|
2737
|
+
}
|
|
2738
|
+
if (gitignored) {
|
|
2739
|
+
yield* import_effect27.Console.log(` \u2022 Added ${target} to .gitignore.`);
|
|
2740
|
+
}
|
|
2741
|
+
yield* import_effect27.Console.log(" \u2022 Your app can now call the Gigadrive API via the SDK (GIGADRIVE_CLIENT_ID/SECRET).");
|
|
2742
|
+
}).pipe(
|
|
2743
|
+
import_effect27.Effect.catchTags({
|
|
2744
|
+
// Ctrl+C during a prompt is a deliberate cancel — exit 0.
|
|
2745
|
+
QuitException: () => import_effect27.Console.log("Cancelled."),
|
|
2746
|
+
NotAuthenticatedError: (err) => import_effect27.Console.error('You are not logged in. Run "gigadrive login" to authenticate.').pipe(
|
|
2747
|
+
import_effect27.Effect.andThen(import_effect27.Effect.fail(err))
|
|
2748
|
+
),
|
|
2749
|
+
ApiRequestError: (err) => import_effect27.Console.error(`Setup failed: ${err.message}`).pipe(import_effect27.Effect.andThen(import_effect27.Effect.fail(err))),
|
|
2750
|
+
NoApplicationsFoundError: (err) => import_effect27.Console.error(err.message).pipe(import_effect27.Effect.andThen(import_effect27.Effect.fail(err))),
|
|
2751
|
+
ApplicationNotFoundError: (err) => import_effect27.Console.error(err.message).pipe(import_effect27.Effect.andThen(import_effect27.Effect.fail(err))),
|
|
2752
|
+
ProjectLinkReadError: (err) => import_effect27.Console.error(err.message).pipe(import_effect27.Effect.andThen(import_effect27.Effect.fail(err))),
|
|
2753
|
+
ProjectLinkWriteError: (err) => import_effect27.Console.error(err.message).pipe(import_effect27.Effect.andThen(import_effect27.Effect.fail(err))),
|
|
2754
|
+
EnvFileReadError: (err) => import_effect27.Console.error(err.message).pipe(import_effect27.Effect.andThen(import_effect27.Effect.fail(err))),
|
|
2755
|
+
EnvFileWriteError: (err) => import_effect27.Console.error(err.message).pipe(import_effect27.Effect.andThen(import_effect27.Effect.fail(err))),
|
|
2756
|
+
DevCredentialsStoreReadError: (err) => import_effect27.Console.error(err.message).pipe(import_effect27.Effect.andThen(import_effect27.Effect.fail(err))),
|
|
2757
|
+
DevCredentialsStoreWriteError: (err) => import_effect27.Console.error(err.message).pipe(import_effect27.Effect.andThen(import_effect27.Effect.fail(err)))
|
|
2758
|
+
})
|
|
2759
|
+
)
|
|
2760
|
+
);
|
|
2761
|
+
|
|
2762
|
+
// src/commands/whoami/index.ts
|
|
2763
|
+
var import_cli14 = require("@effect/cli");
|
|
2764
|
+
var import_effect28 = require("effect");
|
|
2765
|
+
var whoamiCommand = import_cli14.Command.make(
|
|
2248
2766
|
"whoami",
|
|
2249
2767
|
{},
|
|
2250
|
-
() =>
|
|
2768
|
+
() => import_effect28.Effect.gen(function* () {
|
|
2251
2769
|
const auth = yield* AuthService;
|
|
2252
2770
|
const info = yield* auth.getUserInfo;
|
|
2253
|
-
yield*
|
|
2771
|
+
yield* import_effect28.Console.log(JSON.stringify(info, null, 2));
|
|
2254
2772
|
}).pipe(
|
|
2255
|
-
|
|
2256
|
-
NotAuthenticatedError: () =>
|
|
2257
|
-
UserInfoFetchError: (err) =>
|
|
2258
|
-
OAuthDiscoveryError: (err) =>
|
|
2773
|
+
import_effect28.Effect.catchTags({
|
|
2774
|
+
NotAuthenticatedError: () => import_effect28.Console.log('You are not logged in. Run "gigadrive login" to authenticate.'),
|
|
2775
|
+
UserInfoFetchError: (err) => import_effect28.Console.error(`Failed to retrieve user info: ${err.message}`),
|
|
2776
|
+
OAuthDiscoveryError: (err) => import_effect28.Console.error(`Failed to retrieve user info: ${err.message}`)
|
|
2259
2777
|
})
|
|
2260
2778
|
)
|
|
2261
2779
|
);
|
|
2262
2780
|
|
|
2263
2781
|
// src/index.ts
|
|
2264
|
-
var gigadrive =
|
|
2265
|
-
|
|
2782
|
+
var gigadrive = import_cli15.Command.make("gigadrive", {}, () => import_effect29.Effect.void).pipe(
|
|
2783
|
+
import_cli15.Command.withSubcommands([
|
|
2266
2784
|
loginCommand,
|
|
2267
2785
|
logoutCommand,
|
|
2268
2786
|
whoamiCommand,
|
|
@@ -2274,27 +2792,31 @@ var gigadrive = import_cli14.Command.make("gigadrive", {}, () => import_effect25
|
|
|
2274
2792
|
aiCommand,
|
|
2275
2793
|
buildCommand,
|
|
2276
2794
|
debugCommand,
|
|
2277
|
-
platformCommand
|
|
2795
|
+
platformCommand,
|
|
2796
|
+
setupCommand
|
|
2278
2797
|
])
|
|
2279
2798
|
);
|
|
2280
|
-
var cli =
|
|
2799
|
+
var cli = import_cli15.Command.run(gigadrive, {
|
|
2281
2800
|
name: "Gigadrive CLI",
|
|
2282
2801
|
version: package_default.version
|
|
2283
2802
|
});
|
|
2284
|
-
var BaseServices =
|
|
2803
|
+
var BaseServices = import_effect29.Layer.mergeAll(
|
|
2285
2804
|
OAuthConfigService.Default,
|
|
2286
2805
|
AuthStorageService.Default,
|
|
2287
2806
|
PackageManagerService.Default,
|
|
2288
2807
|
ArchiveService.Default,
|
|
2289
2808
|
import_network_config2.NetworkConfigLive,
|
|
2290
2809
|
ProjectConfigService.Default,
|
|
2291
|
-
ProjectLinkService.Default
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
var
|
|
2296
|
-
var
|
|
2297
|
-
|
|
2298
|
-
);
|
|
2299
|
-
|
|
2810
|
+
ProjectLinkService.Default,
|
|
2811
|
+
EnvFileService.Default,
|
|
2812
|
+
DevCredentialsStore.Default
|
|
2813
|
+
).pipe(import_effect29.Layer.provideMerge(AuthService.Default));
|
|
2814
|
+
var ApiClientLive = import_effect29.Layer.provide(ApiClientService.Default, BaseServices);
|
|
2815
|
+
var DeploymentApiLive = import_effect29.Layer.provide(DeploymentApiService.Default, BaseServices);
|
|
2816
|
+
var LocalCredentialsLive = import_effect29.Layer.provide(LocalCredentialsService.Default, BaseServices);
|
|
2817
|
+
var ServicesLive = import_effect29.Layer.mergeAll(BaseServices, ApiClientLive, DeploymentApiLive, LocalCredentialsLive);
|
|
2818
|
+
var AppLive = import_effect29.Layer.mergeAll(ServicesLive, import_effect29.Logger.minimumLogLevel(import_effect29.LogLevel.Info)).pipe(
|
|
2819
|
+
import_effect29.Layer.provideMerge(import_platform_node.NodeContext.layer)
|
|
2820
|
+
);
|
|
2821
|
+
import_platform_node.NodeRuntime.runMain(import_effect29.Effect.provide(cli(process.argv), AppLive));
|
|
2300
2822
|
//# sourceMappingURL=index.cjs.map
|