@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 +18 -0
- package/dist/registry/PropsParser.js +2 -2
- package/dist/registry/Registry.d.ts +2 -2
- package/dist/registry/Registry.js +48 -61
- package/dist/registry/handler.d.ts +96 -89
- package/dist/registry/handler.js +19 -48
- package/dist/utils.d.ts +14 -0
- package/dist/utils.js +16 -1
- package/package.json +2 -2
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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*
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
)
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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 {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
43
|
+
* Represents the TypeScript type inferred from the runtime schema that defines options for the component registry.
|
|
57
44
|
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
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
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
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
|
|
54
|
+
export type ComponentRegistryOptions = Schema.Schema.Type<typeof ComponentRegistryOptionsSchema>;
|
|
68
55
|
/**
|
|
69
|
-
*
|
|
56
|
+
* Handler for the "astro:config:setup" utility that configures and populates the component registry for an Astro integration.
|
|
70
57
|
*
|
|
71
|
-
* This
|
|
72
|
-
*
|
|
73
|
-
*
|
|
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
|
-
* -
|
|
77
|
-
* -
|
|
78
|
-
* -
|
|
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
|
-
* @
|
|
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
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
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
|
-
|
|
101
|
-
|
|
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?:
|
|
105
|
-
|
|
107
|
+
readonly componentRegistry?: {
|
|
108
|
+
readonly [x: string]: string;
|
|
109
|
+
} | undefined;
|
|
110
|
+
readonly builtInComponents?: {
|
|
111
|
+
readonly [x: string]: string;
|
|
112
|
+
} | undefined;
|
|
106
113
|
}], Promise<void>>;
|
package/dist/registry/handler.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { deepmerge, Effect, runEffect } from "@withstudiocms/effect";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
75
|
+
"@withstudiocms/effect": "0.1.0-beta.7"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"@types/node": "^22.0.0",
|