@savvy-web/silk-effects 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -17
- package/index.d.ts +902 -162
- package/index.js +1020 -6
- package/package.json +3 -39
- package/biome.d.ts +0 -135
- package/biome.js +0 -84
- package/config.d.ts +0 -147
- package/config.js +0 -38
- package/hooks.d.ts +0 -197
- package/hooks.js +0 -96
- package/publish.d.ts +0 -260
- package/publish.js +0 -124
- package/tags.d.ts +0 -122
- package/tags.js +0 -25
- package/versioning.d.ts +0 -234
- package/versioning.js +0 -115
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@savvy-web/silk-effects",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Shared Effect library for Silk Suite conventions",
|
|
6
6
|
"homepage": "https://github.com/savvy-web/systems/tree/main/packages/silk-effects",
|
|
@@ -24,37 +24,13 @@
|
|
|
24
24
|
".": {
|
|
25
25
|
"types": "./index.d.ts",
|
|
26
26
|
"import": "./index.js"
|
|
27
|
-
},
|
|
28
|
-
"./publish": {
|
|
29
|
-
"types": "./publish.d.ts",
|
|
30
|
-
"import": "./publish.js"
|
|
31
|
-
},
|
|
32
|
-
"./versioning": {
|
|
33
|
-
"types": "./versioning.d.ts",
|
|
34
|
-
"import": "./versioning.js"
|
|
35
|
-
},
|
|
36
|
-
"./tags": {
|
|
37
|
-
"types": "./tags.d.ts",
|
|
38
|
-
"import": "./tags.js"
|
|
39
|
-
},
|
|
40
|
-
"./hooks": {
|
|
41
|
-
"types": "./hooks.d.ts",
|
|
42
|
-
"import": "./hooks.js"
|
|
43
|
-
},
|
|
44
|
-
"./config": {
|
|
45
|
-
"types": "./config.d.ts",
|
|
46
|
-
"import": "./config.js"
|
|
47
|
-
},
|
|
48
|
-
"./biome": {
|
|
49
|
-
"types": "./biome.d.ts",
|
|
50
|
-
"import": "./biome.js"
|
|
51
27
|
}
|
|
52
28
|
},
|
|
53
29
|
"dependencies": {
|
|
54
30
|
"@effect/platform": "^0.96.0",
|
|
55
31
|
"jsonc-effect": "^0.2.1",
|
|
56
32
|
"semver-effect": "^0.2.1",
|
|
57
|
-
"workspaces-effect": "^0.
|
|
33
|
+
"workspaces-effect": "^0.2.0",
|
|
58
34
|
"yaml-effect": "^0.2.3"
|
|
59
35
|
},
|
|
60
36
|
"peerDependencies": {
|
|
@@ -66,21 +42,9 @@
|
|
|
66
42
|
"!tsdoc.json",
|
|
67
43
|
"LICENSE",
|
|
68
44
|
"README.md",
|
|
69
|
-
"biome.d.ts",
|
|
70
|
-
"biome.js",
|
|
71
|
-
"config.d.ts",
|
|
72
|
-
"config.js",
|
|
73
|
-
"hooks.d.ts",
|
|
74
|
-
"hooks.js",
|
|
75
45
|
"index.d.ts",
|
|
76
46
|
"index.js",
|
|
77
47
|
"package.json",
|
|
78
|
-
"
|
|
79
|
-
"publish.js",
|
|
80
|
-
"tags.d.ts",
|
|
81
|
-
"tags.js",
|
|
82
|
-
"tsdoc-metadata.json",
|
|
83
|
-
"versioning.d.ts",
|
|
84
|
-
"versioning.js"
|
|
48
|
+
"tsdoc-metadata.json"
|
|
85
49
|
]
|
|
86
50
|
}
|
package/biome.d.ts
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { Context } from 'effect';
|
|
2
|
-
import { Effect } from 'effect';
|
|
3
|
-
import { FileSystem } from '@effect/platform';
|
|
4
|
-
import { Layer } from 'effect';
|
|
5
|
-
import { Schema } from 'effect';
|
|
6
|
-
import { VoidIfEmpty } from 'effect/Types';
|
|
7
|
-
import { YieldableError } from 'effect/Cause';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Service that keeps the `$schema` URL in Biome config files in sync with a target version.
|
|
11
|
-
*
|
|
12
|
-
* @remarks
|
|
13
|
-
* Locates `biome.json` and `biome.jsonc` files in the working directory, then compares
|
|
14
|
-
* each file's `$schema` field against the expected `biomejs.dev` URL for the given version.
|
|
15
|
-
* `sync` writes updates in-place; `check` returns the same result without modifying files.
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* ```typescript
|
|
19
|
-
* const result = await Effect.runPromise(
|
|
20
|
-
* Effect.gen(function* () {
|
|
21
|
-
* const syncer = yield* BiomeSchemaSync;
|
|
22
|
-
* return yield* syncer.sync("^1.9.3");
|
|
23
|
-
* }).pipe(
|
|
24
|
-
* Effect.provide(BiomeSchemaSyncLive),
|
|
25
|
-
* Effect.provide(NodeContext.layer),
|
|
26
|
-
* )
|
|
27
|
-
* );
|
|
28
|
-
* ```
|
|
29
|
-
*
|
|
30
|
-
* @since 0.1.0
|
|
31
|
-
*/
|
|
32
|
-
export declare class BiomeSchemaSync extends BiomeSchemaSync_base {
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
declare const BiomeSchemaSync_base: Context.TagClass<BiomeSchemaSync, "@savvy-web/silk-effects/BiomeSchemaSync", {
|
|
36
|
-
/**
|
|
37
|
-
* Update the `$schema` URL in all located Biome config files to match `version`.
|
|
38
|
-
*
|
|
39
|
-
* @param version - Target Biome version (range operators are stripped automatically).
|
|
40
|
-
* @param options - Optional `cwd` and `gitignore` overrides.
|
|
41
|
-
* @returns An `Effect` that succeeds with a {@link BiomeSyncResult} or fails with {@link BiomeSyncError}.
|
|
42
|
-
*
|
|
43
|
-
* @since 0.1.0
|
|
44
|
-
*/
|
|
45
|
-
readonly sync: (version: string, options?: {
|
|
46
|
-
cwd?: string;
|
|
47
|
-
gitignore?: boolean;
|
|
48
|
-
}) => Effect.Effect<BiomeSyncResult, BiomeSyncError>;
|
|
49
|
-
/**
|
|
50
|
-
* Check whether the `$schema` URL in Biome config files is current, without writing any changes.
|
|
51
|
-
*
|
|
52
|
-
* @param version - Target Biome version (range operators are stripped automatically).
|
|
53
|
-
* @param options - Optional `cwd` and `gitignore` overrides.
|
|
54
|
-
* @returns An `Effect` that succeeds with a {@link BiomeSyncResult} or fails with {@link BiomeSyncError}.
|
|
55
|
-
* Files that would be updated appear in `updated`; no disk writes occur.
|
|
56
|
-
*
|
|
57
|
-
* @since 0.1.0
|
|
58
|
-
*/
|
|
59
|
-
readonly check: (version: string, options?: {
|
|
60
|
-
cwd?: string;
|
|
61
|
-
gitignore?: boolean;
|
|
62
|
-
}) => Effect.Effect<BiomeSyncResult, BiomeSyncError>;
|
|
63
|
-
}>;
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Live implementation of {@link BiomeSchemaSync}.
|
|
67
|
-
*
|
|
68
|
-
* @remarks
|
|
69
|
-
* Requires `FileSystem` from `@effect/platform`. Provide `NodeContext.layer` or
|
|
70
|
-
* `BunContext.layer` to satisfy this dependency.
|
|
71
|
-
*
|
|
72
|
-
* @since 0.1.0
|
|
73
|
-
*/
|
|
74
|
-
export declare const BiomeSchemaSyncLive: Layer.Layer<BiomeSchemaSync, never, FileSystem.FileSystem>;
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Raised when a Biome config file cannot be read or its `$schema` URL cannot be updated.
|
|
78
|
-
*
|
|
79
|
-
* @remarks
|
|
80
|
-
* Returned by {@link BiomeSchemaSync.sync} and {@link BiomeSchemaSync.check} when
|
|
81
|
-
* a `biome.json` or `biome.jsonc` file exists but cannot be read, contains invalid JSON,
|
|
82
|
-
* or cannot be written back to disk.
|
|
83
|
-
*
|
|
84
|
-
* @since 0.1.0
|
|
85
|
-
*/
|
|
86
|
-
export declare class BiomeSyncError extends BiomeSyncError_base<{
|
|
87
|
-
readonly path: string;
|
|
88
|
-
readonly reason: string;
|
|
89
|
-
}> {
|
|
90
|
-
get message(): string;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
declare const BiomeSyncError_base: new <A extends Record<string, any> = {}>(args: VoidIfEmpty< { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => YieldableError & {
|
|
94
|
-
readonly _tag: "BiomeSyncError";
|
|
95
|
-
} & Readonly<A>;
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Options for {@link BiomeSchemaSync} operations.
|
|
99
|
-
*
|
|
100
|
-
* @remarks
|
|
101
|
-
* `cwd` overrides the working directory used to locate `biome.json` / `biome.jsonc`.
|
|
102
|
-
* `gitignore` is reserved for future use to skip gitignored config files (defaults to `true`).
|
|
103
|
-
*
|
|
104
|
-
* @since 0.1.0
|
|
105
|
-
*/
|
|
106
|
-
export declare const BiomeSyncOptions: Schema.Struct<{
|
|
107
|
-
cwd: Schema.optional<typeof Schema.String>;
|
|
108
|
-
gitignore: Schema.optionalWith<typeof Schema.Boolean, {
|
|
109
|
-
default: () => true;
|
|
110
|
-
}>;
|
|
111
|
-
}>;
|
|
112
|
-
|
|
113
|
-
/** @since 0.1.0 */
|
|
114
|
-
export declare type BiomeSyncOptions = typeof BiomeSyncOptions.Type;
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Result of a Biome schema URL sync or check operation.
|
|
118
|
-
*
|
|
119
|
-
* @remarks
|
|
120
|
-
* - `updated` — paths of config files whose `$schema` URL was changed (or would be changed on `check`).
|
|
121
|
-
* - `skipped` — paths of config files with no `$schema` field or a non-biomejs.dev URL.
|
|
122
|
-
* - `current` — paths of config files already pointing to the expected schema URL.
|
|
123
|
-
*
|
|
124
|
-
* @since 0.1.0
|
|
125
|
-
*/
|
|
126
|
-
export declare const BiomeSyncResult: Schema.Struct<{
|
|
127
|
-
updated: Schema.Array$<typeof Schema.String>;
|
|
128
|
-
skipped: Schema.Array$<typeof Schema.String>;
|
|
129
|
-
current: Schema.Array$<typeof Schema.String>;
|
|
130
|
-
}>;
|
|
131
|
-
|
|
132
|
-
/** @since 0.1.0 */
|
|
133
|
-
export declare type BiomeSyncResult = typeof BiomeSyncResult.Type;
|
|
134
|
-
|
|
135
|
-
export { }
|
package/biome.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { FileSystem } from "@effect/platform";
|
|
2
|
-
import { Context, Data, Effect, Layer } from "effect";
|
|
3
|
-
import { parse } from "jsonc-effect";
|
|
4
|
-
class BiomeSyncError extends Data.TaggedError("BiomeSyncError") {
|
|
5
|
-
get message() {
|
|
6
|
-
return `Failed to sync biome schema in ${this.path}: ${this.reason}`;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
function extractSemver(version) {
|
|
10
|
-
return version.replace(/^[\^~>=<v]+/, "");
|
|
11
|
-
}
|
|
12
|
-
function buildSchemaUrl(version) {
|
|
13
|
-
return `https://biomejs.dev/schemas/${version}/schema.json`;
|
|
14
|
-
}
|
|
15
|
-
const BIOME_SCHEMA_HOSTNAME = "biomejs.dev";
|
|
16
|
-
function findBiomeConfigs(cwd, fs) {
|
|
17
|
-
const candidates = [
|
|
18
|
-
`${cwd}/biome.json`,
|
|
19
|
-
`${cwd}/biome.jsonc`
|
|
20
|
-
];
|
|
21
|
-
return Effect.gen(function*() {
|
|
22
|
-
const results = [];
|
|
23
|
-
for (const candidate of candidates){
|
|
24
|
-
const exists = yield* fs.exists(candidate).pipe(Effect.orElseSucceed(()=>false));
|
|
25
|
-
if (exists) results.push(candidate);
|
|
26
|
-
}
|
|
27
|
-
return results;
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
class BiomeSchemaSync extends Context.Tag("@savvy-web/silk-effects/BiomeSchemaSync")() {
|
|
31
|
-
}
|
|
32
|
-
const BiomeSchemaSyncLive = Layer.effect(BiomeSchemaSync, Effect.gen(function*() {
|
|
33
|
-
const fs = yield* FileSystem.FileSystem;
|
|
34
|
-
const run = (version, options, write)=>Effect.gen(function*() {
|
|
35
|
-
const cwd = options?.cwd ?? process.cwd();
|
|
36
|
-
const semver = extractSemver(version);
|
|
37
|
-
const expectedUrl = buildSchemaUrl(semver);
|
|
38
|
-
const configs = yield* findBiomeConfigs(cwd, fs);
|
|
39
|
-
const updated = [];
|
|
40
|
-
const skipped = [];
|
|
41
|
-
const current = [];
|
|
42
|
-
for (const configPath of configs){
|
|
43
|
-
const raw = yield* fs.readFileString(configPath).pipe(Effect.mapError((cause)=>new BiomeSyncError({
|
|
44
|
-
path: configPath,
|
|
45
|
-
reason: String(cause)
|
|
46
|
-
})));
|
|
47
|
-
const parsed = yield* parse(raw).pipe(Effect.mapError((e)=>new BiomeSyncError({
|
|
48
|
-
path: configPath,
|
|
49
|
-
reason: `Failed to parse JSONC: ${String(e)}`
|
|
50
|
-
})));
|
|
51
|
-
const schema = parsed.$schema;
|
|
52
|
-
if ("string" != typeof schema) {
|
|
53
|
-
skipped.push(configPath);
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
if (!schema.includes(BIOME_SCHEMA_HOSTNAME)) {
|
|
57
|
-
skipped.push(configPath);
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
if (schema === expectedUrl) {
|
|
61
|
-
current.push(configPath);
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
if (write) {
|
|
65
|
-
const updated_content = raw.replaceAll(schema, expectedUrl);
|
|
66
|
-
yield* fs.writeFileString(configPath, updated_content).pipe(Effect.mapError((cause)=>new BiomeSyncError({
|
|
67
|
-
path: configPath,
|
|
68
|
-
reason: String(cause)
|
|
69
|
-
})));
|
|
70
|
-
}
|
|
71
|
-
updated.push(configPath);
|
|
72
|
-
}
|
|
73
|
-
return {
|
|
74
|
-
updated,
|
|
75
|
-
skipped,
|
|
76
|
-
current
|
|
77
|
-
};
|
|
78
|
-
});
|
|
79
|
-
return {
|
|
80
|
-
sync: (version, options)=>run(version, options, true),
|
|
81
|
-
check: (version, options)=>run(version, options, false)
|
|
82
|
-
};
|
|
83
|
-
}));
|
|
84
|
-
export { BiomeSchemaSync, BiomeSchemaSyncLive, BiomeSyncError };
|
package/config.d.ts
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { Context } from 'effect';
|
|
2
|
-
import { Effect } from 'effect';
|
|
3
|
-
import { FileSystem } from '@effect/platform';
|
|
4
|
-
import { Layer } from 'effect';
|
|
5
|
-
import { Schema } from 'effect';
|
|
6
|
-
import { VoidIfEmpty } from 'effect/Types';
|
|
7
|
-
import { YieldableError } from 'effect/Cause';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Service that locates named config files within a workspace using priority-ordered search paths.
|
|
11
|
-
*
|
|
12
|
-
* @remarks
|
|
13
|
-
* Search priority (highest to lowest):
|
|
14
|
-
* 1. `lib/configs/{name}` — shared config provided by a dependency package.
|
|
15
|
-
* 2. `{cwd}/{name}` — local override at the workspace root.
|
|
16
|
-
*
|
|
17
|
-
* Missing files are silently skipped; only files that actually exist are returned.
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```typescript
|
|
21
|
-
* const result = await Effect.runPromise(
|
|
22
|
-
* Effect.gen(function* () {
|
|
23
|
-
* const discovery = yield* ConfigDiscovery;
|
|
24
|
-
* return yield* discovery.find("biome.json");
|
|
25
|
-
* }).pipe(
|
|
26
|
-
* Effect.provide(ConfigDiscoveryLive),
|
|
27
|
-
* Effect.provide(NodeContext.layer),
|
|
28
|
-
* )
|
|
29
|
-
* );
|
|
30
|
-
* ```
|
|
31
|
-
*
|
|
32
|
-
* @since 0.1.0
|
|
33
|
-
*/
|
|
34
|
-
export declare class ConfigDiscovery extends ConfigDiscovery_base {
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
declare const ConfigDiscovery_base: Context.TagClass<ConfigDiscovery, "@savvy-web/silk-effects/ConfigDiscovery", {
|
|
38
|
-
/**
|
|
39
|
-
* Return the highest-priority {@link ConfigLocation} for the given config file name,
|
|
40
|
-
* or `null` when none of the candidate paths exist.
|
|
41
|
-
*
|
|
42
|
-
* @param name - Config file name (e.g. `"biome.json"`).
|
|
43
|
-
* @param options - Optional `cwd` override for path resolution.
|
|
44
|
-
* @returns An `Effect` that always succeeds with a {@link ConfigLocation} or `null`.
|
|
45
|
-
*
|
|
46
|
-
* @since 0.1.0
|
|
47
|
-
*/
|
|
48
|
-
readonly find: (name: string, options?: {
|
|
49
|
-
cwd?: string;
|
|
50
|
-
}) => Effect.Effect<ConfigLocation | null>;
|
|
51
|
-
/**
|
|
52
|
-
* Return all existing {@link ConfigLocation} entries for the given config file name,
|
|
53
|
-
* ordered from highest to lowest priority.
|
|
54
|
-
*
|
|
55
|
-
* @param name - Config file name (e.g. `"biome.json"`).
|
|
56
|
-
* @param options - Optional `cwd` override for path resolution.
|
|
57
|
-
* @returns An `Effect` that always succeeds with an array of {@link ConfigLocation} records.
|
|
58
|
-
*
|
|
59
|
-
* @since 0.1.0
|
|
60
|
-
*/
|
|
61
|
-
readonly findAll: (name: string, options?: {
|
|
62
|
-
cwd?: string;
|
|
63
|
-
}) => Effect.Effect<ReadonlyArray<ConfigLocation>>;
|
|
64
|
-
}>;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Live implementation of {@link ConfigDiscovery}.
|
|
68
|
-
*
|
|
69
|
-
* @remarks
|
|
70
|
-
* Requires `FileSystem` from `@effect/platform`. Provide `NodeContext.layer` or
|
|
71
|
-
* `BunContext.layer` to satisfy this dependency.
|
|
72
|
-
*
|
|
73
|
-
* @since 0.1.0
|
|
74
|
-
*/
|
|
75
|
-
export declare const ConfigDiscoveryLive: Layer.Layer<ConfigDiscovery, never, FileSystem.FileSystem>;
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Options passed to config discovery methods.
|
|
79
|
-
*
|
|
80
|
-
* @remarks
|
|
81
|
-
* `cwd` overrides the working directory for path resolution (defaults to `process.cwd()`).
|
|
82
|
-
* `tool` is reserved for future use as a tool-specific discovery hint.
|
|
83
|
-
*
|
|
84
|
-
* @since 0.1.0
|
|
85
|
-
*/
|
|
86
|
-
export declare const ConfigDiscoveryOptions: Schema.Struct<{
|
|
87
|
-
cwd: Schema.optional<typeof Schema.String>;
|
|
88
|
-
tool: Schema.optional<typeof Schema.String>;
|
|
89
|
-
}>;
|
|
90
|
-
|
|
91
|
-
/** @since 0.1.0 */
|
|
92
|
-
export declare type ConfigDiscoveryOptions = typeof ConfigDiscoveryOptions.Type;
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* The resolved location of a discovered config file.
|
|
96
|
-
*
|
|
97
|
-
* @remarks
|
|
98
|
-
* Produced by {@link ConfigDiscovery.find} and {@link ConfigDiscovery.findAll}.
|
|
99
|
-
* `path` is the absolute file path; `source` indicates how it was discovered.
|
|
100
|
-
*
|
|
101
|
-
* @since 0.1.0
|
|
102
|
-
*/
|
|
103
|
-
export declare const ConfigLocation: Schema.Struct<{
|
|
104
|
-
path: typeof Schema.String;
|
|
105
|
-
source: Schema.Literal<["lib", "root", "cosmiconfig"]>;
|
|
106
|
-
}>;
|
|
107
|
-
|
|
108
|
-
/** @since 0.1.0 */
|
|
109
|
-
export declare type ConfigLocation = typeof ConfigLocation.Type;
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Raised when a config file cannot be located in any of the expected locations.
|
|
113
|
-
*
|
|
114
|
-
* @remarks
|
|
115
|
-
* Returned by consumers that require a config file to exist. {@link ConfigDiscovery.find}
|
|
116
|
-
* itself returns `null` instead of failing — callers that need a hard failure should
|
|
117
|
-
* map `null` to this error.
|
|
118
|
-
*
|
|
119
|
-
* @since 0.1.0
|
|
120
|
-
*/
|
|
121
|
-
export declare class ConfigNotFoundError extends ConfigNotFoundError_base<{
|
|
122
|
-
readonly name: string;
|
|
123
|
-
readonly searchedPaths: ReadonlyArray<string>;
|
|
124
|
-
}> {
|
|
125
|
-
get message(): string;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
declare const ConfigNotFoundError_base: new <A extends Record<string, any> = {}>(args: VoidIfEmpty< { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => YieldableError & {
|
|
129
|
-
readonly _tag: "ConfigNotFoundError";
|
|
130
|
-
} & Readonly<A>;
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* The discovery strategy used to locate a config file.
|
|
134
|
-
*
|
|
135
|
-
* @remarks
|
|
136
|
-
* - `"lib"` — found under `lib/configs/{name}` relative to the workspace root.
|
|
137
|
-
* - `"root"` — found directly in the workspace root as `{name}`.
|
|
138
|
-
* - `"cosmiconfig"` — reserved for future cosmiconfig-based discovery.
|
|
139
|
-
*
|
|
140
|
-
* @since 0.1.0
|
|
141
|
-
*/
|
|
142
|
-
export declare const ConfigSource: Schema.Literal<["lib", "root", "cosmiconfig"]>;
|
|
143
|
-
|
|
144
|
-
/** @since 0.1.0 */
|
|
145
|
-
export declare type ConfigSource = typeof ConfigSource.Type;
|
|
146
|
-
|
|
147
|
-
export { }
|
package/config.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { FileSystem } from "@effect/platform";
|
|
2
|
-
import { Context, Data, Effect, Layer } from "effect";
|
|
3
|
-
class ConfigDiscovery extends Context.Tag("@savvy-web/silk-effects/ConfigDiscovery")() {
|
|
4
|
-
}
|
|
5
|
-
function safeExists(fs, path) {
|
|
6
|
-
return fs.exists(path).pipe(Effect.orElseSucceed(()=>false));
|
|
7
|
-
}
|
|
8
|
-
const ConfigDiscoveryLive = Layer.effect(ConfigDiscovery, Effect.gen(function*() {
|
|
9
|
-
const fs = yield* FileSystem.FileSystem;
|
|
10
|
-
const findAll = (name, options)=>Effect.gen(function*() {
|
|
11
|
-
const cwd = options?.cwd ?? process.cwd();
|
|
12
|
-
const results = [];
|
|
13
|
-
const libPath = `${cwd}/lib/configs/${name}`;
|
|
14
|
-
const libExists = yield* safeExists(fs, libPath);
|
|
15
|
-
if (libExists) results.push({
|
|
16
|
-
path: libPath,
|
|
17
|
-
source: "lib"
|
|
18
|
-
});
|
|
19
|
-
const rootPath = `${cwd}/${name}`;
|
|
20
|
-
const rootExists = yield* safeExists(fs, rootPath);
|
|
21
|
-
if (rootExists) results.push({
|
|
22
|
-
path: rootPath,
|
|
23
|
-
source: "root"
|
|
24
|
-
});
|
|
25
|
-
return results;
|
|
26
|
-
});
|
|
27
|
-
const find = (name, options)=>findAll(name, options).pipe(Effect.map((results)=>results[0] ?? null));
|
|
28
|
-
return {
|
|
29
|
-
find,
|
|
30
|
-
findAll
|
|
31
|
-
};
|
|
32
|
-
}));
|
|
33
|
-
class ConfigNotFoundError extends Data.TaggedError("ConfigNotFoundError") {
|
|
34
|
-
get message() {
|
|
35
|
-
return `Config '${this.name}' not found. Searched: ${this.searchedPaths.join(", ")}`;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
export { ConfigDiscovery, ConfigDiscoveryLive, ConfigNotFoundError };
|
package/hooks.d.ts
DELETED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
import { Context } from 'effect';
|
|
2
|
-
import { Effect } from 'effect';
|
|
3
|
-
import { FileSystem } from '@effect/platform';
|
|
4
|
-
import { Layer } from 'effect';
|
|
5
|
-
import { Schema } from 'effect';
|
|
6
|
-
import { VoidIfEmpty } from 'effect/Types';
|
|
7
|
-
import { YieldableError } from 'effect/Cause';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Comment syntax used to write managed section markers.
|
|
11
|
-
*
|
|
12
|
-
* @remarks
|
|
13
|
-
* - `"#"` — shell/YAML style, suitable for hook scripts and `.env` files.
|
|
14
|
-
* - `"//"` — C-style, suitable for JavaScript/TypeScript files.
|
|
15
|
-
*
|
|
16
|
-
* @since 0.1.0
|
|
17
|
-
*/
|
|
18
|
-
export declare const CommentStyle: Schema.Literal<["#", "//"]>;
|
|
19
|
-
|
|
20
|
-
/** @since 0.1.0 */
|
|
21
|
-
export declare type CommentStyle = typeof CommentStyle.Type;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Service providing managed section operations for tool-owned regions
|
|
25
|
-
* within user-editable files (e.g. husky hooks).
|
|
26
|
-
*
|
|
27
|
-
* @remarks
|
|
28
|
-
* A managed section is a delimited block in a file bounded by BEGIN/END marker comments.
|
|
29
|
-
* The markers embed the tool name so multiple tools can manage independent sections in
|
|
30
|
-
* the same file. User content outside the markers is always preserved.
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* ```typescript
|
|
34
|
-
* const result = await Effect.runPromise(
|
|
35
|
-
* Effect.gen(function* () {
|
|
36
|
-
* const section = yield* ManagedSection;
|
|
37
|
-
* yield* section.write(".husky/pre-commit", "silk", "\nnpx lint-staged\n");
|
|
38
|
-
* return yield* section.read(".husky/pre-commit", "silk");
|
|
39
|
-
* }).pipe(
|
|
40
|
-
* Effect.provide(ManagedSectionLive),
|
|
41
|
-
* Effect.provide(NodeContext.layer),
|
|
42
|
-
* )
|
|
43
|
-
* );
|
|
44
|
-
* ```
|
|
45
|
-
*
|
|
46
|
-
* @since 0.1.0
|
|
47
|
-
*/
|
|
48
|
-
export declare class ManagedSection extends ManagedSection_base {
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
declare const ManagedSection_base: Context.TagClass<ManagedSection, "@savvy-web/silk-effects/ManagedSection", {
|
|
52
|
-
/**
|
|
53
|
-
* Read and parse the managed section from a file.
|
|
54
|
-
*
|
|
55
|
-
* @param path - Absolute path to the file.
|
|
56
|
-
* @param toolName - Tool identifier embedded in the section markers.
|
|
57
|
-
* @param commentStyle - Comment prefix to use (`"#"` or `"//"`, defaults to `"#"`).
|
|
58
|
-
* @returns An `Effect` that succeeds with a {@link ManagedSectionResult} when markers
|
|
59
|
-
* are found, `null` when the file has no markers, or fails with
|
|
60
|
-
* {@link ManagedSectionParseError} on I/O errors.
|
|
61
|
-
*
|
|
62
|
-
* @since 0.1.0
|
|
63
|
-
*/
|
|
64
|
-
readonly read: (path: string, toolName: string, commentStyle?: string) => Effect.Effect<ManagedSectionResult | null, ManagedSectionParseError>;
|
|
65
|
-
/**
|
|
66
|
-
* Write managed content to a file.
|
|
67
|
-
*
|
|
68
|
-
* @remarks
|
|
69
|
-
* - Replaces the existing managed section when markers are already present.
|
|
70
|
-
* - Appends a new managed section when the file exists but has no markers.
|
|
71
|
-
* - Creates the file when it does not exist.
|
|
72
|
-
*
|
|
73
|
-
* @param path - Absolute path to the file.
|
|
74
|
-
* @param toolName - Tool identifier embedded in the section markers.
|
|
75
|
-
* @param content - Content to place inside the managed section (between markers).
|
|
76
|
-
* @param commentStyle - Comment prefix to use (`"#"` or `"//"`, defaults to `"#"`).
|
|
77
|
-
* @returns An `Effect` that succeeds with `void` or fails with {@link ManagedSectionWriteError}.
|
|
78
|
-
*
|
|
79
|
-
* @since 0.1.0
|
|
80
|
-
*/
|
|
81
|
-
readonly write: (path: string, toolName: string, content: string, commentStyle?: string) => Effect.Effect<void, ManagedSectionWriteError>;
|
|
82
|
-
/**
|
|
83
|
-
* Read-then-write convenience method that replaces managed content while
|
|
84
|
-
* preserving surrounding user content.
|
|
85
|
-
*
|
|
86
|
-
* @param path - Absolute path to the file.
|
|
87
|
-
* @param toolName - Tool identifier embedded in the section markers.
|
|
88
|
-
* @param content - Replacement content for the managed section.
|
|
89
|
-
* @param commentStyle - Comment prefix to use (`"#"` or `"//"`, defaults to `"#"`).
|
|
90
|
-
* @returns An `Effect` that succeeds with `void` or fails with {@link ManagedSectionWriteError}.
|
|
91
|
-
*
|
|
92
|
-
* @since 0.1.0
|
|
93
|
-
*/
|
|
94
|
-
readonly update: (path: string, toolName: string, content: string, commentStyle?: string) => Effect.Effect<void, ManagedSectionWriteError>;
|
|
95
|
-
/**
|
|
96
|
-
* Return `true` when the file contains both BEGIN and END markers for the given tool.
|
|
97
|
-
*
|
|
98
|
-
* @param path - Absolute path to the file.
|
|
99
|
-
* @param toolName - Tool identifier to search for in the markers.
|
|
100
|
-
* @param commentStyle - Comment prefix to match (`"#"` or `"//"`, defaults to `"#"`).
|
|
101
|
-
* @returns An `Effect` that always succeeds with a boolean.
|
|
102
|
-
*
|
|
103
|
-
* @since 0.1.0
|
|
104
|
-
*/
|
|
105
|
-
readonly isManaged: (path: string, toolName: string, commentStyle?: string) => Effect.Effect<boolean>;
|
|
106
|
-
}>;
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Live implementation of {@link ManagedSection} backed by `@effect/platform` FileSystem.
|
|
110
|
-
*
|
|
111
|
-
* @remarks
|
|
112
|
-
* Requires `FileSystem` from `@effect/platform`. Provide `NodeContext.layer` or
|
|
113
|
-
* `BunContext.layer` to satisfy this dependency.
|
|
114
|
-
*
|
|
115
|
-
* @since 0.1.0
|
|
116
|
-
*/
|
|
117
|
-
export declare const ManagedSectionLive: Layer.Layer<ManagedSection, never, FileSystem.FileSystem>;
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Options controlling how managed sections are identified in a file.
|
|
121
|
-
*
|
|
122
|
-
* @remarks
|
|
123
|
-
* `toolName` is embedded in the BEGIN/END markers so multiple tools can coexist
|
|
124
|
-
* in the same file without collision. `commentStyle` defaults to `"#"`.
|
|
125
|
-
*
|
|
126
|
-
* @since 0.1.0
|
|
127
|
-
*/
|
|
128
|
-
export declare const ManagedSectionOptions: Schema.Struct<{
|
|
129
|
-
toolName: typeof Schema.String;
|
|
130
|
-
commentStyle: Schema.optionalWith<Schema.Literal<["#", "//"]>, {
|
|
131
|
-
default: () => "#";
|
|
132
|
-
}>;
|
|
133
|
-
}>;
|
|
134
|
-
|
|
135
|
-
/** @since 0.1.0 */
|
|
136
|
-
export declare type ManagedSectionOptions = typeof ManagedSectionOptions.Type;
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Raised when a managed section cannot be parsed from a file.
|
|
140
|
-
*
|
|
141
|
-
* @remarks
|
|
142
|
-
* Returned by {@link ManagedSection.read} when the file exists but its content
|
|
143
|
-
* cannot be read (e.g. a filesystem permission error).
|
|
144
|
-
*
|
|
145
|
-
* @since 0.1.0
|
|
146
|
-
*/
|
|
147
|
-
export declare class ManagedSectionParseError extends ManagedSectionParseError_base<{
|
|
148
|
-
readonly path: string;
|
|
149
|
-
readonly reason: string;
|
|
150
|
-
}> {
|
|
151
|
-
get message(): string;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
declare const ManagedSectionParseError_base: new <A extends Record<string, any> = {}>(args: VoidIfEmpty< { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => YieldableError & {
|
|
155
|
-
readonly _tag: "ManagedSectionParseError";
|
|
156
|
-
} & Readonly<A>;
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Parsed result of reading a managed section from a file.
|
|
160
|
-
*
|
|
161
|
-
* @remarks
|
|
162
|
-
* Produced by {@link ManagedSection.read}. The `before` and `after` strings
|
|
163
|
-
* contain the file content surrounding the managed block; `managed` holds the
|
|
164
|
-
* content between the BEGIN and END markers (excluding the markers themselves).
|
|
165
|
-
*
|
|
166
|
-
* @since 0.1.0
|
|
167
|
-
*/
|
|
168
|
-
export declare const ManagedSectionResult: Schema.Struct<{
|
|
169
|
-
before: typeof Schema.String;
|
|
170
|
-
managed: typeof Schema.String;
|
|
171
|
-
after: typeof Schema.String;
|
|
172
|
-
}>;
|
|
173
|
-
|
|
174
|
-
/** @since 0.1.0 */
|
|
175
|
-
export declare type ManagedSectionResult = typeof ManagedSectionResult.Type;
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Raised when a managed section cannot be written to a file.
|
|
179
|
-
*
|
|
180
|
-
* @remarks
|
|
181
|
-
* Returned by {@link ManagedSection.write} and {@link ManagedSection.update} when
|
|
182
|
-
* the file cannot be read for content replacement or when the write itself fails.
|
|
183
|
-
*
|
|
184
|
-
* @since 0.1.0
|
|
185
|
-
*/
|
|
186
|
-
export declare class ManagedSectionWriteError extends ManagedSectionWriteError_base<{
|
|
187
|
-
readonly path: string;
|
|
188
|
-
readonly reason: string;
|
|
189
|
-
}> {
|
|
190
|
-
get message(): string;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
declare const ManagedSectionWriteError_base: new <A extends Record<string, any> = {}>(args: VoidIfEmpty< { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => YieldableError & {
|
|
194
|
-
readonly _tag: "ManagedSectionWriteError";
|
|
195
|
-
} & Readonly<A>;
|
|
196
|
-
|
|
197
|
-
export { }
|