@withstudiocms/sdk 0.0.0-beta.0 → 0.1.0-beta.1

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.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +21 -0
  3. package/dist/cache.d.ts +109 -0
  4. package/dist/cache.js +94 -0
  5. package/dist/consts.d.ts +28 -0
  6. package/dist/consts.js +26 -0
  7. package/dist/context.d.ts +188 -0
  8. package/dist/context.js +33 -0
  9. package/dist/index.d.ts +1136 -0
  10. package/dist/index.js +24 -0
  11. package/dist/lib/diff.d.ts +39 -0
  12. package/dist/lib/diff.js +29 -0
  13. package/dist/lib/logger.d.ts +31 -0
  14. package/dist/lib/logger.js +131 -0
  15. package/dist/lib/pluginUtils.d.ts +221 -0
  16. package/dist/lib/pluginUtils.js +80 -0
  17. package/dist/modules/auth/index.d.ts +463 -0
  18. package/dist/modules/auth/index.js +412 -0
  19. package/dist/modules/clear/index.d.ts +72 -0
  20. package/dist/modules/clear/index.js +52 -0
  21. package/dist/modules/config/consts.d.ts +32 -0
  22. package/dist/modules/config/consts.js +18 -0
  23. package/dist/modules/config/index.d.ts +100 -0
  24. package/dist/modules/config/index.js +205 -0
  25. package/dist/modules/config/templates/mailer.d.ts +36 -0
  26. package/dist/modules/config/templates/mailer.js +218 -0
  27. package/dist/modules/config/type-utils.d.ts +13 -0
  28. package/dist/modules/config/type-utils.js +11 -0
  29. package/dist/modules/delete/index.d.ts +140 -0
  30. package/dist/modules/delete/index.js +274 -0
  31. package/dist/modules/diffTracking/index.d.ts +188 -0
  32. package/dist/modules/diffTracking/index.js +276 -0
  33. package/dist/modules/get/index.d.ts +272 -0
  34. package/dist/modules/get/index.js +466 -0
  35. package/dist/modules/index.d.ts +1003 -0
  36. package/dist/modules/index.js +37 -0
  37. package/dist/modules/init/index.d.ts +60 -0
  38. package/dist/modules/init/index.js +38 -0
  39. package/dist/modules/middleware/index.d.ts +56 -0
  40. package/dist/modules/middleware/index.js +50 -0
  41. package/dist/modules/notificationSettings/index.d.ts +57 -0
  42. package/dist/modules/notificationSettings/index.js +39 -0
  43. package/dist/modules/plugins/index.d.ts +166 -0
  44. package/dist/modules/plugins/index.js +261 -0
  45. package/dist/modules/post/index.d.ts +305 -0
  46. package/dist/modules/post/index.js +305 -0
  47. package/dist/modules/resetTokenBucket/index.d.ts +91 -0
  48. package/dist/modules/resetTokenBucket/index.js +93 -0
  49. package/dist/modules/rest_api/index.d.ts +92 -0
  50. package/dist/modules/rest_api/index.js +113 -0
  51. package/dist/modules/update/index.d.ts +184 -0
  52. package/dist/modules/update/index.js +174 -0
  53. package/dist/modules/util/collectors.d.ts +261 -0
  54. package/dist/modules/util/collectors.js +141 -0
  55. package/dist/modules/util/folderTree.d.ts +100 -0
  56. package/dist/modules/util/folderTree.js +176 -0
  57. package/dist/modules/util/generators.d.ts +83 -0
  58. package/dist/modules/util/generators.js +106 -0
  59. package/dist/modules/util/getFromNPM.d.ts +191 -0
  60. package/dist/modules/util/getFromNPM.js +100 -0
  61. package/dist/modules/util/index.d.ts +236 -0
  62. package/dist/modules/util/index.js +20 -0
  63. package/dist/modules/util/parsers.d.ts +60 -0
  64. package/dist/modules/util/parsers.js +43 -0
  65. package/dist/modules/util/slugify.d.ts +22 -0
  66. package/dist/modules/util/slugify.js +19 -0
  67. package/dist/modules/util/users.d.ts +99 -0
  68. package/dist/modules/util/users.js +78 -0
  69. package/dist/types.d.ts +360 -0
  70. package/dist/types.js +10 -0
  71. package/package.json +55 -7
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ import { Deepmerge, Effect, Layer, Logger } from "@withstudiocms/effect";
2
+ import CacheService from "./cache.js";
3
+ import { DBClientLive, makeSDKContext } from "./context.js";
4
+ import { makeLogger, setLoggerLevel } from "./lib/logger.js";
5
+ import SDKModules from "./modules/index.js";
6
+ export * from "./context.js";
7
+ const loggerLayer = Logger.replace(Logger.defaultLogger, makeLogger);
8
+ const SDKBaseDependencies = Layer.mergeAll(
9
+ CacheService.Default,
10
+ Deepmerge.Default,
11
+ setLoggerLevel,
12
+ loggerLayer
13
+ );
14
+ const StudioCMSSDKCore = Effect.all({
15
+ dbService: DBClientLive,
16
+ cache: CacheService,
17
+ ...SDKModules
18
+ }).pipe(Effect.provide(SDKBaseDependencies));
19
+ const makeStudioCMSSDKCoreLive = (context) => StudioCMSSDKCore.pipe(Effect.provide(makeSDKContext(context)));
20
+ export {
21
+ SDKBaseDependencies,
22
+ StudioCMSSDKCore,
23
+ makeStudioCMSSDKCoreLive
24
+ };
@@ -0,0 +1,39 @@
1
+ import { Effect } from '@withstudiocms/effect';
2
+ import { createTwoFilesPatch as diffCreateTwoFilesPatch } from 'diff';
3
+ import { type Diff2HtmlConfig } from 'diff2html';
4
+ declare const DiffError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
5
+ readonly _tag: "DiffError";
6
+ } & Readonly<A>;
7
+ /**
8
+ * Custom error class for diff-related operations in the SDK.
9
+ */
10
+ export declare class DiffError extends DiffError_base<{
11
+ cause: unknown;
12
+ }> {
13
+ }
14
+ /**
15
+ * Helper function to wrap diff-related operations with error handling.
16
+ *
17
+ * @param _try - A function that performs the desired operation.
18
+ * @returns An Effect that either succeeds with the result of the operation or fails with a DiffError.
19
+ */
20
+ export declare const useDiffError: <T>(_try: () => T) => Effect.Effect<T, DiffError, never>;
21
+ /**
22
+ * Creates a unified diff patch between two text inputs.
23
+ *
24
+ * @param oldStr - The original text.
25
+ * @param newStr - The modified text.
26
+ * @param fileNameOld - The name of the original file (default: 'OldFile').
27
+ * @param fileNameNew - The name of the modified file (default: 'NewFile').
28
+ * @returns An Effect that resolves to the unified diff string.
29
+ */
30
+ export declare const createTwoFilesPatch: <T>(fn: (patch: typeof diffCreateTwoFilesPatch) => T) => Effect.Effect<T, DiffError, never>;
31
+ /**
32
+ * Generates an HTML representation of the differences between two text inputs.
33
+ *
34
+ * @param diff - The unified diff string.
35
+ * @param options - Optional configuration for the diff HTML output.
36
+ * @returns An Effect that resolves to the HTML string representing the diff.
37
+ */
38
+ export declare const diffHTML: (diff: string, options?: Diff2HtmlConfig | undefined) => Effect.Effect<string, DiffError, never>;
39
+ export {};
@@ -0,0 +1,29 @@
1
+ import { Data, Effect } from "@withstudiocms/effect";
2
+ import { createTwoFilesPatch as diffCreateTwoFilesPatch } from "diff";
3
+ import { html } from "diff2html";
4
+ class DiffError extends Data.TaggedError("DiffError") {
5
+ }
6
+ const useDiffError = (_try) => Effect.try({
7
+ try: _try,
8
+ catch: (error) => new DiffError({ cause: error })
9
+ });
10
+ const createTwoFilesPatch = Effect.fn(
11
+ (fn) => useDiffError(() => fn(diffCreateTwoFilesPatch))
12
+ );
13
+ const diffHTML = Effect.fn(
14
+ (diff, options) => useDiffError(
15
+ () => html(diff, {
16
+ diffStyle: "word",
17
+ matching: "lines",
18
+ drawFileList: false,
19
+ outputFormat: "side-by-side",
20
+ ...options
21
+ })
22
+ )
23
+ );
24
+ export {
25
+ DiffError,
26
+ createTwoFilesPatch,
27
+ diffHTML,
28
+ useDiffError
29
+ };
@@ -0,0 +1,31 @@
1
+ import { Layer } from '@withstudiocms/effect';
2
+ export declare function stripNameFromLabel(label: string): string;
3
+ /**
4
+ * A cache that stores instances of `AstroIntegrationLogger` associated with their string keys.
5
+ * This is used to avoid creating multiple logger instances for the same key.
6
+ */
7
+ export declare const loggerCache: Map<string, SDKLogger>;
8
+ export type LoggerLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
9
+ export declare const levels: Record<LoggerLevel, number>;
10
+ export interface LogOptions {
11
+ level: LoggerLevel;
12
+ }
13
+ export declare const getEventPrefix: (level: LoggerLevel, label?: string) => string;
14
+ export declare class SDKLogger {
15
+ options: LogOptions;
16
+ label: string;
17
+ constructor(logging: LogOptions, label: string);
18
+ /**
19
+ * Creates a new logger instance with a new label, but the same log options.
20
+ */
21
+ fork(label: string): SDKLogger;
22
+ info(message: string): void;
23
+ warn(message: string): void;
24
+ error(message: string): void;
25
+ debug(message: string): void;
26
+ }
27
+ /**
28
+ * Sets the logger level based on the `STUDIOCMS_LOGLEVEL` environment variable,
29
+ * defaulting to `LogLevel.Info` if the variable is not set or invalid.
30
+ */
31
+ export declare const setLoggerLevel: Layer.Layer<never, import("effect/ConfigError").ConfigError, never>;
@@ -0,0 +1,131 @@
1
+ import { styleText } from "node:util";
2
+ import { Config, Effect, Layer, List, Logger, LogLevel } from "@withstudiocms/effect";
3
+ function stripNameFromLabel(label) {
4
+ const prefix = "studiocms/";
5
+ return label.startsWith(prefix) ? label.slice(prefix.length) : label;
6
+ }
7
+ const loggerCache = /* @__PURE__ */ new Map();
8
+ const levels = {
9
+ debug: 20,
10
+ info: 30,
11
+ warn: 40,
12
+ error: 50,
13
+ silent: 90
14
+ };
15
+ const dateTimeFormat = new Intl.DateTimeFormat([], {
16
+ hour: "2-digit",
17
+ minute: "2-digit",
18
+ second: "2-digit",
19
+ hour12: false
20
+ });
21
+ function getLevelPrefix(level) {
22
+ const levelLabel = level.toUpperCase();
23
+ switch (level) {
24
+ case "error":
25
+ return `[${levelLabel}]`;
26
+ case "warn":
27
+ return `[${levelLabel}]`;
28
+ case "debug":
29
+ return `[${levelLabel}]`;
30
+ default:
31
+ return "";
32
+ }
33
+ }
34
+ const getEventPrefix = (level, label) => {
35
+ const timestamp = `${dateTimeFormat.format(/* @__PURE__ */ new Date())}`;
36
+ const prefix = [];
37
+ if (level === "error" || level === "warn" || level === "debug") {
38
+ prefix.push(styleText("bold", timestamp));
39
+ prefix.push(getLevelPrefix(level));
40
+ } else {
41
+ prefix.push(timestamp);
42
+ }
43
+ if (label) {
44
+ prefix.push(`[${label}]`);
45
+ }
46
+ if (level === "error") {
47
+ return styleText("red", prefix.join(" "));
48
+ }
49
+ if (level === "warn") {
50
+ return styleText("yellow", prefix.join(" "));
51
+ }
52
+ if (level === "debug") {
53
+ return styleText("blue", prefix.join(" "));
54
+ }
55
+ if (prefix.length === 1) {
56
+ return styleText("dim", prefix[0]);
57
+ }
58
+ return `${styleText("dim", prefix[0])} ${styleText("blue", prefix.splice(1).join(" "))}`;
59
+ };
60
+ class SDKLogger {
61
+ options;
62
+ label;
63
+ constructor(logging, label) {
64
+ this.options = logging;
65
+ this.label = label;
66
+ }
67
+ /**
68
+ * Creates a new logger instance with a new label, but the same log options.
69
+ */
70
+ fork(label) {
71
+ return new SDKLogger(this.options, label);
72
+ }
73
+ info(message) {
74
+ console.log(`${getEventPrefix("info", this.label)} ${message}`);
75
+ }
76
+ warn(message) {
77
+ console.warn(`${getEventPrefix("warn", this.label)} \u26A0\uFE0F ${message}`);
78
+ }
79
+ error(message) {
80
+ console.error(`${getEventPrefix("error", this.label)} \u274C ${message}`);
81
+ }
82
+ debug(message) {
83
+ console.debug(`${getEventPrefix("debug", this.label)} \u{1F41B} ${message}`);
84
+ }
85
+ }
86
+ const _logger = new SDKLogger({ level: "info" }, "studiocms:runtime");
87
+ const makeLogger = Logger.make(({ logLevel, message: _message, spans }) => {
88
+ const label = "sdk";
89
+ const logger = loggerCache.get(label) ?? _logger.fork(`studiocms:runtime/${stripNameFromLabel(label)}`);
90
+ loggerCache.set(label, logger);
91
+ const list = List.toArray(spans);
92
+ const spanPart = list.length ? ` :: ${list.join(" \u203A ")}` : "";
93
+ const message = `${String(_message)}${spanPart}`;
94
+ switch (logLevel) {
95
+ case LogLevel.Trace:
96
+ case LogLevel.Debug: {
97
+ logger.debug(`${message}`);
98
+ break;
99
+ }
100
+ case LogLevel.Error:
101
+ case LogLevel.Fatal: {
102
+ logger.error(`${message}`);
103
+ break;
104
+ }
105
+ case LogLevel.Warning: {
106
+ logger.warn(`${message}`);
107
+ break;
108
+ }
109
+ case LogLevel.All:
110
+ case LogLevel.Info: {
111
+ logger.info(message);
112
+ break;
113
+ }
114
+ default: {
115
+ logger.info(message);
116
+ }
117
+ }
118
+ });
119
+ const setLoggerLevel = Config.withDefault(
120
+ Config.logLevel("STUDIOCMS_LOGLEVEL"),
121
+ LogLevel.Info
122
+ ).pipe(Effect.andThen(Logger.minimumLogLevel), Layer.unwrapEffect);
123
+ export {
124
+ SDKLogger,
125
+ getEventPrefix,
126
+ levels,
127
+ loggerCache,
128
+ makeLogger,
129
+ setLoggerLevel,
130
+ stripNameFromLabel
131
+ };
@@ -0,0 +1,221 @@
1
+ import { Effect, Schema } from '@withstudiocms/effect';
2
+ import type { StudioCMSPluginData } from '@withstudiocms/kysely/tables';
3
+ import type { z } from 'zod';
4
+ /**
5
+ * Represents a plugin data entry with a strongly-typed `data` property.
6
+ *
7
+ * @template T - The type of the `data` property.
8
+ * @property {T} data - The plugin-specific data payload.
9
+ */
10
+ export interface PluginDataEntry<T extends object> extends Omit<(typeof StudioCMSPluginData)['Select']['Type'], 'data'> {
11
+ data: T;
12
+ }
13
+ /**
14
+ * Represents a JSON validator function for a specific type.
15
+ *
16
+ * @template T - The type that the validator function checks for.
17
+ * @property jsonFn - A type guard function that determines if the provided data is of type T.
18
+ */
19
+ export interface JSONValidatorFn<T> {
20
+ jsonFn: (data: unknown) => data is T;
21
+ }
22
+ /**
23
+ * Interface representing a validator for an effect schema.
24
+ *
25
+ * @typeParam T - The type of the value that the schema validates.
26
+ *
27
+ * @property effectSchema - The schema used for validation, which takes a value of type `T` and returns either a `ParseError` or `never`.
28
+ */
29
+ export interface EffectSchemaValidator<E extends Schema.Struct<any>> {
30
+ effectSchema: E;
31
+ }
32
+ /**
33
+ * Interface representing a validator that uses a Zod schema to validate data of type `T`.
34
+ *
35
+ * @template T - The type of data to be validated.
36
+ * @property zodSchema - The Zod schema instance used for validation.
37
+ */
38
+ export interface ZodValidator<T> {
39
+ zodSchema: z.ZodSchema<T>;
40
+ }
41
+ /**
42
+ * Represents the available validator options for a given type `T`.
43
+ *
44
+ * This type is a union of supported validator types:
45
+ * - `JSONValidatorFn<T>`: A function-based JSON validator for type `T`.
46
+ * - `EffectSchemaValidator<T>`: A validator using the Effect schema for type `T`.
47
+ * - `ZodValidator<T>`: A validator using the Zod schema for type `T`.
48
+ *
49
+ * @template T - The type to be validated.
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * // The Interface for a User type
54
+ * interface User {
55
+ * id: number;
56
+ * name: string;
57
+ * email: string;
58
+ * }
59
+ *
60
+ * // Example of defining a JSON validator Fn for a User type
61
+ * const userValidator: ValidatorOptions<User> = {
62
+ * jsonFn: (data: unknown): data is User => {
63
+ * return (
64
+ * typeof data === 'object' &&
65
+ * data !== null &&
66
+ * 'id' in data &&
67
+ * 'name' in data &&
68
+ * 'email' in data &&
69
+ * typeof (data as any).id === 'number' &&
70
+ * typeof (data as any).name === 'string' &&
71
+ * typeof (data as any).email === 'string'
72
+ * );
73
+ * }
74
+ * };
75
+ *
76
+ * // Example of defining an Effect schema validator for a User type
77
+ * import { Schema } from 'studiocms/effect';
78
+ *
79
+ * const userEffectSchema = Schema.Struct({
80
+ * id: Schema.Number,
81
+ * name: Schema.String,
82
+ * email: Schema.String
83
+ * });
84
+ *
85
+ * type UserEffectSchema = (typeof userEffectSchema)['Type'];
86
+ * type UserEffectSchemaFields = (typeof userEffectSchema)['fields'];
87
+ *
88
+ * const userEffectValidator: ValidatorOptions<UserEffectSchema, UserEffectSchemaFields> = {
89
+ * effectSchema: userEffectSchema
90
+ * };
91
+ *
92
+ * // Example of defining a Zod validator for a User type
93
+ * import { z } from 'astro/zod';
94
+ *
95
+ * const userZodValidator: ValidatorOptions<User> = {
96
+ * zodSchema: z.object({
97
+ * id: z.number(),
98
+ * name: z.string(),
99
+ * email: z.string()
100
+ * })
101
+ * };
102
+ * ```
103
+ */
104
+ export type ValidatorOptions<T extends Schema.Struct<any> | object> = T extends Schema.Struct<any> ? EffectSchemaValidator<T> : JSONValidatorFn<T> | ZodValidator<T>;
105
+ export type RecursiveSimplifyMutable<A> = {
106
+ -readonly [K in keyof A]: A[K] extends object ? RecursiveSimplifyMutable<A[K]> : A[K];
107
+ } extends infer B ? B : never;
108
+ /**
109
+ * Enum representing the possible responses when selecting plugin data,
110
+ * indicating whether the existence of the data should cause a failure or not.
111
+ *
112
+ * @enum {string}
113
+ * @property {string} ExistsNoFail - The plugin data exists and should not cause a failure.
114
+ * @property {string} ExistsShouldFail - The plugin data exists and should cause a failure.
115
+ */
116
+ export declare enum SelectPluginDataRespondOrFail {
117
+ ExistsNoFail = "existsNoFail",
118
+ ExistsShouldFail = "existsShouldFail",
119
+ NotExistsShouldFail = "notExistsShouldFail"
120
+ }
121
+ /**
122
+ * Wraps the provided `id` and `data` into a `PluginDataEntry<T>` object and returns it as an Effect.
123
+ *
124
+ * @template T - The type of the data to be wrapped.
125
+ * @param id - The unique identifier for the plugin data entry.
126
+ * @param data - The data to be associated with the given id.
127
+ * @returns An Effect that, when executed, yields a `PluginDataEntry<T>` containing the provided id and data.
128
+ */
129
+ export declare const parsedDataResponse: <T extends object>(id: string, data: T) => Effect.Effect<PluginDataEntry<T>, never, never>;
130
+ /**
131
+ * Filters out `undefined` and `null` values from an array of entries.
132
+ *
133
+ * @typeParam T - The type of the array elements.
134
+ * @param entries - An array containing elements of type `T` or `undefined`.
135
+ * @returns A new array containing only the defined (non-`undefined`, non-`null`) entries of type `T`.
136
+ */
137
+ export declare function noUndefinedEntries<T>(entries: (T | undefined)[]): T[];
138
+ /**
139
+ * Returns a function that validates a boolean condition and either returns the provided value
140
+ * cast to type `T` if the condition is true, or throws an error if the condition is false.
141
+ *
142
+ * @typeParam T - The expected type of the validated object.
143
+ * @param data - The value to be validated and potentially returned as type `T`.
144
+ * @returns A function that takes a boolean indicating validation success.
145
+ * @throws {Error} If the boolean argument is false, throws an error with the serialized value.
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * const validateUser = isJsonValid<User>(userData);
150
+ * const user = validateUser(isUserValid); // Returns userData as User if valid, otherwise throws.
151
+ * ```
152
+ */
153
+ export declare const isJsonValid: <T extends object>(data: unknown) => (isValid: boolean) => T;
154
+ /**
155
+ * Returns a validator function based on the provided validator options.
156
+ *
157
+ * This function supports three types of validators:
158
+ * - `jsonFn`: A custom JSON validation function.
159
+ * - `effectSchema`: An Effect schema for validation.
160
+ * - `zodSchema`: A Zod schema for validation.
161
+ *
162
+ * The returned validator function takes unknown data and attempts to validate it
163
+ * according to the specified validator. If validation succeeds, the data is returned
164
+ * as type `T`. If validation fails, an error is thrown or returned as an Effect error.
165
+ *
166
+ * @typeParam T - The expected type of the validated data.
167
+ * @param validator - The validator options, which must include one of: `jsonFn`, `effectSchema`, or `zodSchema`.
168
+ * @returns A function that takes unknown data and returns an Effect that resolves to type `T` if validation succeeds, or fails with an error if validation fails.
169
+ * @throws Error if none of the expected validator options are provided.
170
+ */
171
+ export declare const getValidatorFn: <T extends Schema.Struct<Schema.Struct.Fields> | object>(validator: ValidatorOptions<T>) => Effect.Effect<(data: unknown) => Effect.Effect<T, Error, never>, Error, never>;
172
+ /**
173
+ * Parses and validates plugin data from a raw input, supporting multiple validation strategies.
174
+ *
175
+ * This function attempts to parse the provided `rawData`, which can be either a JSON string or an object.
176
+ * If a validator is provided, it validates the parsed data using one of the supported validation methods:
177
+ * - JSON function (`jsonFn`)
178
+ * - Effect schema (`effectSchema`)
179
+ * - Zod schema (`zodSchema`)
180
+ *
181
+ * If no validator is provided, the parsed data is returned as is.
182
+ * If validation fails or the input format is invalid, an error is yielded.
183
+ *
184
+ * @typeParam T - The expected type of the parsed and validated data.
185
+ * @param rawData - The raw input data, which can be a JSON string or an object.
186
+ * @param validator - Optional. An object specifying the validation strategy to use.
187
+ * @returns An `Effect` yielding the parsed and validated data of type `T`, or an error if parsing or validation fails.
188
+ *
189
+ * @throws {Error} If the input is neither a string nor an object, or if parsing/validation fails.
190
+ */
191
+ export declare const parseData: <T extends Schema.Struct<Schema.Struct.Fields> | object>(rawData: unknown, validator?: ValidatorOptions<T> | undefined) => Effect.Effect<T, Error, never>;
192
+ /**
193
+ * Base options for using plugin data.
194
+ *
195
+ * @template T - The type of the data object.
196
+ * @property [Type] - An optional type definition for the data.
197
+ * @property [validator] - Optional validator options for the data type.
198
+ */
199
+ export interface UsePluginDataOptsBase<T extends Schema.Struct<Schema.Struct.Fields> | object> {
200
+ Type?: T;
201
+ validator?: ValidatorOptions<T>;
202
+ }
203
+ /**
204
+ * Options for using plugin data, extending the base options with an entry identifier.
205
+ *
206
+ * @template T - The type of the plugin data object.
207
+ * @extends UsePluginDataOptsBase<T>
208
+ *
209
+ * @property entryId - The unique identifier for the entry associated with the plugin data.
210
+ */
211
+ export interface UsePluginDataOpts<T extends Schema.Struct<Schema.Struct.Fields> | object> extends UsePluginDataOptsBase<T> {
212
+ entryId: string;
213
+ }
214
+ /**
215
+ * Represents a partial implementation of the `UsePluginDataOpts` type for a given object type `T`.
216
+ *
217
+ * This type is useful when you want to provide only a subset of the properties defined in `UsePluginDataOpts<T>`.
218
+ *
219
+ * @typeParam T - The object type for which the plugin data options are defined.
220
+ */
221
+ export type UserPluginDataOptsImplementation<T extends Schema.Struct<Schema.Struct.Fields> | object> = Partial<UsePluginDataOpts<T>>;
@@ -0,0 +1,80 @@
1
+ import { Effect, pipe, Schema } from "@withstudiocms/effect";
2
+ var SelectPluginDataRespondOrFail = /* @__PURE__ */ ((SelectPluginDataRespondOrFail2) => {
3
+ SelectPluginDataRespondOrFail2["ExistsNoFail"] = "existsNoFail";
4
+ SelectPluginDataRespondOrFail2["ExistsShouldFail"] = "existsShouldFail";
5
+ SelectPluginDataRespondOrFail2["NotExistsShouldFail"] = "notExistsShouldFail";
6
+ return SelectPluginDataRespondOrFail2;
7
+ })(SelectPluginDataRespondOrFail || {});
8
+ const parsedDataResponse = (id, data) => Effect.succeed({
9
+ id,
10
+ data
11
+ });
12
+ function noUndefinedEntries(entries) {
13
+ return entries.filter((entry) => entry !== void 0 && entry !== null);
14
+ }
15
+ const isJsonValid = (data) => (isValid) => {
16
+ if (isValid) return data;
17
+ throw new Error("Validation failed for plugin data");
18
+ };
19
+ const getValidatorFn = Effect.fn("studiocms/sdk/effect/pluginUtils/getValidatorFn")(
20
+ function* (validator) {
21
+ if ("jsonFn" in validator) {
22
+ return (data) => Effect.try({
23
+ try: () => pipe(validator.jsonFn(data), isJsonValid(data)),
24
+ catch: (error) => new Error(`JSON validation failed: ${error.message}`)
25
+ });
26
+ }
27
+ if ("effectSchema" in validator) {
28
+ return (data) => Schema.decodeUnknown(validator.effectSchema)(data).pipe(
29
+ Effect.mapError(
30
+ (error) => new Error(`Schema validation failed: ${error.message}`)
31
+ )
32
+ );
33
+ }
34
+ if ("zodSchema" in validator) {
35
+ return (data) => Effect.try({
36
+ try: () => {
37
+ const result = validator.zodSchema.safeParse(data);
38
+ if (result.success) {
39
+ return result.data;
40
+ }
41
+ throw new Error(`Zod validation failed: ${result.error.message}`, {
42
+ cause: result.error.cause
43
+ });
44
+ },
45
+ catch: (error) => new Error(error.message, { cause: error.cause })
46
+ });
47
+ }
48
+ return yield* Effect.fail(
49
+ new Error(
50
+ "Invalid validator options provided, expected one of: jsonFn, effectSchema, or zodSchema"
51
+ )
52
+ );
53
+ }
54
+ );
55
+ const parseData = Effect.fn("studiocms/sdk/effect/pluginUtils/parseData")(function* (rawData, validator) {
56
+ let parsedInput;
57
+ if (typeof rawData === "string") {
58
+ parsedInput = yield* Effect.try({
59
+ try: () => JSON.parse(rawData),
60
+ catch: (error) => new Error(`JSON parsing failed: ${error}`)
61
+ });
62
+ } else if (rawData !== null && typeof rawData === "object") {
63
+ parsedInput = rawData;
64
+ } else {
65
+ return yield* Effect.fail(new Error(`Invalid plugin data format: ${typeof rawData}`));
66
+ }
67
+ if (!validator || validator === void 0) {
68
+ return parsedInput;
69
+ }
70
+ const validatorFn = yield* getValidatorFn(validator);
71
+ return yield* validatorFn(parsedInput);
72
+ });
73
+ export {
74
+ SelectPluginDataRespondOrFail,
75
+ getValidatorFn,
76
+ isJsonValid,
77
+ noUndefinedEntries,
78
+ parseData,
79
+ parsedDataResponse
80
+ };