@withstudiocms/component-registry 0.1.0-beta.5 → 0.1.0-beta.7

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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @withstudiocms/component-registry
2
2
 
3
+ ## 0.1.0-beta.7
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1029](https://github.com/withstudiocms/studiocms/pull/1029) [`da369c7`](https://github.com/withstudiocms/studiocms/commit/da369c7bd8f40670cb56821d74686c79840f06e4) Thanks [@Adammatthiesen](https://github.com/Adammatthiesen)! - Integrates new Kysely based SDK into StudioCMS
8
+
9
+ - Updated dependencies [[`ee90810`](https://github.com/withstudiocms/studiocms/commit/ee9081053f808d4366a9c95e13539a5198b27bb5), [`a5b84c5`](https://github.com/withstudiocms/studiocms/commit/a5b84c52383bf299aa70c04b064850c7883b59b1), [`9a8bfed`](https://github.com/withstudiocms/studiocms/commit/9a8bfeda461dbc7e3188222db3adeffca1c29f6a), [`ba79740`](https://github.com/withstudiocms/studiocms/commit/ba797403563b8fbd381e0fc28f4ccba0ec6432a6), [`3c54788`](https://github.com/withstudiocms/studiocms/commit/3c54788df0bd548f1e3489b7c7334279ee85d5cb), [`1e1e6a1`](https://github.com/withstudiocms/studiocms/commit/1e1e6a1038de31bfe73070b4feb7163a3e7385a0), [`97c7847`](https://github.com/withstudiocms/studiocms/commit/97c7847c0cdd41998e0a6d8c61ab6f3c4ac4474e), [`675b7d5`](https://github.com/withstudiocms/studiocms/commit/675b7d5bbb2c40e6a204d3c7227812923e37289f)]:
10
+ - @withstudiocms/effect@0.1.0-beta.7
11
+
12
+ ## 0.1.0-beta.6
13
+
14
+ ### Patch Changes
15
+
16
+ - [#978](https://github.com/withstudiocms/studiocms/pull/978) [`34e2c50`](https://github.com/withstudiocms/studiocms/commit/34e2c509914596d5e8bb75bceb6bf2b2cadeba3d) Thanks [@Adammatthiesen](https://github.com/Adammatthiesen)! - Cleans up component registry code
17
+
18
+ - Updated dependencies [[`61091e1`](https://github.com/withstudiocms/studiocms/commit/61091e1e7633f1b4bf0fa3e0a09debb06b861fbe)]:
19
+ - @withstudiocms/effect@0.1.0-beta.6
20
+
3
21
  ## 0.1.0-beta.5
4
22
 
5
23
  ### Patch Changes
@@ -143,7 +143,7 @@ class PropsParser extends Effect.Service()("PropsParser", {
143
143
  try: () => {
144
144
  const frontmatterMatch = astroFileContent.match(/^---\s*\n([\s\S]*?)\n---/m);
145
145
  if (!frontmatterMatch) {
146
- throw new Error("No frontmatter found in Astro file");
146
+ return "";
147
147
  }
148
148
  const frontmatter = frontmatterMatch[1];
149
149
  const interfaceMatch = frontmatter.match(
@@ -164,7 +164,7 @@ class PropsParser extends Effect.Service()("PropsParser", {
164
164
  /(?:export\s+)?(?:interface|type)\s+Props\s*[={]/
165
165
  );
166
166
  if (propsStart === -1) {
167
- throw new Error("No Props interface or type found in frontmatter");
167
+ return "";
168
168
  }
169
169
  const propsSubstring = frontmatter.substring(propsStart);
170
170
  let braceCount = 0;
@@ -1,11 +1,11 @@
1
1
  import { Effect, Layer, Platform } from '@withstudiocms/effect';
2
- import { ComponentNotFoundError, ComponentRegistryError, FileParseError } from '../errors.js';
2
+ import { ComponentNotFoundError } from '../errors.js';
3
3
  import type { AstroComponentProps } from '../types.js';
4
4
  import { PropsParser } from './PropsParser.js';
5
5
  declare const ComponentRegistry_base: Effect.Service.Class<ComponentRegistry, "ComponentRegistry", {
6
6
  readonly dependencies: readonly [Layer.Layer<PropsParser, never, never>, Layer.Layer<Platform.Path.Path, never, never>, Layer.Layer<Platform.FileSystem.FileSystem, never, never>];
7
7
  readonly effect: Effect.Effect<{
8
- registerComponentFromFile: (filePath: string, componentName?: string) => Effect.Effect<void, ComponentRegistryError | FileParseError | Platform.Error.PlatformError, never>;
8
+ registerComponentFromFile: (filePath: string, componentName?: string | undefined) => Effect.Effect<void, import("../errors.js").ComponentRegistryError | import("../errors.js").FileParseError | Platform.Error.PlatformError, never>;
9
9
  getAllComponents: () => Effect.Effect<Map<string, AstroComponentProps>, never, never>;
10
10
  getComponentProps: (componentName: string) => Effect.Effect<AstroComponentProps, ComponentNotFoundError, never>;
11
11
  validateProps: (componentName: string, props: Record<string, unknown>) => Effect.Effect<{
@@ -1,5 +1,5 @@
1
1
  import { Effect, Layer, Platform, PlatformNode } from "@withstudiocms/effect";
2
- import { ComponentNotFoundError, ComponentRegistryError, FileParseError } from "../errors.js";
2
+ import { ComponentNotFoundError } from "../errors.js";
3
3
  import { PropsParser } from "./PropsParser.js";
4
4
  const registryDeps = Layer.mergeAll(
5
5
  PropsParser.Default,
@@ -9,69 +9,56 @@ const registryDeps = Layer.mergeAll(
9
9
  class ComponentRegistry extends Effect.Service()("ComponentRegistry", {
10
10
  dependencies: [PropsParser.Default, Platform.Path.layer, PlatformNode.NodeFileSystem.layer],
11
11
  effect: Effect.gen(function* () {
12
- const parser = yield* PropsParser;
13
- const fs = yield* Platform.FileSystem.FileSystem;
14
- const path = yield* Platform.Path.Path;
12
+ const [parser, fs, path] = yield* Effect.all([
13
+ PropsParser,
14
+ Platform.FileSystem.FileSystem,
15
+ Platform.Path.Path
16
+ ]);
15
17
  const components = /* @__PURE__ */ new Map();
16
- return {
17
- registerComponentFromFile: (filePath, componentName) => Effect.gen(function* () {
18
- const fileContent = yield* fs.readFileString(filePath);
19
- const propsDefinition = yield* parser.extractPropsFromAstroFile(fileContent).pipe(
20
- Effect.mapError(
21
- (error) => new FileParseError({
22
- filePath,
23
- message: error.message,
24
- cause: error.cause
25
- })
26
- )
27
- );
28
- const name = componentName || path.basename(filePath, path.extname(filePath));
29
- const parsed = yield* parser.parseComponentProps(propsDefinition).pipe(
30
- Effect.mapError(
31
- (error) => (
32
- /* v8 ignore start */
33
- new ComponentRegistryError({
34
- message: `Failed to register component ${name}`,
35
- cause: error
36
- })
37
- )
38
- /* v8 ignore stop */
39
- )
40
- );
41
- if (parsed.length > 0) {
42
- components.set(name, parsed[0]);
43
- }
44
- }),
45
- getAllComponents: () => Effect.succeed(new Map(components)),
46
- getComponentProps: (componentName) => Effect.gen(function* () {
47
- const component = components.get(componentName);
48
- if (!component) {
49
- return yield* Effect.fail(new ComponentNotFoundError({ componentName }));
18
+ const _registerComponentFromFile = Effect.fn(
19
+ (filePath, componentName) => fs.readFileString(filePath).pipe(
20
+ Effect.flatMap(parser.extractPropsFromAstroFile),
21
+ Effect.flatMap(parser.parseComponentProps),
22
+ Effect.map((parsed) => {
23
+ const name = componentName || path.basename(filePath, path.extname(filePath));
24
+ const component = parsed[0] ?? {
25
+ name,
26
+ props: []
27
+ };
28
+ components.set(name, component);
29
+ })
30
+ )
31
+ );
32
+ const _getAllComponents = Effect.fn(() => Effect.succeed(new Map(components)));
33
+ const _getComponentProps = Effect.fn(function* (componentName) {
34
+ const component = components.get(componentName);
35
+ if (!component) {
36
+ return yield* Effect.fail(new ComponentNotFoundError({ componentName }));
37
+ }
38
+ return component;
39
+ });
40
+ const _validateProps = Effect.fn(function* (componentName, props) {
41
+ const component = yield* _getComponentProps(componentName);
42
+ const errors = [];
43
+ const providedProps = new Set(Object.keys(props));
44
+ for (const prop of component.props) {
45
+ if (!prop.optional && !providedProps.has(prop.name)) {
46
+ errors.push(`Required prop "${prop.name}" is missing`);
50
47
  }
51
- return component;
52
- }),
53
- validateProps: (componentName, props) => Effect.gen(function* () {
54
- const component = components.get(componentName);
55
- if (!component) {
56
- return yield* Effect.fail(new ComponentNotFoundError({ componentName }));
48
+ }
49
+ const validPropNames = new Set(component.props.map((p) => p.name));
50
+ for (const propName of providedProps) {
51
+ if (!validPropNames.has(propName)) {
52
+ errors.push(`Unknown prop "${propName}"`);
57
53
  }
58
- const errors = [];
59
- const providedProps = new Set(Object.keys(props));
60
- if (component) {
61
- for (const prop of component.props) {
62
- if (!prop.optional && !providedProps.has(prop.name)) {
63
- errors.push(`Required prop "${prop.name}" is missing`);
64
- }
65
- }
66
- const validPropNames = new Set(component.props.map((p) => p.name));
67
- for (const propName of providedProps) {
68
- if (!validPropNames.has(propName)) {
69
- errors.push(`Unknown prop "${propName}"`);
70
- }
71
- }
72
- }
73
- return { valid: errors.length === 0, errors };
74
- })
54
+ }
55
+ return { valid: errors.length === 0, errors };
56
+ });
57
+ return {
58
+ registerComponentFromFile: _registerComponentFromFile,
59
+ getAllComponents: _getAllComponents,
60
+ getComponentProps: _getComponentProps,
61
+ validateProps: _validateProps
75
62
  };
76
63
  }).pipe(Effect.provide(registryDeps))
77
64
  }) {
@@ -1,106 +1,113 @@
1
1
  /// <reference types="../virtual.d.ts" preserve="true" />
2
- import { Effect } from '@withstudiocms/effect';
3
- import { z } from 'astro/zod';
4
- export declare const ComponentRegistryHandlerOptionSchema: z.ZodObject<{
5
- config: z.ZodObject<{
6
- /**
7
- * The name of the integration
8
- */
9
- name: z.ZodString;
10
- /**
11
- * The virtual module ID for generated imports
12
- *
13
- * @example 'virtual:my-integration'
14
- */
15
- virtualId: z.ZodOptional<z.ZodString>;
16
- /**
17
- * Enables verbose logging
18
- */
19
- verbose: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
20
- }, "strip", z.ZodTypeAny, {
21
- name: string;
22
- verbose?: boolean | undefined;
23
- virtualId?: string | undefined;
24
- }, {
25
- name: string;
26
- verbose?: boolean | undefined;
27
- virtualId?: string | undefined;
2
+ import { Schema } from '@withstudiocms/effect';
3
+ /**
4
+ * Schema for validating options passed to the component registry.
5
+ *
6
+ * @remarks
7
+ * This schema enforces the shape of the options object used to configure the
8
+ * component registry. It expects a required top-level `config` object and two
9
+ * optional record maps (`componentRegistry` and `builtInComponents`) keyed by
10
+ * string. The schema is intended to be used with the project's `Schema` utility
11
+ * to validate runtime inputs.
12
+ *
13
+ * @property config - Required configuration object for the registry.
14
+ * @property config.name - The required name of the registry instance (string).
15
+ * @property config.virtualId - Optional virtual identifier used for lookup or
16
+ * resolution (string).
17
+ * @property config.verbose - Optional flag to enable verbose logging or
18
+ * diagnostics (boolean).
19
+ * @property componentRegistry - Optional string-keyed record describing
20
+ * externally provided components or component entries. The exact shape of
21
+ * each record value is defined by `StringRecordSchema` in the codebase.
22
+ * @property builtInComponents - Optional string-keyed record describing
23
+ * built-in components provided by the system. Also uses `StringRecordSchema`.
24
+ *
25
+ * @example
26
+ * // Example shape that conforms to this schema:
27
+ * // {
28
+ * // config: { name: "my-registry", virtualId: "v1", verbose: true },
29
+ * // componentRegistry: { "button": "/components/button" },
30
+ * // builtInComponents: { "text": "/components/text" }
31
+ * // }
32
+ */
33
+ export declare const ComponentRegistryOptionsSchema: Schema.Struct<{
34
+ config: Schema.Struct<{
35
+ name: typeof Schema.String;
36
+ virtualId: Schema.optional<typeof Schema.String>;
37
+ verbose: Schema.optional<typeof Schema.Boolean>;
28
38
  }>;
29
- /**
30
- * A record of user-provided component names to file paths.
31
- */
32
- componentRegistry: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
33
- /**
34
- * A record of built-in component names to file paths.
35
- */
36
- builtInComponents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
37
- }, "strip", z.ZodTypeAny, {
38
- config: {
39
- name: string;
40
- verbose?: boolean | undefined;
41
- virtualId?: string | undefined;
42
- };
43
- componentRegistry?: Record<string, string> | undefined;
44
- builtInComponents?: Record<string, string> | undefined;
45
- }, {
46
- config: {
47
- name: string;
48
- verbose?: boolean | undefined;
49
- virtualId?: string | undefined;
50
- };
51
- componentRegistry?: Record<string, string> | undefined;
52
- builtInComponents?: Record<string, string> | undefined;
39
+ componentRegistry: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.String>>;
40
+ builtInComponents: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.String>>;
53
41
  }>;
54
- export type ComponentRegistryHandlerOptions = z.infer<typeof ComponentRegistryHandlerOptionSchema>;
55
42
  /**
56
- * Creates an Effect-based resolver function for resolving component paths.
43
+ * Represents the TypeScript type inferred from the runtime schema that defines options for the component registry.
57
44
  *
58
- * @param base - The base path used to initialize the resolver.
59
- * @returns An Effect-wrapped function that accepts a callback. The callback receives a `resolve` function,
60
- * which can be used to resolve component paths relative to the base. If an error occurs during resolution,
61
- * it is caught, logged to the console, and an Error object is returned with the original error as its cause.
45
+ * This alias is produced by applying the schema-to-type helper (Schema.Schema.Type) to the schema that describes
46
+ * the registry options. Use this type when declaring or validating objects that will be passed to the component
47
+ * registry to ensure compile-time alignment with the runtime schema.
62
48
  *
63
- * @example
64
- * const resolveEffect = resolver('/components');
65
- * const result = yield* resolveEffect((resolve) => resolve('Button'));
49
+ * Notes:
50
+ * - The precise shape, allowed properties, and defaults are determined by the underlying schema; consult that
51
+ * schema for the authoritative specification of each option.
52
+ * - Because this type is derived from the schema, updating the schema will automatically update this type.
66
53
  */
67
- export declare const resolver: (base: string) => Effect.Effect<(fn: (resolve: (...path: Array<string>) => string) => string) => Effect.Effect<string, Error, never>, never, never>;
54
+ export type ComponentRegistryOptions = Schema.Schema.Type<typeof ComponentRegistryOptionsSchema>;
68
55
  /**
69
- * Handles the setup and registration of components in the component registry during the Astro config setup phase.
56
+ * Handler for the "astro:config:setup" utility that configures and populates the component registry for an Astro integration.
70
57
  *
71
- * This utility merges built-in and user-provided component registries, validates and resolves component paths,
72
- * registers components, and generates virtual imports for use at runtime. It also logs detailed information
73
- * about the registration process, including the number of components processed and their properties.
58
+ * This handler:
59
+ * - Decodes and validates the provided options using the ComponentRegistryOptionsSchema.
60
+ * - Forks and configures a logger scoped to the integration name, supporting a verbose mode for more detailed output.
61
+ * - Merges built-in components with user-provided component registry entries.
62
+ * - Iterates the merged registry and validates each entry:
63
+ * - Only string paths ending with ".astro" are considered.
64
+ * - Each component path is resolved via Astro's resolver; failures are logged and the entry is skipped.
65
+ * - Registers successfully resolved components with the ComponentRegistry effect and collects component metadata (props).
66
+ * - Constructs virtual imports for:
67
+ * - A generated component index (exports for each detected component).
68
+ * - A name export for the integration.
69
+ * - A runtime module import.
70
+ * - Optional alias exports when `virtualId` is provided.
71
+ * - Adds the virtual imports to Astro's config so they are available at runtime.
72
+ * - Emits informative log messages throughout; when `verbose` is true and there are few components, it logs the extracted component props in full.
74
73
  *
75
74
  * @remarks
76
- * - Only components with string values ending in `.astro` are considered valid.
77
- * - Uses Effect for error handling and asynchronous operations.
78
- * - Generates virtual modules for internal proxying and runtime usage.
75
+ * - The handler operates within the Effect runtime and uses an injected ComponentRegistry implementation (ComponentRegistry.Default by default).
76
+ * - Path resolution and registry interactions are handled as Effects; resolution errors are caught and logged so processing continues for other entries.
77
+ * - The handler gracefully skips invalid, non-".astro", or unresolved component entries instead of failing fast.
78
+ *
79
+ * @param params - The Astro config setup parameters provided by defineUtility('astro:config:setup'). Contains the integration config, root path, logger, and other environment helpers used for resolving and registering components.
80
+ * @param opts - Options validated against ComponentRegistryOptionsSchema. Typical fields include:
81
+ * - name: string — name of the integration (used for log scoping and virtual exports).
82
+ * - verbose?: boolean — enable verbose logging.
83
+ * - virtualId?: string — optional virtual alias identifier to emit alias exports.
84
+ * - builtInComponents?: Record<string, string> — default components provided by the integration.
85
+ * - componentRegistry?: Record<string, string> — user-provided component mapping.
86
+ *
87
+ * @returns An Effect-wrapped completion of the setup process. When executed, the effect configures the ComponentRegistry, registers components, and installs virtual imports into the Astro configuration. Any non-fatal errors encountered during resolution or registration are logged and cause the individual entry to be skipped; unrecoverable errors will surface as Effect failures.
79
88
  *
80
- * @param params - The parameters provided by the Astro utility hook, including logger and config.
81
- * @param options - An object containing configuration and registry options:
82
- * - `config.verbose` - Enables verbose logging if true.
83
- * - `config.name` - The name of the integration for logging purposes.
84
- * - `config.virtualId` - The virtual module ID for generated imports.
85
- * - `builtInComponents` - A record of built-in component names to file paths.
86
- * - `componentRegistry` - A record of user-provided component names to file paths.
87
- * @returns A promise that resolves after the component registry has been set up and virtual imports have been added.
89
+ * @throws Resolution or registry errors are handled per-entry and logged; fatal errors related to effect provisioning or unexpected failures may be thrown as Effect failures.
88
90
  *
89
91
  * @example
90
- * ```typescript
91
- * await componentRegistryHandler(params, {
92
- * config: { verbose: true, name: 'my-integration', virtualId: 'virtual:my-registry' },
93
- * builtInComponents: { button: '/components/Button.astro' },
94
- * componentRegistry: { card: '/components/Card.astro' }
95
- * });
96
- * ```
92
+ * // Conceptual usage (options shape)
93
+ * // {
94
+ * // name: 'my-integration',
95
+ * // verbose: true,
96
+ * // virtualId: 'virtual:components',
97
+ * // builtInComponents: { Header: './components/Header.astro' },
98
+ * // componentRegistry: { Footer: './src/components/Footer.astro' }
99
+ * // }
97
100
  */
98
- export declare const componentRegistryHandler: import("astro-integration-kit").HookUtility<"astro:config:setup", [{
99
- config: {
100
- name: string;
101
- verbose?: boolean | undefined;
102
- virtualId?: string | undefined;
101
+ export declare const componentRegistryHandler: import("astro-integration-kit").HookUtility<"astro:config:setup", [opts: {
102
+ readonly config: {
103
+ readonly verbose?: boolean | undefined;
104
+ readonly name: string;
105
+ readonly virtualId?: string | undefined;
103
106
  };
104
- componentRegistry?: Record<string, string> | undefined;
105
- builtInComponents?: Record<string, string> | undefined;
107
+ readonly componentRegistry?: {
108
+ readonly [x: string]: string;
109
+ } | undefined;
110
+ readonly builtInComponents?: {
111
+ readonly [x: string]: string;
112
+ } | undefined;
106
113
  }], Promise<void>>;
@@ -1,7 +1,6 @@
1
- import { deepmerge, Effect, runEffect } from "@withstudiocms/effect";
2
- import { z } from "astro/zod";
3
- import { addVirtualImports, createResolver, defineUtility } from "astro-integration-kit";
4
- import { convertHyphensToUnderscores, integrationLogger } from "../utils.js";
1
+ import { deepmerge, Effect, runEffect, Schema } from "@withstudiocms/effect";
2
+ import { addVirtualImports, defineUtility } from "astro-integration-kit";
3
+ import { convertHyphensToUnderscores, integrationLogger, resolver } from "../utils.js";
5
4
  import {
6
5
  buildAliasExports,
7
6
  buildVirtualImport,
@@ -10,51 +9,24 @@ import {
10
9
  RuntimeInternalId
11
10
  } from "./consts.js";
12
11
  import { ComponentRegistry } from "./Registry.js";
13
- const ComponentRegistryHandlerOptionSchema = z.object({
14
- config: z.object({
15
- /**
16
- * The name of the integration
17
- */
18
- name: z.string(),
19
- /**
20
- * The virtual module ID for generated imports
21
- *
22
- * @example 'virtual:my-integration'
23
- */
24
- virtualId: z.string().optional(),
25
- /**
26
- * Enables verbose logging
27
- */
28
- verbose: z.boolean().default(false).optional()
12
+ const StringRecordSchema = Schema.Record({ key: Schema.String, value: Schema.String });
13
+ const ComponentRegistryOptionsSchema = Schema.Struct({
14
+ config: Schema.Struct({
15
+ name: Schema.String,
16
+ virtualId: Schema.optional(Schema.String),
17
+ verbose: Schema.optional(Schema.Boolean)
29
18
  }),
30
- /**
31
- * A record of user-provided component names to file paths.
32
- */
33
- componentRegistry: z.record(z.string(), z.string()).optional(),
34
- /**
35
- * A record of built-in component names to file paths.
36
- */
37
- builtInComponents: z.record(z.string(), z.string()).optional()
38
- });
39
- const resolver = Effect.fn(function* (base) {
40
- const { resolve: _resolve } = createResolver(base);
41
- return Effect.fn(
42
- (fn) => Effect.try({
43
- try: () => fn(_resolve),
44
- catch: (error) => {
45
- console.error("Error occurred while resolving component:", error);
46
- return new Error("Failed to resolve component", { cause: error });
47
- }
48
- })
49
- );
19
+ componentRegistry: Schema.optional(StringRecordSchema),
20
+ builtInComponents: Schema.optional(StringRecordSchema)
50
21
  });
51
22
  const componentRegistryHandler = defineUtility("astro:config:setup")(
52
- async (params, {
53
- config: { verbose = false, name, virtualId },
54
- builtInComponents = {},
55
- componentRegistry = {}
56
- }) => await runEffect(
23
+ async (params, opts) => await runEffect(
57
24
  Effect.gen(function* () {
25
+ const {
26
+ config: { verbose = false, name, virtualId },
27
+ builtInComponents = {},
28
+ componentRegistry = {}
29
+ } = yield* Schema.decode(ComponentRegistryOptionsSchema)(opts);
58
30
  const logger = params.logger.fork(`${name}:component-registry`);
59
31
  const logInfo = { logger, logLevel: "info", verbose };
60
32
  integrationLogger(logInfo, "Setting up component registry...");
@@ -156,7 +128,6 @@ ${JSON.stringify(componentProps, null, 2)}`
156
128
  )
157
129
  );
158
130
  export {
159
- ComponentRegistryHandlerOptionSchema,
160
- componentRegistryHandler,
161
- resolver
131
+ ComponentRegistryOptionsSchema,
132
+ componentRegistryHandler
162
133
  };
package/dist/utils.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Effect } from '@withstudiocms/effect';
1
2
  import type { AstroIntegrationLogger } from 'astro';
2
3
  /**
3
4
  * Options for configuring the logger.
@@ -50,3 +51,16 @@ export declare function getIndent(ln: string): string;
50
51
  * @returns The dedent string output.
51
52
  */
52
53
  export declare function dedent(str: string): string;
54
+ /**
55
+ * Creates an Effect-based resolver function for resolving component paths.
56
+ *
57
+ * @param base - The base path used to initialize the resolver.
58
+ * @returns An Effect-wrapped function that accepts a callback. The callback receives a `resolve` function,
59
+ * which can be used to resolve component paths relative to the base. If an error occurs during resolution,
60
+ * it is caught, logged to the console, and an Error object is returned with the original error as its cause.
61
+ *
62
+ * @example
63
+ * const resolveEffect = resolver('/components');
64
+ * const result = yield* resolveEffect((resolve) => resolve('Button'));
65
+ */
66
+ export declare const resolver: (base: string) => Effect.Effect<(fn: (resolve: (...path: Array<string>) => string) => string) => Effect.Effect<string, Error, never>, never, never>;
package/dist/utils.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { Effect } from "@withstudiocms/effect";
2
+ import { createResolver } from "astro-integration-kit";
1
3
  const integrationLogger = async (opts, message) => {
2
4
  const { logLevel, logger, verbose = false } = opts;
3
5
  switch (verbose) {
@@ -32,10 +34,23 @@ function dedent(str) {
32
34
  if (indent.length === 0) return lns.join("\n");
33
35
  return lns.map((ln) => ln.startsWith(indent) ? ln.slice(indent.length) : ln).join("\n");
34
36
  }
37
+ const resolver = Effect.fn(function* (base) {
38
+ const { resolve: _resolve } = createResolver(base);
39
+ return Effect.fn(
40
+ (fn) => Effect.try({
41
+ try: () => fn(_resolve),
42
+ catch: (error) => {
43
+ console.error("Error occurred while resolving component:", error);
44
+ return new Error("Failed to resolve component", { cause: error });
45
+ }
46
+ })
47
+ );
48
+ });
35
49
  export {
36
50
  convertHyphensToUnderscores,
37
51
  convertUnderscoresToHyphens,
38
52
  dedent,
39
53
  getIndent,
40
- integrationLogger
54
+ integrationLogger,
55
+ resolver
41
56
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@withstudiocms/component-registry",
3
- "version": "0.1.0-beta.5",
3
+ "version": "0.1.0-beta.7",
4
4
  "description": "Component Registry Utilities for Astro",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -72,7 +72,7 @@
72
72
  "astro-integration-kit": "^0.19.1",
73
73
  "ts-morph": "^27.0.2",
74
74
  "ultrahtml": "1.6.0",
75
- "@withstudiocms/effect": "0.1.0-beta.5"
75
+ "@withstudiocms/effect": "0.1.0-beta.7"
76
76
  },
77
77
  "devDependencies": {
78
78
  "@types/node": "^22.0.0",