@graftland/cli 0.3.3 → 0.4.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/Application.d.ts +27 -0
- package/dist/Application.d.ts.map +1 -0
- package/dist/Application.js +27 -0
- package/dist/Application.js.map +1 -0
- package/dist/Commands.d.ts +34 -0
- package/dist/Commands.d.ts.map +1 -0
- package/dist/Commands.js +31 -0
- package/dist/Commands.js.map +1 -0
- package/dist/Manage.d.ts +8 -5
- package/dist/Manage.d.ts.map +1 -1
- package/dist/Manage.js +60 -2
- package/dist/Manage.js.map +1 -1
- package/dist/Start.d.ts +2 -1
- package/dist/Start.d.ts.map +1 -1
- package/dist/Start.js +25 -9
- package/dist/Start.js.map +1 -1
- package/dist/bin.js +38 -11
- package/dist/bin.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/internal/commandConfig.js +62 -0
- package/dist/internal/commandConfig.js.map +1 -0
- package/dist/internal/commandHost.js +80 -0
- package/dist/internal/commandHost.js.map +1 -0
- package/dist/internal/commandRegistry.js +59 -0
- package/dist/internal/commandRegistry.js.map +1 -0
- package/dist/internal/configSchema.d.ts +25 -4
- package/dist/internal/configSchema.d.ts.map +1 -1
- package/dist/internal/configSchema.js +6 -34
- package/dist/internal/configSchema.js.map +1 -1
- package/dist/internal/env.js.map +1 -1
- package/dist/internal/importer.js +18 -0
- package/dist/internal/importer.js.map +1 -0
- package/dist/internal/intercepts.js.map +1 -1
- package/dist/internal/protocolOutput.js +67 -0
- package/dist/internal/protocolOutput.js.map +1 -0
- package/dist/internal/watch.js.map +1 -1
- package/package.json +10 -7
- package/schema.json +2321 -0
- package/src/Application.ts +55 -0
- package/src/Commands.ts +47 -0
- package/src/Manage.ts +81 -2
- package/src/Start.ts +100 -28
- package/src/bin.ts +80 -12
- package/src/index.ts +3 -0
- package/src/internal/commandConfig.ts +91 -0
- package/src/internal/commandHost.ts +216 -0
- package/src/internal/commandRegistry.ts +100 -0
- package/src/internal/configSchema.ts +10 -70
- package/src/internal/env.ts +3 -2
- package/src/internal/importer.ts +28 -0
- package/src/internal/intercepts.ts +2 -1
- package/src/internal/protocolOutput.ts +101 -0
- package/src/internal/watch.ts +4 -2
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Context, Effect, Exit, Layer, Schema, Scope } from "effect";
|
|
2
|
+
import { NodeServices } from "@effect/platform-node";
|
|
3
|
+
import { Digest, SecureRandom, Signature } from "effect/crypto";
|
|
4
|
+
declare namespace Application_d_exports {
|
|
5
|
+
export { Application, ApplicationError, ProtocolOutput, platform };
|
|
6
|
+
}
|
|
7
|
+
/** Set before argument parsing when stdout belongs to a byte protocol. */
|
|
8
|
+
export declare const ProtocolOutput: Context.Reference<boolean>;
|
|
9
|
+
declare const ApplicationError_base: Schema.Class<ApplicationError, Schema.TaggedStruct<"ApplicationError", {
|
|
10
|
+
readonly cause: Schema.Cause<Schema.Unknown, Schema.Unknown>;
|
|
11
|
+
}>, import("effect/Cause").YieldableError & {
|
|
12
|
+
readonly brand: unique symbol;
|
|
13
|
+
}>;
|
|
14
|
+
/** An application requested a failed process exit, preserving its original cause. */
|
|
15
|
+
export declare class ApplicationError extends ApplicationError_base {}
|
|
16
|
+
declare const Application_base: Context.ServiceClass<Application, "@graftland/cli/Application", {
|
|
17
|
+
/** Exclusively reserves the process protocol channel until the caller releases its scope. */
|
|
18
|
+
readonly claimProtocol: Effect.Effect<void, ApplicationError, Scope.Scope>;
|
|
19
|
+
readonly finish: (exit: Exit.Exit<void, unknown>) => Effect.Effect<void>;
|
|
20
|
+
readonly onExit: (release: Effect.Effect<void>) => Effect.Effect<void>;
|
|
21
|
+
}>;
|
|
22
|
+
/** Applications can request process completion and report cleanup independently of loader diagnostics. */
|
|
23
|
+
export declare class Application extends Application_base {}
|
|
24
|
+
/** Node capabilities shared by application and command hosts. */
|
|
25
|
+
export declare const platform: Layer.Layer<Digest.Digest | import("effect/http/HttpClient").HttpClient | SecureRandom.SecureRandom | Signature.Signature | NodeServices.NodeServices, never, never>;
|
|
26
|
+
export { Application_d_exports };
|
|
27
|
+
//# sourceMappingURL=Application.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Application.d.ts","names":[],"sources":["../src/Application.ts"],"mappings":";;;;;;;qBAiBa,gBAAc,QAAA;;;;WAQR;;;qBAFN,yBAAyB;;;WAYZ,eAAA,OAAO,aAAa,kBAAkB,MAAM;WACnD,SAAC,MAAM,KAAK,wBAAwB,OAAO;WAC3C,SAAC,SAAS,OAAO,iBAAiB,OAAO;;;qBAN/C,oBAAoB;;qBAWpB,UAAQ,MAAA,MAAA,OAAA,0CAAA,aAAA,aAAA,eAAA,UAAA,YAAA,aAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { ProtocolStdio } from "./internal/protocolOutput.js";
|
|
3
|
+
import { Context, Effect, Layer, Option, Schema, Stdio } from "effect";
|
|
4
|
+
import { NodeServices } from "@effect/platform-node";
|
|
5
|
+
import { Digest, SecureRandom, Signature } from "effect/crypto";
|
|
6
|
+
import { FetchHttpClient } from "effect/http";
|
|
7
|
+
// src/Application.ts
|
|
8
|
+
var Application_exports = /* @__PURE__ */ __exportAll({
|
|
9
|
+
Application: () => Application,
|
|
10
|
+
ApplicationError: () => ApplicationError,
|
|
11
|
+
ProtocolOutput: () => ProtocolOutput,
|
|
12
|
+
platform: () => platform
|
|
13
|
+
});
|
|
14
|
+
/** Set before argument parsing when stdout belongs to a byte protocol. */
|
|
15
|
+
const ProtocolOutput = Context.Reference("@graftland/cli/ProtocolOutput", { defaultValue: () => false });
|
|
16
|
+
/** An application requested a failed process exit, preserving its original cause. */
|
|
17
|
+
var ApplicationError = class extends Schema.TaggedError()("ApplicationError", { cause: Schema.Cause(Schema.Unknown, Schema.Unknown) }) {};
|
|
18
|
+
/** Applications can request process completion and report cleanup independently of loader diagnostics. */
|
|
19
|
+
var Application = class extends Context.Service()("@graftland/cli/Application") {};
|
|
20
|
+
/** Node capabilities shared by application and command hosts. */
|
|
21
|
+
const platform = Layer.mergeAll(Layer.effect(Stdio.Stdio, Effect.gen(function* () {
|
|
22
|
+
const reserved = yield* ProtocolStdio;
|
|
23
|
+
return Option.isSome(reserved) ? reserved.value : yield* Stdio.Stdio;
|
|
24
|
+
})).pipe(Layer.provideMerge(NodeServices.layer)), FetchHttpClient.layer, Digest.layerWebCrypto, SecureRandom.layerWebCrypto, Signature.layerWebCrypto.pipe(Layer.provide(SecureRandom.layerWebCrypto)));
|
|
25
|
+
export { Application, ApplicationError, Application_exports, ProtocolOutput, platform };
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=Application.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Application.js","names":[],"sources":["../src/Application.ts"],"sourcesContent":["import {\n\tContext,\n\tEffect,\n\tExit,\n\tLayer,\n\tOption,\n\tSchema,\n\tScope,\n\tStdio,\n} from \"effect\"\nimport { Digest, SecureRandom, Signature } from \"effect/crypto\"\nimport { FetchHttpClient } from \"effect/http\"\nimport { NodeServices } from \"@effect/platform-node\"\n\nimport { ProtocolStdio } from \"./internal/protocolOutput\"\n\n/** Set before argument parsing when stdout belongs to a byte protocol. */\nexport const ProtocolOutput = Context.Reference(\n\t\"@graftland/cli/ProtocolOutput\",\n\t{ defaultValue: () => false },\n)\n\n/** An application requested a failed process exit, preserving its original cause. */\nexport class ApplicationError extends Schema.TaggedError<\n\tApplicationError,\n\t{ readonly brand: unique symbol }\n>()(\"ApplicationError\", {\n\tcause: Schema.Cause(Schema.Unknown, Schema.Unknown),\n}) {}\n\n/** Applications can request process completion and report cleanup independently of loader diagnostics. */\nexport class Application extends Context.Service<\n\tApplication,\n\t{\n\t\t/** Exclusively reserves the process protocol channel until the caller releases its scope. */\n\t\treadonly claimProtocol: Effect.Effect<void, ApplicationError, Scope.Scope>\n\t\treadonly finish: (exit: Exit.Exit<void, unknown>) => Effect.Effect<void>\n\t\treadonly onExit: (release: Effect.Effect<void>) => Effect.Effect<void>\n\t}\n>()(\"@graftland/cli/Application\") {}\n\n/** Node capabilities shared by application and command hosts. */\nexport const platform = Layer.mergeAll(\n\tLayer.effect(\n\t\tStdio.Stdio,\n\t\tEffect.gen(function* () {\n\t\t\tconst reserved = yield* ProtocolStdio\n\t\t\treturn Option.isSome(reserved) ? reserved.value : yield* Stdio.Stdio\n\t\t}),\n\t).pipe(Layer.provideMerge(NodeServices.layer)),\n\tFetchHttpClient.layer,\n\tDigest.layerWebCrypto,\n\tSecureRandom.layerWebCrypto,\n\tSignature.layerWebCrypto.pipe(Layer.provide(SecureRandom.layerWebCrypto)),\n)\n"],"mappings":";;;;;;;;;;;;;;AAiBA,MAAa,iBAAiB,QAAQ,UACrC,iCACA,EAAE,oBAAoB,MAAM,CAC7B;;AAGA,IAAa,mBAAb,cAAsC,OAAO,YAG3C,CAAC,CAAC,oBAAoB,EACvB,OAAO,OAAO,MAAM,OAAO,SAAS,OAAO,OAAO,EACnD,CAAC,CAAC,CAAC,CAAC;;AAGJ,IAAa,cAAb,cAAiC,QAAQ,QAQvC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC;;AAGnC,MAAa,WAAW,MAAM,SAC7B,MAAM,OACL,MAAM,OACN,OAAO,IAAI,aAAa;CACvB,MAAM,WAAW,OAAO;CACxB,OAAO,OAAO,OAAO,QAAQ,IAAI,SAAS,QAAQ,OAAO,MAAM;AAChE,CAAC,CACF,CAAC,CAAC,KAAK,MAAM,aAAa,aAAa,KAAK,CAAC,GAC7C,gBAAgB,OAChB,OAAO,gBACP,aAAa,gBACb,UAAU,eAAe,KAAK,MAAM,QAAQ,aAAa,cAAc,CAAC,CACzE"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Context, Effect, Schema, Scope } from "effect";
|
|
2
|
+
import { CliError, Command } from "effect/cli";
|
|
3
|
+
declare namespace Commands_d_exports {
|
|
4
|
+
export { CommandConfigError, CommandRegistrationError, Commands, Environment };
|
|
5
|
+
}
|
|
6
|
+
/** Services available when a registered command runs. Provide other services on the command itself. */
|
|
7
|
+
export type Environment = Command.Environment | Scope.Scope;
|
|
8
|
+
declare const CommandRegistrationError_base: Schema.Class<CommandRegistrationError, Schema.TaggedStruct<"CommandRegistrationError", {
|
|
9
|
+
readonly command: Schema.String;
|
|
10
|
+
readonly detail: Schema.String;
|
|
11
|
+
}>, import("effect/Cause").YieldableError & {
|
|
12
|
+
readonly brand: unique symbol;
|
|
13
|
+
}>;
|
|
14
|
+
/** A command name, alias, or registration lifetime conflicts with the host. */
|
|
15
|
+
export declare class CommandRegistrationError extends CommandRegistrationError_base {
|
|
16
|
+
get message(): string;
|
|
17
|
+
}
|
|
18
|
+
declare const Commands_base: Context.ServiceClass<Commands, "@graftland/cli/Commands", {
|
|
19
|
+
readonly register: <const Name extends string, Input, ContextInput, E extends CliError.CliError, R extends Environment>(command: Command.Command<Name, Input, ContextInput, E, R>) => Effect.Effect<void, CommandRegistrationError, Scope.Scope>;
|
|
20
|
+
}>;
|
|
21
|
+
/** Register one native Effect CLI command tree during the plugin's activation. */
|
|
22
|
+
export declare class Commands extends Commands_base {}
|
|
23
|
+
declare const CommandConfigError_base: Schema.Class<CommandConfigError, Schema.TaggedStruct<"CommandConfigError", {
|
|
24
|
+
readonly file: Schema.String;
|
|
25
|
+
readonly cause: Schema.Unknown;
|
|
26
|
+
}>, import("effect/Cause").YieldableError & {
|
|
27
|
+
readonly brand: unique symbol;
|
|
28
|
+
}>;
|
|
29
|
+
/** A declared command plugin could not be decoded from its config file. */
|
|
30
|
+
export declare class CommandConfigError extends CommandConfigError_base {
|
|
31
|
+
get message(): string;
|
|
32
|
+
}
|
|
33
|
+
export { Commands_d_exports };
|
|
34
|
+
//# sourceMappingURL=Commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Commands.d.ts","names":[],"sources":["../src/Commands.ts"],"mappings":";;;;;;YAIY,cAAc,QAAQ,cAAc,MAAM;;;;;WAKnC;;;qBAFN,iCAAiC;MAOhC;;;WASO,iBACZ,qBACN,OACA,cACA,UAAU,SAAS,UACnB,UAAU,aAEV,SAAS,QAAQ,QAAQ,MAAM,OAAO,cAAc,GAAG,OACnD,OAAO,aAAa,0BAA0B,MAAM;;;qBAX9C,iBAAiB;;;;;WAkBX;;;qBAFN,2BAA2B;MAO1B"}
|
package/dist/Commands.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { Context, Schema } from "effect";
|
|
3
|
+
// src/Commands.ts
|
|
4
|
+
var Commands_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
CommandConfigError: () => CommandConfigError,
|
|
6
|
+
CommandRegistrationError: () => CommandRegistrationError,
|
|
7
|
+
Commands: () => Commands
|
|
8
|
+
});
|
|
9
|
+
/** A command name, alias, or registration lifetime conflicts with the host. */
|
|
10
|
+
var CommandRegistrationError = class extends Schema.TaggedError()("CommandRegistrationError", {
|
|
11
|
+
command: Schema.String,
|
|
12
|
+
detail: Schema.String
|
|
13
|
+
}) {
|
|
14
|
+
get message() {
|
|
15
|
+
return `${this.command}: ${this.detail}`;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
/** Register one native Effect CLI command tree during the plugin's activation. */
|
|
19
|
+
var Commands = class extends Context.Service()("@graftland/cli/Commands") {};
|
|
20
|
+
/** A declared command plugin could not be decoded from its config file. */
|
|
21
|
+
var CommandConfigError = class extends Schema.TaggedError()("CommandConfigError", {
|
|
22
|
+
file: Schema.String,
|
|
23
|
+
cause: Schema.Unknown
|
|
24
|
+
}) {
|
|
25
|
+
get message() {
|
|
26
|
+
return `Cannot read command plugins from ${this.file}`;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
export { CommandConfigError, CommandRegistrationError, Commands, Commands_exports };
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=Commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Commands.js","names":[],"sources":["../src/Commands.ts"],"sourcesContent":["import { Context, Effect, Schema, Scope } from \"effect\"\nimport type { CliError, Command } from \"effect/cli\"\n\n/** Services available when a registered command runs. Provide other services on the command itself. */\nexport type Environment = Command.Environment | Scope.Scope\n\n/** A command name, alias, or registration lifetime conflicts with the host. */\nexport class CommandRegistrationError extends Schema.TaggedError<\n\tCommandRegistrationError,\n\t{ readonly brand: unique symbol }\n>()(\"CommandRegistrationError\", {\n\tcommand: Schema.String,\n\tdetail: Schema.String,\n}) {\n\toverride get message() {\n\t\treturn `${this.command}: ${this.detail}`\n\t}\n}\n\n/** Register one native Effect CLI command tree during the plugin's activation. */\nexport class Commands extends Context.Service<\n\tCommands,\n\t{\n\t\treadonly register: <\n\t\t\tconst Name extends string,\n\t\t\tInput,\n\t\t\tContextInput,\n\t\t\tE extends CliError.CliError,\n\t\t\tR extends Environment,\n\t\t>(\n\t\t\tcommand: Command.Command<Name, Input, ContextInput, E, R>,\n\t\t) => Effect.Effect<void, CommandRegistrationError, Scope.Scope>\n\t}\n>()(\"@graftland/cli/Commands\") {}\n\n/** A declared command plugin could not be decoded from its config file. */\nexport class CommandConfigError extends Schema.TaggedError<\n\tCommandConfigError,\n\t{ readonly brand: unique symbol }\n>()(\"CommandConfigError\", {\n\tfile: Schema.String,\n\tcause: Schema.Unknown,\n}) {\n\toverride get message() {\n\t\treturn `Cannot read command plugins from ${this.file}`\n\t}\n}\n"],"mappings":";;;;;;;;;AAOA,IAAa,2BAAb,cAA8C,OAAO,YAGnD,CAAC,CAAC,4BAA4B;CAC/B,SAAS,OAAO;CAChB,QAAQ,OAAO;AAChB,CAAC,CAAC,CAAC;CACF,IAAa,UAAU;EACtB,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK;CACjC;AACD;;AAGA,IAAa,WAAb,cAA8B,QAAQ,QAapC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC;;AAGhC,IAAa,qBAAb,cAAwC,OAAO,YAG7C,CAAC,CAAC,sBAAsB;CACzB,MAAM,OAAO;CACb,OAAO,OAAO;AACf,CAAC,CAAC,CAAC;CACF,IAAa,UAAU;EACtB,OAAO,oCAAoC,KAAK;CACjD;AACD"}
|
package/dist/Manage.d.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
+
import { CommandConfigError } from "./Commands.js";
|
|
2
|
+
import { Config, Effect, FileSystem, Option, Path } from "effect";
|
|
1
3
|
import * as Create from "@graftland/create";
|
|
2
4
|
import * as PackageManager from "@graftland/package-manager";
|
|
3
|
-
import { Config, Effect, Option } from "effect";
|
|
4
5
|
declare namespace Manage_d_exports {
|
|
5
|
-
export { add, create, remove };
|
|
6
|
+
export { add, addPlugin, create, remove };
|
|
6
7
|
}
|
|
7
8
|
export declare const create: (options: {
|
|
8
9
|
readonly directory: string;
|
|
9
10
|
readonly name: Option.Option<string>;
|
|
10
11
|
readonly install: boolean;
|
|
11
|
-
}) => Effect.Effect<void, Config.ConfigError | Create.CreateError | Create.InvalidName | Create.InvalidPackageManager | PackageManager.Error, import("effect/process/ChildProcessSpawner").ChildProcessSpawner |
|
|
12
|
-
export declare const add: (specs: readonly string[]) => Effect.Effect<void, Config.ConfigError | PackageManager.Error, import("effect/process/ChildProcessSpawner").ChildProcessSpawner |
|
|
13
|
-
export declare const remove: (names: ReadonlyArray<string>) => Effect.Effect<void, Config.ConfigError | PackageManager.Error, import("effect/process/ChildProcessSpawner").ChildProcessSpawner |
|
|
12
|
+
}) => Effect.Effect<void, Config.ConfigError | Create.CreateError | Create.InvalidName | Create.InvalidPackageManager | PackageManager.Error, import("effect/process/ChildProcessSpawner").ChildProcessSpawner | FileSystem.FileSystem | Path.Path>;
|
|
13
|
+
export declare const add: (specs: readonly string[]) => Effect.Effect<void, Config.ConfigError | PackageManager.Error, import("effect/process/ChildProcessSpawner").ChildProcessSpawner | FileSystem.FileSystem | Path.Path>;
|
|
14
|
+
export declare const remove: (names: ReadonlyArray<string>) => Effect.Effect<void, Config.ConfigError | PackageManager.Error, import("effect/process/ChildProcessSpawner").ChildProcessSpawner | FileSystem.FileSystem | Path.Path>;
|
|
15
|
+
/** Install a command plugin and explicitly enable its /cli entry. */
|
|
16
|
+
export declare const addPlugin: (name: string, global?: boolean | undefined) => Effect.Effect<void, CommandConfigError | Config.ConfigError | PackageManager.Error, import("effect/process/ChildProcessSpawner").ChildProcessSpawner | FileSystem.FileSystem | Path.Path>;
|
|
14
17
|
export { Manage_d_exports };
|
|
15
18
|
//# sourceMappingURL=Manage.d.ts.map
|
package/dist/Manage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Manage.d.ts","names":[],"sources":["../src/Manage.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Manage.d.ts","names":[],"sources":["../src/Manage.ts"],"mappings":";;;;;;;qBAqEa,SAAM;WACE;WACL,MAAA,OAAO;WACJ;MAWjB,OAAA,aAAA,OAAA,cAAA,OAAA,cAAA,OAAA,cAAA,OAAA,wBAAA,eAAA,oDAAA,sBAAA,WAAA,aAAA,KAAA;qBAEW,MAAG,6BAAA,OAAA,aAAA,OAAA,cAAA,eAAA,oDAAA,sBAAA,WAAA,aAAA,KAAA;qBAgBH,SAAM,OAAW,0BAAqB,OAAA,aAAA,OAAA,cAAA,eAAA,oDAAA,sBAAA,WAAA,aAAA,KAAA;;qBAuDtC,YAAS,cAAA,iCAAA,OAAA,aAAA,qBAAA,OAAA,cAAA,eAAA,oDAAA,sBAAA,WAAA,aAAA,KAAA"}
|
package/dist/Manage.js
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { CommandConfigError } from "./Commands.js";
|
|
3
|
+
import { home } from "./internal/commandConfig.js";
|
|
4
|
+
import { Array, Config, Effect, FileSystem, Option, Path, Predicate, Record, Schema, String } from "effect";
|
|
2
5
|
import * as Create from "@graftland/create";
|
|
3
6
|
import * as PackageManager from "@graftland/package-manager";
|
|
4
|
-
import {
|
|
7
|
+
import { parseDocument } from "yaml";
|
|
5
8
|
// src/Manage.ts
|
|
6
9
|
/**
|
|
7
10
|
* Creating projects and changing their dependencies.
|
|
8
11
|
*/
|
|
9
12
|
var Manage_exports = /* @__PURE__ */ __exportAll({
|
|
10
13
|
add: () => add,
|
|
14
|
+
addPlugin: () => addPlugin,
|
|
11
15
|
create: () => create,
|
|
12
16
|
remove: () => remove
|
|
13
17
|
});
|
|
@@ -50,6 +54,60 @@ const add = Effect.fn("Manage.add")(function* (specs) {
|
|
|
50
54
|
yield* install(".", Record.fromEntries(Array.map(decoded, (spec) => Predicate.isString(spec) ? [spec, "latest"] : [spec[0], spec[2]])));
|
|
51
55
|
});
|
|
52
56
|
const remove = (names) => install(".", Record.fromEntries(Array.map(names, (name) => [name, null])));
|
|
53
|
-
|
|
57
|
+
const enabledConfig = Effect.fnUntraced(function* (file, module) {
|
|
58
|
+
const fs = yield* FileSystem.FileSystem;
|
|
59
|
+
const text = (yield* fs.exists(file)) ? yield* fs.readFileString(file) : "[]\n";
|
|
60
|
+
const document = yield* Effect.try({
|
|
61
|
+
try: () => {
|
|
62
|
+
const document = parseDocument(text);
|
|
63
|
+
const error = document.errors[0];
|
|
64
|
+
if (error !== void 0) throw error;
|
|
65
|
+
if (document.toJS() === null) document.contents = document.createNode([]);
|
|
66
|
+
return document;
|
|
67
|
+
},
|
|
68
|
+
catch: (cause) => CommandConfigError.make({
|
|
69
|
+
file,
|
|
70
|
+
cause
|
|
71
|
+
})
|
|
72
|
+
});
|
|
73
|
+
const entries = yield* Schema.decodeUnknownEffect(Schema.Array(Schema.Unknown))(document.toJS());
|
|
74
|
+
const existing = Array.findFirstIndex(entries, (entry) => Predicate.hasProperty(entry, "name") && entry.name === module && Predicate.hasProperty(entry, "cli") && entry.cli === true);
|
|
75
|
+
return yield* Effect.try({
|
|
76
|
+
try: () => {
|
|
77
|
+
if (Option.isSome(existing)) document.setIn([existing.value, "disabled"], false);
|
|
78
|
+
else document.add({
|
|
79
|
+
name: module,
|
|
80
|
+
cli: true
|
|
81
|
+
});
|
|
82
|
+
return document.toString();
|
|
83
|
+
},
|
|
84
|
+
catch: (cause) => CommandConfigError.make({
|
|
85
|
+
file,
|
|
86
|
+
cause
|
|
87
|
+
})
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
const prepareHome = Effect.fnUntraced(function* (directory) {
|
|
91
|
+
const fs = yield* FileSystem.FileSystem;
|
|
92
|
+
const path = yield* Path.Path;
|
|
93
|
+
yield* fs.makeDirectory(directory, { recursive: true });
|
|
94
|
+
const manifest = path.join(directory, "package.json");
|
|
95
|
+
if (!(yield* fs.exists(manifest))) yield* fs.writeFileString(manifest, "{\"private\":true,\"type\":\"module\"}\n");
|
|
96
|
+
}, Effect.uninterruptible);
|
|
97
|
+
/** Install a command plugin and explicitly enable its /cli entry. */
|
|
98
|
+
const addPlugin = Effect.fn("Manage.addPlugin")(function* (name, global = false) {
|
|
99
|
+
const path = yield* Path.Path;
|
|
100
|
+
const fs = yield* FileSystem.FileSystem;
|
|
101
|
+
const directory = global ? yield* home : path.resolve(".");
|
|
102
|
+
const packageName = String.startsWith("@")(name) || String.startsWith("graft-plugin-")(name) ? name : `@graftland/plugin-${name}`;
|
|
103
|
+
const module = `${packageName}/cli`;
|
|
104
|
+
const file = path.join(directory, "graft.yml");
|
|
105
|
+
const text = yield* enabledConfig(file, module);
|
|
106
|
+
if (global) yield* prepareHome(directory);
|
|
107
|
+
yield* install(directory, Record.singleton(packageName, "latest"));
|
|
108
|
+
yield* fs.writeFileString(file, text).pipe(Effect.uninterruptible);
|
|
109
|
+
yield* Effect.logInfo(`Enabled ${module} in ${file}`);
|
|
110
|
+
});
|
|
111
|
+
export { Manage_exports, add, addPlugin, create, remove };
|
|
54
112
|
|
|
55
113
|
//# sourceMappingURL=Manage.js.map
|
package/dist/Manage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Manage.js","names":[],"sources":["../src/Manage.ts"],"sourcesContent":["/**\n * Creating projects and changing their dependencies.\n */\nimport * as Create from \"@graftland/create\"\nimport * as PackageManager from \"@graftland/package-manager\"\nimport {\
|
|
1
|
+
{"version":3,"file":"Manage.js","names":[],"sources":["../src/Manage.ts"],"sourcesContent":["/**\n * Creating projects and changing their dependencies.\n */\nimport {\n\tArray,\n\tConfig,\n\tEffect,\n\tFileSystem,\n\tOption,\n\tPath,\n\tPredicate,\n\tRecord,\n\tSchema,\n\tString,\n} from \"effect\"\n\nimport * as Create from \"@graftland/create\"\nimport * as PackageManager from \"@graftland/package-manager\"\n\nimport { parseDocument, type Document } from \"yaml\"\n\nimport { CommandConfigError } from \"./Commands\"\nimport { home } from \"./internal/commandConfig\"\n\nconst report = (result: PackageManager.InstallResult) =>\n\tEffect.logInfo(\n\t\t`${result.agent}: ${result.added.length} added, ${result.updated.length} updated, ${result.removed.length} removed`,\n\t).pipe(\n\t\tEffect.andThen(\n\t\t\tOption.match(result.snapshotCleanupFailure, {\n\t\t\t\tonNone: () => Effect.void,\n\t\t\t\tonSome: ({ cause, snapshotDirectory }) =>\n\t\t\t\t\tEffect.logWarning(\n\t\t\t\t\t\t\"Installation committed; snapshot cleanup failed. Retry removing the retained snapshot.\",\n\t\t\t\t\t\tcause,\n\t\t\t\t\t\t{ snapshotDirectory },\n\t\t\t\t\t),\n\t\t\t}),\n\t\t),\n\t)\n\n/**\n * `name@range`, split at the last `@` so a scope's `@` stays in the name. A\n * bare name means the latest version.\n */\nconst Spec = Schema.Union([\n\tSchema.TemplateLiteralParser([\n\t\tPackageManager.PackageName,\n\t\t\"@\",\n\t\tSchema.String,\n\t]),\n\tPackageManager.PackageName,\n])\nconst decodeSpecs = Schema.decodeEffect(Schema.Array(Spec))\n\nconst install = Effect.fn(\"Manage.install\")(function* (\n\tdirectory: string,\n\tchanges: Readonly<Record<string, string | null>>,\n) {\n\tconst decoded = yield* Schema.decodeEffect(PackageManager.Changes)(changes)\n\t// Set by npm, pnpm and Yarn when they run graft, such as through `pnpm dlx`.\n\tconst userAgent = yield* Config.String(\"npm_config_user_agent\").pipe(\n\t\tConfig.withDefault(\"\"),\n\t)\n\tconst manager = yield* PackageManager.make({ directory, userAgent })\n\tconst result = yield* manager.install(decoded)\n\tyield* report(result)\n})\n\nexport const create = Effect.fn(\"Manage.create\")(function* (options: {\n\treadonly directory: string\n\treadonly name: Option.Option<string>\n\treadonly install: boolean\n}) {\n\tconst project = yield* Create.create({\n\t\tdirectory: options.directory,\n\t\t...Option.match(options.name, {\n\t\t\tonNone: () => ({}),\n\t\t\tonSome: (name) => ({ name }),\n\t\t}),\n\t})\n\tyield* Effect.logInfo(`Created ${project.name} in ${project.directory}`)\n\tif (options.install) yield* install(project.directory, {})\n})\n\nexport const add = Effect.fn(\"Manage.add\")(function* (\n\tspecs: ReadonlyArray<string>,\n) {\n\tconst decoded = yield* decodeSpecs(specs)\n\tyield* install(\n\t\t\".\",\n\t\tRecord.fromEntries(\n\t\t\tArray.map(decoded, (spec) =>\n\t\t\t\tPredicate.isString(spec)\n\t\t\t\t\t? ([spec, \"latest\"] as const)\n\t\t\t\t\t: ([spec[0], spec[2]] as const),\n\t\t\t),\n\t\t),\n\t)\n})\n\nexport const remove = (names: ReadonlyArray<string>) =>\n\tinstall(\n\t\t\".\",\n\t\tRecord.fromEntries(Array.map(names, (name) => [name, null] as const)),\n\t)\n\nconst enabledConfig = Effect.fnUntraced(function* (\n\tfile: string,\n\tmodule: string,\n) {\n\tconst fs = yield* FileSystem.FileSystem\n\tconst text = (yield* fs.exists(file))\n\t\t? yield* fs.readFileString(file)\n\t\t: \"[]\\n\"\n\tconst document = yield* Effect.try({\n\t\ttry: () => {\n\t\t\tconst document: Document = parseDocument(text)\n\t\t\tconst error = document.errors[0]\n\t\t\tif (error !== undefined) throw error\n\t\t\tif (document.toJS() === null) document.contents = document.createNode([])\n\t\t\treturn document\n\t\t},\n\t\tcatch: (cause) => CommandConfigError.make({ file, cause }),\n\t})\n\tconst entries = yield* Schema.decodeUnknownEffect(\n\t\tSchema.Array(Schema.Unknown),\n\t)(document.toJS())\n\tconst existing = Array.findFirstIndex(\n\t\tentries,\n\t\t(entry) =>\n\t\t\tPredicate.hasProperty(entry, \"name\") &&\n\t\t\tentry.name === module &&\n\t\t\tPredicate.hasProperty(entry, \"cli\") &&\n\t\t\tentry.cli === true,\n\t)\n\treturn yield* Effect.try({\n\t\ttry: () => {\n\t\t\tif (Option.isSome(existing))\n\t\t\t\tdocument.setIn([existing.value, \"disabled\"], false)\n\t\t\telse document.add({ name: module, cli: true })\n\t\t\treturn document.toString()\n\t\t},\n\t\tcatch: (cause) => CommandConfigError.make({ file, cause }),\n\t})\n})\nconst prepareHome = Effect.fnUntraced(function* (directory: string) {\n\tconst fs = yield* FileSystem.FileSystem\n\tconst path = yield* Path.Path\n\tyield* fs.makeDirectory(directory, { recursive: true })\n\tconst manifest = path.join(directory, \"package.json\")\n\tif (!(yield* fs.exists(manifest)))\n\t\tyield* fs.writeFileString(manifest, '{\"private\":true,\"type\":\"module\"}\\n')\n}, Effect.uninterruptible)\n\n/** Install a command plugin and explicitly enable its /cli entry. */\nexport const addPlugin = Effect.fn(\"Manage.addPlugin\")(function* (\n\tname: string,\n\tglobal: boolean = false,\n) {\n\tconst path = yield* Path.Path\n\tconst fs = yield* FileSystem.FileSystem\n\tconst directory = global ? yield* home : path.resolve(\".\")\n\tconst packageName =\n\t\tString.startsWith(\"@\")(name) || String.startsWith(\"graft-plugin-\")(name)\n\t\t\t? name\n\t\t\t: `@graftland/plugin-${name}`\n\tconst module = `${packageName}/cli`\n\tconst file = path.join(directory, \"graft.yml\")\n\tconst text = yield* enabledConfig(file, module)\n\tif (global) yield* prepareHome(directory)\n\tyield* install(directory, Record.singleton(packageName, \"latest\"))\n\t// Once accepted, the native write must finish before command cleanup can proceed.\n\tyield* fs.writeFileString(file, text).pipe(Effect.uninterruptible)\n\tyield* Effect.logInfo(`Enabled ${module} in ${file}`)\n})\n"],"mappings":"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"}
|
package/dist/Start.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ApplicationError } from "./Application.js";
|
|
1
2
|
import { Effect, PlatformError, Schema } from "effect";
|
|
2
3
|
import { Graft } from "@graftland/graft";
|
|
3
4
|
import { Loader, Tree } from "@graftland/loader";
|
|
@@ -20,6 +21,6 @@ export interface Options {
|
|
|
20
21
|
* modules are imported through the hot reloader, so bare specifiers resolve
|
|
21
22
|
* from the application directory whether or not `watch` is on.
|
|
22
23
|
*/
|
|
23
|
-
export declare const run: (options: Options) => Effect.Effect<
|
|
24
|
+
export declare const run: (options: Options) => Effect.Effect<void, ApplicationError | Graft.ServiceConflict | PlatformError.BadArgument | PlatformError.PlatformError | Schema.SchemaError | Loader.StoreError | Tree.InvalidOperation>;
|
|
24
25
|
export { Start_d_exports };
|
|
25
26
|
//# sourceMappingURL=Start.d.ts.map
|
package/dist/Start.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Start.d.ts","names":[],"sources":["../src/Start.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Start.d.ts","names":[],"sources":["../src/Start.ts"],"mappings":";;;;;;;iBAoCiB;;WAEP;;WAEA;;;;;WAKA;;;;;;;qBAQG,MAAG,SACN,YACP,OAAO,aAEP,mBACA,MAAM,kBACN,cAAc,cACd,cAAc,gBACd,OAAO,cACP,OAAO,aACP,KAAK"}
|
package/dist/Start.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { Application, ApplicationError, platform } from "./Application.js";
|
|
2
3
|
import { EnvFile, layer, watchEnvFile } from "./internal/env.js";
|
|
3
4
|
import { layer as layer$1 } from "./internal/intercepts.js";
|
|
4
5
|
import { watchModules } from "./internal/watch.js";
|
|
5
|
-
import { Effect, FileSystem, Layer, Logger, Path } from "effect";
|
|
6
|
+
import { Array, Cause, Deferred, Effect, Exit, FileSystem, Layer, Logger, Option, Path, Scope, Semaphore } from "effect";
|
|
6
7
|
import { NodeServices } from "@effect/platform-node";
|
|
7
|
-
import { SecureRandom } from "effect/crypto";
|
|
8
8
|
import { Graft, Plugin } from "@graftland/graft";
|
|
9
9
|
import * as Hmr from "@graftland/hmr";
|
|
10
|
-
import { Include, Loader, ModuleResolver } from "@graftland/loader";
|
|
10
|
+
import { Entry, Include, Loader, ModuleResolver } from "@graftland/loader";
|
|
11
11
|
// src/Start.ts
|
|
12
12
|
/**
|
|
13
13
|
* Runs a Graft application from its config file.
|
|
@@ -18,7 +18,15 @@ var Start_exports = /* @__PURE__ */ __exportAll({ run: () => run });
|
|
|
18
18
|
* modules are imported through the hot reloader, so bare specifiers resolve
|
|
19
19
|
* from the application directory whether or not `watch` is on.
|
|
20
20
|
*/
|
|
21
|
-
const run = Effect.
|
|
21
|
+
const run = (options) => Effect.gen(function* () {
|
|
22
|
+
const scope = yield* Effect.scope;
|
|
23
|
+
const done = yield* Deferred.make();
|
|
24
|
+
const protocol = yield* Semaphore.make(1);
|
|
25
|
+
yield* Graft.provide(Application, {
|
|
26
|
+
claimProtocol: Effect.acquireRelease(protocol.takeIfAvailable(1).pipe(Effect.flatMap((acquired) => acquired ? Effect.void : Effect.fail(ApplicationError.make({ cause: Cause.fail("Only one runner may own the process stdio channel") })))), () => protocol.release(1)),
|
|
27
|
+
finish: (exit) => Deferred.done(done, Exit.isFailure(exit) ? Exit.fail(ApplicationError.make({ cause: exit.cause })) : Exit.void).pipe(Effect.asVoid),
|
|
28
|
+
onExit: (release) => Scope.addFinalizer(scope, release)
|
|
29
|
+
});
|
|
22
30
|
const path = yield* Path.Path;
|
|
23
31
|
const file = path.resolve(options.config);
|
|
24
32
|
const directory = path.dirname(file);
|
|
@@ -30,16 +38,24 @@ const run = Effect.fn("Start.run")(function* (options) {
|
|
|
30
38
|
});
|
|
31
39
|
const modules = yield* ModuleResolver.make({
|
|
32
40
|
base: directory,
|
|
33
|
-
importer: hmr.importModule
|
|
41
|
+
importer: options.watch ? hmr.importModuleScoped : hmr.importModule
|
|
34
42
|
});
|
|
35
43
|
yield* Graft.provide(ModuleResolver.ModuleResolver, {
|
|
36
44
|
resolve: resolver.resolve,
|
|
37
45
|
importModule: modules.importModule
|
|
38
46
|
});
|
|
47
|
+
const fs = yield* FileSystem.FileSystem;
|
|
48
|
+
const observe = hmr.observation.pipe(Effect.provideService(FileSystem.FileSystem, fs), Effect.map((source) => ({
|
|
49
|
+
...source,
|
|
50
|
+
watch: (files, activation) => source.watch(files, activation).pipe(Effect.mapError((cause) => ModuleResolver.ModuleInvalid.make({
|
|
51
|
+
specifier: Array.join(files, ", "),
|
|
52
|
+
cause
|
|
53
|
+
})))
|
|
54
|
+
})));
|
|
39
55
|
yield* (yield* Graft.plugin(Include.Include, {
|
|
40
56
|
path: file,
|
|
41
57
|
watch: options.watch
|
|
42
|
-
})).await;
|
|
58
|
+
}).pipe(Effect.provideService(ModuleResolver.Watch, options.watch ? Option.some(observe) : Option.none()))).await;
|
|
43
59
|
if (options.watch) {
|
|
44
60
|
const { reload } = yield* EnvFile;
|
|
45
61
|
const envFile = options.envFile;
|
|
@@ -50,7 +66,7 @@ const run = Effect.fn("Start.run")(function* (options) {
|
|
|
50
66
|
FileSystem.FileSystem,
|
|
51
67
|
Path.Path
|
|
52
68
|
],
|
|
53
|
-
apply: Effect.
|
|
69
|
+
apply: () => Effect.gen(function* () {
|
|
54
70
|
const loader = yield* Loader.Loader;
|
|
55
71
|
yield* watchModules(hmr, directory, loader.retry).pipe(Effect.forkScoped);
|
|
56
72
|
if (envFile !== void 0) yield* watchEnvFile(envFile, reload, loader.retry).pipe(Effect.forkScoped);
|
|
@@ -59,8 +75,8 @@ const run = Effect.fn("Start.run")(function* (options) {
|
|
|
59
75
|
yield* Graft.plugin(reloader);
|
|
60
76
|
}
|
|
61
77
|
yield* Effect.logInfo(`Running ${path.relative(process.cwd(), file) || file}`);
|
|
62
|
-
return yield*
|
|
63
|
-
}
|
|
78
|
+
return yield* Deferred.await(done);
|
|
79
|
+
}).pipe(Effect.scoped, Effect.provideService(Entry.Select, (entry) => entry["cli"] !== true), Effect.provide(Layer.provideMerge(Graft.layer, Layer.mergeAll(platform, layer$1, layer(options.envFile).pipe(Layer.provide(NodeServices.layer)), Logger.layer([Logger.consolePretty()])))));
|
|
64
80
|
export { Start_exports, run };
|
|
65
81
|
|
|
66
82
|
//# sourceMappingURL=Start.js.map
|
package/dist/Start.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Start.js","names":["intercepts","env"],"sources":["../src/Start.ts"],"sourcesContent":["/**\n * Runs a Graft application from its config file.\n */\nimport {
|
|
1
|
+
{"version":3,"file":"Start.js","names":["intercepts","env"],"sources":["../src/Start.ts"],"sourcesContent":["/**\n * Runs a Graft application from its config file.\n */\nimport {\n\tArray,\n\tCause,\n\tDeferred,\n\tEffect,\n\tExit,\n\tFileSystem,\n\tLayer,\n\tLogger,\n\tOption,\n\tPath,\n\tScope,\n\tSemaphore,\n\ttype PlatformError,\n\ttype Schema,\n} from \"effect\"\nimport { NodeServices } from \"@effect/platform-node\"\n\nimport { Graft, Plugin } from \"@graftland/graft\"\nimport * as Hmr from \"@graftland/hmr\"\nimport {\n\tEntry,\n\tInclude,\n\tLoader,\n\tModuleResolver,\n\ttype Tree,\n} from \"@graftland/loader\"\n\nimport { Application, ApplicationError, platform } from \"./Application\"\nimport { layer as env, EnvFile, watchEnvFile } from \"./internal/env\"\nimport { layer as intercepts } from \"./internal/intercepts\"\nimport { watchModules } from \"./internal/watch\"\n\nexport interface Options {\n\t/** Path of the config file. */\n\treadonly config: string\n\t/** Reload plugin modules and the config file when they change. */\n\treadonly watch: boolean\n\t/**\n\t * A `.env` file that `!env` reads when the process environment does not set\n\t * a variable. With `watch`, changes to it are read again.\n\t */\n\treadonly envFile?: string | undefined\n}\n\n/**\n * Loads the entries of the config file and runs until interrupted. Plugin\n * modules are imported through the hot reloader, so bare specifiers resolve\n * from the application directory whether or not `watch` is on.\n */\nexport const run = (\n\toptions: Options,\n): Effect.Effect<\n\tvoid,\n\t| ApplicationError\n\t| Graft.ServiceConflict\n\t| PlatformError.BadArgument\n\t| PlatformError.PlatformError\n\t| Schema.SchemaError\n\t| Loader.StoreError\n\t| Tree.InvalidOperation\n> =>\n\tEffect.gen(function* () {\n\t\tconst scope = yield* Effect.scope\n\t\tconst done = yield* Deferred.make<void, ApplicationError>()\n\t\tconst protocol = yield* Semaphore.make(1)\n\t\tyield* Graft.provide(Application, {\n\t\t\tclaimProtocol: Effect.acquireRelease(\n\t\t\t\tprotocol.takeIfAvailable(1).pipe(\n\t\t\t\t\tEffect.flatMap((acquired) =>\n\t\t\t\t\t\tacquired\n\t\t\t\t\t\t\t? Effect.void\n\t\t\t\t\t\t\t: Effect.fail(\n\t\t\t\t\t\t\t\t\tApplicationError.make({\n\t\t\t\t\t\t\t\t\t\tcause: Cause.fail(\n\t\t\t\t\t\t\t\t\t\t\t\"Only one runner may own the process stdio channel\",\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t() => protocol.release(1),\n\t\t\t),\n\t\t\tfinish: (exit) =>\n\t\t\t\tDeferred.done(\n\t\t\t\t\tdone,\n\t\t\t\t\tExit.isFailure(exit)\n\t\t\t\t\t\t? Exit.fail(ApplicationError.make({ cause: exit.cause }))\n\t\t\t\t\t\t: Exit.void,\n\t\t\t\t).pipe(Effect.asVoid),\n\t\t\tonExit: (release) => Scope.addFinalizer(scope, release),\n\t\t})\n\t\tconst path = yield* Path.Path\n\t\tconst file = path.resolve(options.config)\n\t\tconst directory = path.dirname(file)\n\t\tconst base = yield* path.toFileUrl(file)\n\t\tconst hmr = yield* Hmr.make({ base: base.href })\n\t\tconst resolver = yield* ModuleResolver.make({\n\t\t\tbase: directory,\n\t\t\timporter: hmr.importerScoped,\n\t\t})\n\t\tconst modules = yield* ModuleResolver.make({\n\t\t\tbase: directory,\n\t\t\timporter: options.watch ? hmr.importModuleScoped : hmr.importModule,\n\t\t})\n\t\tyield* Graft.provide(ModuleResolver.ModuleResolver, {\n\t\t\tresolve: resolver.resolve,\n\t\t\timportModule: modules.importModule,\n\t\t})\n\t\tconst fs = yield* FileSystem.FileSystem\n\t\tconst observe = hmr.observation.pipe(\n\t\t\tEffect.provideService(FileSystem.FileSystem, fs),\n\t\t\tEffect.map((source) => ({\n\t\t\t\t...source,\n\t\t\t\twatch: (files: ReadonlyArray<string>, activation: Scope.Scope) =>\n\t\t\t\t\tsource.watch(files, activation).pipe(\n\t\t\t\t\t\tEffect.mapError((cause) =>\n\t\t\t\t\t\t\tModuleResolver.ModuleInvalid.make({\n\t\t\t\t\t\t\t\tspecifier: Array.join(files, \", \"),\n\t\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t})),\n\t\t)\n\t\tconst included = yield* Graft.plugin(Include.Include, {\n\t\t\tpath: file,\n\t\t\twatch: options.watch,\n\t\t}).pipe(\n\t\t\tEffect.provideService(\n\t\t\t\tModuleResolver.Watch,\n\t\t\t\toptions.watch ? Option.some(observe) : Option.none(),\n\t\t\t),\n\t\t)\n\t\tyield* included.await\n\t\tif (options.watch) {\n\t\t\tconst { reload } = yield* EnvFile\n\t\t\tconst envFile = options.envFile\n\t\t\tconst reloader = Plugin.make({\n\t\t\t\tname: \"reloader\",\n\t\t\t\tinject: [Loader.Loader, FileSystem.FileSystem, Path.Path],\n\t\t\t\tapply: () =>\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst loader = yield* Loader.Loader\n\t\t\t\t\t\tyield* watchModules(hmr, directory, loader.retry).pipe(\n\t\t\t\t\t\t\tEffect.forkScoped,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tif (envFile !== undefined)\n\t\t\t\t\t\t\tyield* watchEnvFile(envFile, reload, loader.retry).pipe(\n\t\t\t\t\t\t\t\tEffect.forkScoped,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t}),\n\t\t\t})\n\t\t\tyield* Graft.plugin(reloader)\n\t\t}\n\n\t\tyield* Effect.logInfo(\n\t\t\t`Running ${path.relative(process.cwd(), file) || file}`,\n\t\t)\n\t\treturn yield* Deferred.await(done)\n\t}).pipe(\n\t\tEffect.scoped,\n\t\tEffect.provideService(Entry.Select, (entry) => entry[\"cli\"] !== true),\n\t\t// @effect-diagnostics-next-line strictEffectProvide:off -- this runs the whole application, so it is an entry point\n\t\tEffect.provide(\n\t\t\tLayer.provideMerge(\n\t\t\t\tGraft.layer,\n\t\t\t\tLayer.mergeAll(\n\t\t\t\t\tplatform,\n\t\t\t\t\tintercepts,\n\t\t\t\t\tenv(options.envFile).pipe(Layer.provide(NodeServices.layer)),\n\t\t\t\t\tLogger.layer([Logger.consolePretty()]),\n\t\t\t\t),\n\t\t\t),\n\t\t),\n\t)\n"],"mappings":"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"}
|
package/dist/bin.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { version } from "./package.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { platform } from "./Application.js";
|
|
4
|
+
import { output, run } from "./internal/commandHost.js";
|
|
5
|
+
import { Array, Effect, Layer, Logger, Option, Stdio } from "effect";
|
|
6
|
+
import { NodeRuntime } from "@effect/platform-node";
|
|
7
|
+
import { Graft } from "@graftland/graft";
|
|
8
|
+
import { Argument, CliError, Command, Flag } from "effect/cli";
|
|
6
9
|
// src/bin.ts
|
|
7
10
|
/**
|
|
8
11
|
* The `graft` executable. Running this module starts the program.
|
|
@@ -20,15 +23,39 @@ const create = Command.make("create", {
|
|
|
20
23
|
name: Flag.String("name").pipe(Flag.withDescription("Package name; defaults to the directory name"), Flag.optional),
|
|
21
24
|
install: Flag.Boolean("install").pipe(Flag.withDescription("Install dependencies afterwards"), Flag.withDefault(false))
|
|
22
25
|
}, (options) => Effect.promise(() => import("./Manage.js")).pipe(Effect.uninterruptible, Effect.flatMap((Manage) => Manage.create(options)))).pipe(Command.withDescription("Create a new Graft project"));
|
|
23
|
-
const add = Command.make("add", {
|
|
26
|
+
const add = Command.make("add", {
|
|
27
|
+
packages: Argument.variadic(Argument.String("package")),
|
|
28
|
+
plugin: Flag.String("plugin").pipe(Flag.optional),
|
|
29
|
+
global: Flag.Boolean("global").pipe(Flag.withDefault(false))
|
|
30
|
+
}, Effect.fnUntraced(function* ({ packages, plugin, global }) {
|
|
31
|
+
if (global && Option.isNone(plugin) || Option.isSome(plugin) && packages.length > 0) return yield* CliError.UserError.make({
|
|
32
|
+
cause: "Conflicting install options",
|
|
33
|
+
userMessage: "Use add --plugin <name> [--global] without package arguments"
|
|
34
|
+
});
|
|
35
|
+
const Manage = yield* Effect.promise(() => import("./Manage.js")).pipe(Effect.uninterruptible);
|
|
36
|
+
return yield* Option.isSome(plugin) ? Manage.addPlugin(plugin.value, global) : Manage.add(packages);
|
|
37
|
+
})).pipe(Command.withDescription("Add dependencies, restoring the project if installing fails"));
|
|
24
38
|
const remove = Command.make("remove", { packages: Argument.variadic(Argument.String("package")) }, ({ packages }) => Effect.promise(() => import("./Manage.js")).pipe(Effect.uninterruptible, Effect.flatMap((Manage) => Manage.remove(packages)))).pipe(Command.withDescription("Remove dependencies, restoring the project if installing fails"));
|
|
25
|
-
const graft = Command.make("graft").pipe(Command.withDescription("Run and manage Graft applications"), Command.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
const graft = Command.make("graft").pipe(Command.withDescription("Run and manage Graft applications"), Command.withSharedFlags({
|
|
40
|
+
stdio: Flag.Boolean("stdio").pipe(Flag.withDefault(false)),
|
|
41
|
+
noPlugins: Flag.Boolean("no-plugins").pipe(Flag.withDefault(false))
|
|
42
|
+
}));
|
|
43
|
+
const program = Effect.gen(function* () {
|
|
44
|
+
const args = yield* (yield* Stdio.Stdio).args;
|
|
45
|
+
return yield* output(Effect.scoped(Effect.gen(function* () {
|
|
46
|
+
const context = yield* Layer.build(Graft.layer);
|
|
47
|
+
return yield* run([
|
|
48
|
+
start,
|
|
49
|
+
create,
|
|
50
|
+
add,
|
|
51
|
+
remove
|
|
52
|
+
], graft, version, args).pipe(Effect.provideContext(context));
|
|
53
|
+
})), args);
|
|
54
|
+
});
|
|
55
|
+
NodeRuntime.runMain(Effect.scoped(Effect.gen(function* () {
|
|
56
|
+
const context = yield* Layer.build(platform);
|
|
57
|
+
return yield* program.pipe(Effect.provideContext(context));
|
|
58
|
+
})).pipe((effect) => Effect.withFiber((main) => effect.pipe(Effect.tapCause((cause) => Array.every(cause.reasons, (reason) => reason._tag === "Interrupt" && reason.fiberId === main.id) || Array.every(cause.reasons, (reason) => reason._tag === "Fail" && CliError.isCliError(reason.error)) ? Effect.void : Effect.logError(cause)))), Effect.provideService(Logger.LogToStderr, true)), { disableErrorReporting: true });
|
|
32
59
|
export {};
|
|
33
60
|
|
|
34
61
|
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","names":[],"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * The `graft` executable. Running this module starts the program.\n */\nimport {
|
|
1
|
+
{"version":3,"file":"bin.js","names":["Host.output","Host.run"],"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * The `graft` executable. Running this module starts the program.\n */\nimport { Array, Effect, Layer, Logger, Option, Stdio } from \"effect\"\nimport { Argument, CliError, Command, Flag } from \"effect/cli\"\nimport { NodeRuntime } from \"@effect/platform-node\"\n\nimport { Graft } from \"@graftland/graft\"\n\nimport { version } from \"../package.json\" with { type: \"json\" }\nimport { platform } from \"./Application\"\nimport * as Host from \"./internal/commandHost\"\n\nconst start = Command.make(\n\t\"start\",\n\t{\n\t\tconfig: Argument.String(\"config\").pipe(\n\t\t\tArgument.withDescription(\"Path of the config file\"),\n\t\t\tArgument.withDefault(\"graft.yml\"),\n\t\t),\n\t\twatch: Flag.Boolean(\"watch\").pipe(\n\t\t\tFlag.withAlias(\"w\"),\n\t\t\tFlag.withDescription(\"Reload plugins and config when files change\"),\n\t\t\tFlag.withDefault(false),\n\t\t),\n\t\tenvFile: Flag.String(\"env-file\").pipe(\n\t\t\tFlag.withDescription(\n\t\t\t\t\"Read variables for !env from a .env file; the process environment takes precedence\",\n\t\t\t),\n\t\t\tFlag.optional,\n\t\t),\n\t},\n\t(options) =>\n\t\tEffect.promise(() => import(\"./Start\")).pipe(\n\t\t\tEffect.uninterruptible,\n\t\t\tEffect.flatMap((Start) =>\n\t\t\t\tStart.run({\n\t\t\t\t\t...options,\n\t\t\t\t\tenvFile: Option.getOrUndefined(options.envFile),\n\t\t\t\t}),\n\t\t\t),\n\t\t),\n).pipe(\n\tCommand.withDescription(\"Run the application described by a config file\"),\n)\n\nconst create = Command.make(\n\t\"create\",\n\t{\n\t\tdirectory: Argument.String(\"directory\").pipe(\n\t\t\tArgument.withDescription(\"Where to create the project\"),\n\t\t),\n\t\tname: Flag.String(\"name\").pipe(\n\t\t\tFlag.withDescription(\"Package name; defaults to the directory name\"),\n\t\t\tFlag.optional,\n\t\t),\n\t\tinstall: Flag.Boolean(\"install\").pipe(\n\t\t\tFlag.withDescription(\"Install dependencies afterwards\"),\n\t\t\tFlag.withDefault(false),\n\t\t),\n\t},\n\t(options) =>\n\t\tEffect.promise(() => import(\"./Manage\")).pipe(\n\t\t\tEffect.uninterruptible,\n\t\t\tEffect.flatMap((Manage) => Manage.create(options)),\n\t\t),\n).pipe(Command.withDescription(\"Create a new Graft project\"))\n\nconst add = Command.make(\n\t\"add\",\n\t{\n\t\tpackages: Argument.variadic(Argument.String(\"package\")),\n\t\tplugin: Flag.String(\"plugin\").pipe(Flag.optional),\n\t\tglobal: Flag.Boolean(\"global\").pipe(Flag.withDefault(false)),\n\t},\n\tEffect.fnUntraced(function* ({ packages, plugin, global }) {\n\t\tif (\n\t\t\t(global && Option.isNone(plugin)) ||\n\t\t\t(Option.isSome(plugin) && packages.length > 0)\n\t\t)\n\t\t\treturn yield* CliError.UserError.make({\n\t\t\t\tcause: \"Conflicting install options\",\n\t\t\t\tuserMessage:\n\t\t\t\t\t\"Use add --plugin <name> [--global] without package arguments\",\n\t\t\t})\n\t\tconst Manage = yield* Effect.promise(() => import(\"./Manage\")).pipe(\n\t\t\tEffect.uninterruptible,\n\t\t)\n\t\treturn yield* Option.isSome(plugin)\n\t\t\t? Manage.addPlugin(plugin.value, global)\n\t\t\t: Manage.add(packages)\n\t}),\n).pipe(\n\tCommand.withDescription(\n\t\t\"Add dependencies, restoring the project if installing fails\",\n\t),\n)\n\nconst remove = Command.make(\n\t\"remove\",\n\t{ packages: Argument.variadic(Argument.String(\"package\")) },\n\t({ packages }) =>\n\t\tEffect.promise(() => import(\"./Manage\")).pipe(\n\t\t\tEffect.uninterruptible,\n\t\t\tEffect.flatMap((Manage) => Manage.remove(packages)),\n\t\t),\n).pipe(\n\tCommand.withDescription(\n\t\t\"Remove dependencies, restoring the project if installing fails\",\n\t),\n)\n\nconst graft = Command.make(\"graft\").pipe(\n\tCommand.withDescription(\"Run and manage Graft applications\"),\n\tCommand.withSharedFlags({\n\t\tstdio: Flag.Boolean(\"stdio\").pipe(Flag.withDefault(false)),\n\t\tnoPlugins: Flag.Boolean(\"no-plugins\").pipe(Flag.withDefault(false)),\n\t}),\n)\n\nconst program = Effect.gen(function* () {\n\tconst stdio = yield* Stdio.Stdio\n\tconst args = yield* stdio.args\n\treturn yield* Host.output(\n\t\tEffect.scoped(\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst context = yield* Layer.build(Graft.layer)\n\t\t\t\treturn yield* Host.run(\n\t\t\t\t\t[start, create, add, remove],\n\t\t\t\t\tgraft,\n\t\t\t\t\tversion,\n\t\t\t\t\targs,\n\t\t\t\t).pipe(Effect.provideContext(context))\n\t\t\t}),\n\t\t),\n\t\targs,\n\t)\n})\nNodeRuntime.runMain(\n\tEffect.scoped(\n\t\tEffect.gen(function* () {\n\t\t\tconst context = yield* Layer.build(platform)\n\t\t\treturn yield* program.pipe(Effect.provideContext(context))\n\t\t}),\n\t).pipe(\n\t\t(effect) =>\n\t\t\tEffect.withFiber((main) =>\n\t\t\t\teffect.pipe(\n\t\t\t\t\tEffect.tapCause((cause) =>\n\t\t\t\t\t\tArray.every(\n\t\t\t\t\t\t\tcause.reasons,\n\t\t\t\t\t\t\t(reason) =>\n\t\t\t\t\t\t\t\treason._tag === \"Interrupt\" && reason.fiberId === main.id,\n\t\t\t\t\t\t) ||\n\t\t\t\t\t\tArray.every(\n\t\t\t\t\t\t\tcause.reasons,\n\t\t\t\t\t\t\t(reason) =>\n\t\t\t\t\t\t\t\treason._tag === \"Fail\" && CliError.isCliError(reason.error),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\t? Effect.void\n\t\t\t\t\t\t\t: Effect.logError(cause),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\tEffect.provideService(Logger.LogToStderr, true),\n\t),\n\t{ disableErrorReporting: true },\n)\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { Manage_d_exports } from "./Manage.js";
|
|
2
2
|
import { Start_d_exports } from "./Start.js";
|
|
3
|
-
|
|
3
|
+
import { Commands_d_exports } from "./Commands.js";
|
|
4
|
+
import { Application_d_exports } from "./Application.js";
|
|
5
|
+
export { Application_d_exports as Application, Commands_d_exports as Commands, Manage_d_exports as Manage, Start_d_exports as Start };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { Manage_exports } from "./Manage.js";
|
|
2
2
|
import { Start_exports } from "./Start.js";
|
|
3
|
-
|
|
3
|
+
import { Commands_exports } from "./Commands.js";
|
|
4
|
+
import { Application_exports } from "./Application.js";
|
|
5
|
+
export { Application_exports as Application, Commands_exports as Commands, Manage_exports as Manage, Start_exports as Start };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { CommandConfigError } from "../Commands.js";
|
|
2
|
+
import { Array, Config, Effect, FileSystem, HashMap, Option, Path, Predicate, Schema } from "effect";
|
|
3
|
+
import { parseDocument } from "yaml";
|
|
4
|
+
// src/internal/commandConfig.ts
|
|
5
|
+
const Description = Schema.Struct({
|
|
6
|
+
name: Schema.String,
|
|
7
|
+
config: Schema.optionalKey(Schema.Unknown),
|
|
8
|
+
disabled: Schema.optionalKey(Schema.Boolean)
|
|
9
|
+
});
|
|
10
|
+
const home = Effect.gen(function* () {
|
|
11
|
+
const path = yield* Path.Path;
|
|
12
|
+
const override = yield* Config.String("GRAFT_HOME").pipe(Config.option);
|
|
13
|
+
if (Option.isSome(override)) return path.resolve(override.value);
|
|
14
|
+
const directory = yield* Config.String("HOME");
|
|
15
|
+
return path.join(directory, ".graft");
|
|
16
|
+
});
|
|
17
|
+
const read = Effect.fnUntraced(function* (file) {
|
|
18
|
+
const fs = yield* FileSystem.FileSystem;
|
|
19
|
+
if (!(yield* fs.exists(file))) return [];
|
|
20
|
+
const text = yield* fs.readFileString(file);
|
|
21
|
+
const { Entry } = yield* Effect.promise(() => import("@graftland/loader")).pipe(Effect.uninterruptible);
|
|
22
|
+
const value = yield* Effect.try({
|
|
23
|
+
try: () => {
|
|
24
|
+
const document = parseDocument(text, { customTags: [{
|
|
25
|
+
tag: "!env",
|
|
26
|
+
resolve: (name) => new Entry.Env({ name })
|
|
27
|
+
}] });
|
|
28
|
+
const error = document.errors[0];
|
|
29
|
+
if (error !== void 0) throw error;
|
|
30
|
+
return document.toJS();
|
|
31
|
+
},
|
|
32
|
+
catch: (cause) => CommandConfigError.make({
|
|
33
|
+
file,
|
|
34
|
+
cause
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
const entries = yield* Schema.decodeUnknownEffect(Schema.NullOr(Schema.Array(Schema.Unknown)))(value).pipe(Effect.mapError((cause) => CommandConfigError.make({
|
|
38
|
+
file,
|
|
39
|
+
cause
|
|
40
|
+
})));
|
|
41
|
+
return yield* Effect.forEach(Array.filter(entries ?? [], (entry) => Predicate.hasProperty(entry, "cli") && entry.cli === true), (entry) => Schema.decodeUnknownEffect(Description)(entry).pipe(Effect.mapBoth({
|
|
42
|
+
onFailure: (cause) => CommandConfigError.make({
|
|
43
|
+
file,
|
|
44
|
+
cause
|
|
45
|
+
}),
|
|
46
|
+
onSuccess: (entry) => ({
|
|
47
|
+
...entry,
|
|
48
|
+
file
|
|
49
|
+
})
|
|
50
|
+
})));
|
|
51
|
+
});
|
|
52
|
+
const discover = Effect.fnUntraced(function* (watch) {
|
|
53
|
+
const path = yield* Path.Path;
|
|
54
|
+
const directory = yield* home;
|
|
55
|
+
const global = yield* read(path.join(directory, "graft.yml"));
|
|
56
|
+
const project = yield* read(path.resolve("graft.yml")).pipe(Effect.catchTag("CommandConfigError", (error) => watch ? Effect.logWarning("Command discovery skipped invalid project configuration; restart to load command plugins", error).pipe(Effect.as([])) : Effect.fail(error)));
|
|
57
|
+
const merged = Array.reduce([...global, ...project], HashMap.empty(), (map, entry) => HashMap.set(map, entry.name, entry));
|
|
58
|
+
return Array.filter(Array.fromIterable(HashMap.values(merged)), (entry) => entry.disabled !== true);
|
|
59
|
+
});
|
|
60
|
+
export { discover, home, read };
|
|
61
|
+
|
|
62
|
+
//# sourceMappingURL=commandConfig.js.map
|