@no-mess/client 0.1.1 → 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 CHANGED
@@ -53,11 +53,136 @@ The `useNoMessPreview` hook handles the postMessage handshake between the no-mes
53
53
  const products = await client.getProducts();
54
54
  const product = await client.getProduct("product-handle");
55
55
  const collections = await client.getCollections();
56
+ const collection = await client.getCollection("collection-handle");
56
57
  ```
57
58
 
58
- ## API reference
59
+ ## Configuration
59
60
 
60
- Full documentation at [no-mess.xyz/docs/sdk](https://no-mess.xyz/docs/sdk).
61
+ ```ts
62
+ const client = createNoMessClient({
63
+ apiKey: "nm_...", // Required — secret or publishable key
64
+ apiUrl: "https://...", // Optional — defaults to https://api.no-mess.xyz
65
+ });
66
+ ```
67
+
68
+ ### API Key Types
69
+
70
+ - **Secret keys** (`nm_...`) — Full access. Use server-side only.
71
+ - **Publishable keys** (`nm_pub_...`) — Read-only access to published content. Safe for client-side use.
72
+
73
+ ## API Reference
74
+
75
+ ### Content
76
+
77
+ | Method | Description |
78
+ |--------|-------------|
79
+ | `client.getSchemas()` | List all content type schemas |
80
+ | `client.getSchema(typeSlug)` | Get a single schema by slug |
81
+ | `client.getEntries(contentType)` | Fetch all published entries of a content type |
82
+ | `client.getEntry(contentType, slug)` | Get a single entry by slug |
83
+
84
+ ### Shopify
85
+
86
+ | Method | Description |
87
+ |--------|-------------|
88
+ | `client.getProducts()` | List all synced Shopify products |
89
+ | `client.getProduct(handle)` | Get a product by handle |
90
+ | `client.getCollections()` | List all synced Shopify collections |
91
+ | `client.getCollection(handle)` | Get a collection by handle |
92
+
93
+ ### Preview
94
+
95
+ | Method | Description |
96
+ |--------|-------------|
97
+ | `client.exchangePreviewSession(session)` | Exchange a preview session token (HMAC-SHA256 auth) |
98
+
99
+ ### React Hooks (`@no-mess/client/react`)
100
+
101
+ | Hook | Description |
102
+ |------|-------------|
103
+ | `useNoMessPreview(config)` | Subscribe to live preview updates in an iframe |
104
+ | `useNoMessLiveEdit(config)` | Enable live editing with field-level updates |
105
+
106
+ ## Schema Builder
107
+
108
+ The `@no-mess/client/schema` export provides helpers for defining content type schemas in code. Used by the [no-mess CLI](../no-mess-cli) to push and pull schemas.
109
+
110
+ ```ts
111
+ import { defineSchema, defineContentType, field } from "@no-mess/client/schema";
112
+
113
+ export default defineSchema({
114
+ contentTypes: [
115
+ defineContentType("blog-post", {
116
+ name: "Blog Post",
117
+ description: "Articles for the blog",
118
+ fields: {
119
+ title: field.text({ required: true }),
120
+ body: field.textarea({ required: true }),
121
+ heroImage: field.image(),
122
+ publishedAt: field.datetime(),
123
+ featured: field.boolean(),
124
+ externalUrl: field.url(),
125
+ category: field.select({
126
+ choices: [
127
+ { label: "Tech", value: "tech" },
128
+ { label: "Design", value: "design" },
129
+ ],
130
+ }),
131
+ relatedProduct: field.shopifyProduct(),
132
+ featuredCollection: field.shopifyCollection(),
133
+ },
134
+ }),
135
+ ],
136
+ });
137
+ ```
138
+
139
+ ### Field Types
140
+
141
+ | Builder | Type | Description |
142
+ |---------|------|-------------|
143
+ | `field.text()` | `text` | Plain text input |
144
+ | `field.textarea()` | `textarea` | Multi-line text |
145
+ | `field.number()` | `number` | Numeric value |
146
+ | `field.boolean()` | `boolean` | True/false toggle |
147
+ | `field.datetime()` | `datetime` | Date/time picker |
148
+ | `field.url()` | `url` | URL field |
149
+ | `field.image()` | `image` | Image upload |
150
+ | `field.select(opts)` | `select` | Dropdown with choices (requires `choices` array) |
151
+ | `field.shopifyProduct()` | `shopifyProduct` | Shopify product reference |
152
+ | `field.shopifyCollection()` | `shopifyCollection` | Shopify collection reference |
153
+
154
+ ### Field Options
155
+
156
+ All field builders accept an options object:
157
+
158
+ ```ts
159
+ field.text({
160
+ required: true, // Whether the field is required (default: false)
161
+ description: "...", // Help text shown in the dashboard
162
+ })
163
+ ```
164
+
165
+ The `select` builder additionally requires a `choices` array:
166
+
167
+ ```ts
168
+ field.select({
169
+ required: true,
170
+ choices: [
171
+ { label: "Draft", value: "draft" },
172
+ { label: "Published", value: "published" },
173
+ ],
174
+ })
175
+ ```
176
+
177
+ ### Schema Utilities
178
+
179
+ | Function | Description |
180
+ |----------|-------------|
181
+ | `defineSchema({ contentTypes })` | Define a complete schema with content types |
182
+ | `defineContentType(slug, options)` | Define a single content type |
183
+ | `parseSchemaSource(source)` | Parse a schema.ts source string into a schema definition |
184
+ | `generateSchemaSource(schema)` | Generate schema.ts source from a schema definition |
185
+ | `generateContentTypeSource(contentType)` | Generate source for a single content type |
61
186
 
62
187
  ## License
63
188
 
@@ -0,0 +1,13 @@
1
+ import type { FieldBuilderResult } from "./field-builders";
2
+ import type { ContentTypeDefinition } from "./schema-types";
3
+ export interface ContentTypeConfig {
4
+ name: string;
5
+ description?: string;
6
+ fields: Record<string, FieldBuilderResult>;
7
+ }
8
+ /**
9
+ * Defines a content type from a slug and configuration object.
10
+ * Converts field builder results into FieldDefinition[].
11
+ */
12
+ export declare function defineContentType(slug: string, config: ContentTypeConfig): ContentTypeDefinition;
13
+ //# sourceMappingURL=define-content-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-content-type.d.ts","sourceRoot":"","sources":["../../src/schema/define-content-type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAmB,MAAM,gBAAgB,CAAC;AAE7E,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CAC5C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,iBAAiB,GACxB,qBAAqB,CAgCvB"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Defines a content type from a slug and configuration object.
3
+ * Converts field builder results into FieldDefinition[].
4
+ */
5
+ export function defineContentType(slug, config) {
6
+ const fields = Object.entries(config.fields).map(([name, builder]) => {
7
+ const def = {
8
+ name,
9
+ type: builder._type,
10
+ required: builder._required,
11
+ };
12
+ if (builder._description) {
13
+ def.description = builder._description;
14
+ }
15
+ if (builder._options) {
16
+ def.options = {};
17
+ if (builder._options.choices) {
18
+ def.options.choices = builder._options.choices;
19
+ }
20
+ }
21
+ return def;
22
+ });
23
+ const result = {
24
+ slug,
25
+ name: config.name,
26
+ fields,
27
+ };
28
+ if (config.description) {
29
+ result.description = config.description;
30
+ }
31
+ return result;
32
+ }
33
+ //# sourceMappingURL=define-content-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-content-type.js","sourceRoot":"","sources":["../../src/schema/define-content-type.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAY,EACZ,MAAyB;IAEzB,MAAM,MAAM,GAAsB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CACjE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE;QAClB,MAAM,GAAG,GAAoB;YAC3B,IAAI;YACJ,IAAI,EAAE,OAAO,CAAC,KAAK;YACnB,QAAQ,EAAE,OAAO,CAAC,SAAS;SAC5B,CAAC;QACF,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACzB,GAAG,CAAC,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;QACzC,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,GAAG,CAAC,OAAO,GAAG,EAAE,CAAC;YACjB,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBAC7B,GAAG,CAAC,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;YACjD,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CACF,CAAC;IAEF,MAAM,MAAM,GAA0B;QACpC,IAAI;QACJ,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,MAAM;KACP,CAAC;IAEF,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IAC1C,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ContentTypeDefinition, SchemaDefinition } from "./schema-types";
2
+ export interface SchemaConfig {
3
+ contentTypes: ContentTypeDefinition[];
4
+ }
5
+ /**
6
+ * Wraps content type definitions into a SchemaDefinition.
7
+ */
8
+ export declare function defineSchema(config: SchemaConfig): SchemaDefinition;
9
+ //# sourceMappingURL=define-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-schema.d.ts","sourceRoot":"","sources":["../../src/schema/define-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE9E,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,qBAAqB,EAAE,CAAC;CACvC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,gBAAgB,CAInE"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Wraps content type definitions into a SchemaDefinition.
3
+ */
4
+ export function defineSchema(config) {
5
+ return {
6
+ contentTypes: config.contentTypes,
7
+ };
8
+ }
9
+ //# sourceMappingURL=define-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-schema.js","sourceRoot":"","sources":["../../src/schema/define-schema.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAoB;IAC/C,OAAO;QACL,YAAY,EAAE,MAAM,CAAC,YAAY;KAClC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { FieldType } from "./schema-types";
2
+ export interface FieldBuilderOptions {
3
+ required?: boolean;
4
+ description?: string;
5
+ }
6
+ export interface SelectChoice {
7
+ label: string;
8
+ value: string;
9
+ }
10
+ export interface SelectFieldOptions extends FieldBuilderOptions {
11
+ choices: SelectChoice[];
12
+ }
13
+ export interface FieldBuilderResult {
14
+ _type: FieldType;
15
+ _required: boolean;
16
+ _description?: string;
17
+ _options?: {
18
+ choices?: SelectChoice[];
19
+ };
20
+ }
21
+ export declare const field: {
22
+ text: (opts?: FieldBuilderOptions) => FieldBuilderResult;
23
+ textarea: (opts?: FieldBuilderOptions) => FieldBuilderResult;
24
+ number: (opts?: FieldBuilderOptions) => FieldBuilderResult;
25
+ boolean: (opts?: FieldBuilderOptions) => FieldBuilderResult;
26
+ datetime: (opts?: FieldBuilderOptions) => FieldBuilderResult;
27
+ url: (opts?: FieldBuilderOptions) => FieldBuilderResult;
28
+ image: (opts?: FieldBuilderOptions) => FieldBuilderResult;
29
+ select: (opts: SelectFieldOptions) => FieldBuilderResult;
30
+ shopifyProduct: (opts?: FieldBuilderOptions) => FieldBuilderResult;
31
+ shopifyCollection: (opts?: FieldBuilderOptions) => FieldBuilderResult;
32
+ };
33
+ //# sourceMappingURL=field-builders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-builders.d.ts","sourceRoot":"","sources":["../../src/schema/field-builders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;IAC7D,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;KAC1B,CAAC;CACH;AAUD,eAAO,MAAM,KAAK;kBAPD,mBAAmB,KAAG,kBAAkB;sBAAxC,mBAAmB,KAAG,kBAAkB;oBAAxC,mBAAmB,KAAG,kBAAkB;qBAAxC,mBAAmB,KAAG,kBAAkB;sBAAxC,mBAAmB,KAAG,kBAAkB;iBAAxC,mBAAmB,KAAG,kBAAkB;mBAAxC,mBAAmB,KAAG,kBAAkB;mBAexC,kBAAkB,KAAG,kBAAkB;4BAfvC,mBAAmB,KAAG,kBAAkB;+BAAxC,mBAAmB,KAAG,kBAAkB;CAuBxD,CAAC"}
@@ -0,0 +1,25 @@
1
+ function createFieldBuilder(type) {
2
+ return (opts) => ({
3
+ _type: type,
4
+ _required: opts?.required ?? false,
5
+ _description: opts?.description,
6
+ });
7
+ }
8
+ export const field = {
9
+ text: createFieldBuilder("text"),
10
+ textarea: createFieldBuilder("textarea"),
11
+ number: createFieldBuilder("number"),
12
+ boolean: createFieldBuilder("boolean"),
13
+ datetime: createFieldBuilder("datetime"),
14
+ url: createFieldBuilder("url"),
15
+ image: createFieldBuilder("image"),
16
+ select: (opts) => ({
17
+ _type: "select",
18
+ _required: opts.required ?? false,
19
+ _description: opts.description,
20
+ _options: { choices: opts.choices },
21
+ }),
22
+ shopifyProduct: createFieldBuilder("shopifyProduct"),
23
+ shopifyCollection: createFieldBuilder("shopifyCollection"),
24
+ };
25
+ //# sourceMappingURL=field-builders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-builders.js","sourceRoot":"","sources":["../../src/schema/field-builders.ts"],"names":[],"mappings":"AAyBA,SAAS,kBAAkB,CAAC,IAAe;IACzC,OAAO,CAAC,IAA0B,EAAsB,EAAE,CAAC,CAAC;QAC1D,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,IAAI,EAAE,QAAQ,IAAI,KAAK;QAClC,YAAY,EAAE,IAAI,EAAE,WAAW;KAChC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC;IAChC,QAAQ,EAAE,kBAAkB,CAAC,UAAU,CAAC;IACxC,MAAM,EAAE,kBAAkB,CAAC,QAAQ,CAAC;IACpC,OAAO,EAAE,kBAAkB,CAAC,SAAS,CAAC;IACtC,QAAQ,EAAE,kBAAkB,CAAC,UAAU,CAAC;IACxC,GAAG,EAAE,kBAAkB,CAAC,KAAK,CAAC;IAC9B,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC;IAClC,MAAM,EAAE,CAAC,IAAwB,EAAsB,EAAE,CAAC,CAAC;QACzD,KAAK,EAAE,QAAQ;QACf,SAAS,EAAE,IAAI,CAAC,QAAQ,IAAI,KAAK;QACjC,YAAY,EAAE,IAAI,CAAC,WAAW;QAC9B,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;KACpC,CAAC;IACF,cAAc,EAAE,kBAAkB,CAAC,gBAAgB,CAAC;IACpD,iBAAiB,EAAE,kBAAkB,CAAC,mBAAmB,CAAC;CAC3D,CAAC"}
@@ -0,0 +1,12 @@
1
+ export type { FieldType, FieldDefinition, ContentTypeDefinition, SchemaDefinition, } from "./schema-types";
2
+ export { FIELD_TYPES } from "./schema-types";
3
+ export type { FieldBuilderOptions, SelectChoice, SelectFieldOptions, FieldBuilderResult, } from "./field-builders";
4
+ export { field } from "./field-builders";
5
+ export type { ContentTypeConfig } from "./define-content-type";
6
+ export { defineContentType } from "./define-content-type";
7
+ export type { SchemaConfig } from "./define-schema";
8
+ export { defineSchema } from "./define-schema";
9
+ export type { ParseError, ParseWarning, ParseResult } from "./parse-schema";
10
+ export { parseSchemaSource } from "./parse-schema";
11
+ export { generateSchemaSource, generateContentTypeSource, } from "./serialize-schema";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,SAAS,EACT,eAAe,EACf,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,YAAY,EACV,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EACL,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { FIELD_TYPES } from "./schema-types";
2
+ export { field } from "./field-builders";
3
+ export { defineContentType } from "./define-content-type";
4
+ export { defineSchema } from "./define-schema";
5
+ export { parseSchemaSource } from "./parse-schema";
6
+ export { generateSchemaSource, generateContentTypeSource, } from "./serialize-schema";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAQ7C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAGzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG1D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EACL,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { type ContentTypeDefinition } from "./schema-types";
2
+ export interface ParseError {
3
+ line: number;
4
+ column: number;
5
+ message: string;
6
+ }
7
+ export interface ParseWarning {
8
+ line: number;
9
+ message: string;
10
+ }
11
+ export interface ParseResult {
12
+ success: boolean;
13
+ contentTypes: ContentTypeDefinition[];
14
+ errors: ParseError[];
15
+ warnings: ParseWarning[];
16
+ }
17
+ /**
18
+ * Parses schema DSL source text and extracts ContentTypeDefinition[].
19
+ * Custom recursive-descent parser — no TS compiler, no eval.
20
+ * Never throws; returns partial results + errors.
21
+ */
22
+ export declare function parseSchemaSource(source: string): ParseResult;
23
+ //# sourceMappingURL=parse-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-schema.d.ts","sourceRoot":"","sources":["../../src/schema/parse-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,qBAAqB,EAG3B,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,qBAAqB,EAAE,CAAC;IACtC,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAID;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CA6C7D"}
@@ -0,0 +1,419 @@
1
+ import { FIELD_TYPES, } from "./schema-types";
2
+ const FIELD_TYPE_SET = new Set(FIELD_TYPES);
3
+ /**
4
+ * Parses schema DSL source text and extracts ContentTypeDefinition[].
5
+ * Custom recursive-descent parser — no TS compiler, no eval.
6
+ * Never throws; returns partial results + errors.
7
+ */
8
+ export function parseSchemaSource(source) {
9
+ const errors = [];
10
+ const warnings = [];
11
+ const contentTypes = [];
12
+ // Strip comments (line and block) while preserving line positions
13
+ const stripped = stripComments(source);
14
+ // Find all defineContentType( occurrences
15
+ const pattern = /defineContentType\s*\(/g;
16
+ let match;
17
+ while ((match = pattern.exec(stripped)) !== null) {
18
+ const startIdx = match.index + match[0].length;
19
+ const line = lineAt(source, match.index);
20
+ try {
21
+ const result = parseDefineContentTypeArgs(stripped, startIdx, line);
22
+ if (result.contentType) {
23
+ contentTypes.push(result.contentType);
24
+ }
25
+ if (result.errors.length > 0) {
26
+ errors.push(...result.errors);
27
+ }
28
+ if (result.warnings.length > 0) {
29
+ warnings.push(...result.warnings);
30
+ }
31
+ }
32
+ catch {
33
+ errors.push({
34
+ line,
35
+ column: 0,
36
+ message: "Failed to parse defineContentType call",
37
+ });
38
+ }
39
+ }
40
+ // Also support standalone defineSchema({ contentTypes: [...] }) wrapping
41
+ // The individual defineContentType calls inside are already captured above
42
+ return {
43
+ success: errors.length === 0 && contentTypes.length > 0,
44
+ contentTypes,
45
+ errors,
46
+ warnings,
47
+ };
48
+ }
49
+ /**
50
+ * Strip line comments (//) and block comments while preserving newlines.
51
+ */
52
+ function stripComments(source) {
53
+ let result = "";
54
+ let i = 0;
55
+ let inString = null;
56
+ let escaped = false;
57
+ while (i < source.length) {
58
+ const ch = source[i];
59
+ const next = source[i + 1];
60
+ if (escaped) {
61
+ result += ch;
62
+ escaped = false;
63
+ i++;
64
+ continue;
65
+ }
66
+ if (inString) {
67
+ if (ch === "\\") {
68
+ escaped = true;
69
+ result += ch;
70
+ i++;
71
+ continue;
72
+ }
73
+ if (ch === inString) {
74
+ inString = null;
75
+ }
76
+ result += ch;
77
+ i++;
78
+ continue;
79
+ }
80
+ // Template literals
81
+ if (ch === "`") {
82
+ inString = "`";
83
+ result += ch;
84
+ i++;
85
+ continue;
86
+ }
87
+ if (ch === '"' || ch === "'") {
88
+ inString = ch;
89
+ result += ch;
90
+ i++;
91
+ continue;
92
+ }
93
+ // Line comment
94
+ if (ch === "/" && next === "/") {
95
+ while (i < source.length && source[i] !== "\n") {
96
+ result += " ";
97
+ i++;
98
+ }
99
+ continue;
100
+ }
101
+ // Block comment
102
+ if (ch === "/" && next === "*") {
103
+ i += 2;
104
+ while (i < source.length) {
105
+ if (source[i] === "*" && source[i + 1] === "/") {
106
+ i += 2;
107
+ break;
108
+ }
109
+ result += source[i] === "\n" ? "\n" : " ";
110
+ i++;
111
+ }
112
+ continue;
113
+ }
114
+ result += ch;
115
+ i++;
116
+ }
117
+ return result;
118
+ }
119
+ function lineAt(source, index) {
120
+ let line = 1;
121
+ for (let i = 0; i < index && i < source.length; i++) {
122
+ if (source[i] === "\n")
123
+ line++;
124
+ }
125
+ return line;
126
+ }
127
+ function columnAt(source, index) {
128
+ let col = 1;
129
+ for (let i = index - 1; i >= 0; i--) {
130
+ if (source[i] === "\n")
131
+ break;
132
+ col++;
133
+ }
134
+ return col;
135
+ }
136
+ /**
137
+ * Parse the arguments of defineContentType(slug, config).
138
+ * `startIdx` points to the character after the opening `(`.
139
+ */
140
+ function parseDefineContentTypeArgs(source, startIdx, baseLine) {
141
+ const errors = [];
142
+ const warnings = [];
143
+ let i = skipWhitespace(source, startIdx);
144
+ // Parse slug (first string argument)
145
+ const slugResult = parseStringLiteral(source, i);
146
+ if (!slugResult) {
147
+ errors.push({
148
+ line: baseLine,
149
+ column: columnAt(source, i),
150
+ message: "Expected string literal for content type slug",
151
+ });
152
+ return { contentType: null, errors, warnings };
153
+ }
154
+ const slug = slugResult.value;
155
+ i = skipWhitespace(source, slugResult.end);
156
+ // Expect comma
157
+ if (source[i] !== ",") {
158
+ errors.push({
159
+ line: lineAt(source, i),
160
+ column: columnAt(source, i),
161
+ message: "Expected comma after slug",
162
+ });
163
+ return { contentType: null, errors, warnings };
164
+ }
165
+ i = skipWhitespace(source, i + 1);
166
+ // Parse config object
167
+ if (source[i] !== "{") {
168
+ errors.push({
169
+ line: lineAt(source, i),
170
+ column: columnAt(source, i),
171
+ message: "Expected object literal for content type config",
172
+ });
173
+ return { contentType: null, errors, warnings };
174
+ }
175
+ const configResult = extractBalanced(source, i, "{", "}");
176
+ if (!configResult) {
177
+ errors.push({
178
+ line: lineAt(source, i),
179
+ column: columnAt(source, i),
180
+ message: "Unterminated config object",
181
+ });
182
+ return { contentType: null, errors, warnings };
183
+ }
184
+ const configBody = configResult.inner;
185
+ // Extract name
186
+ const name = extractPropertyString(configBody, "name");
187
+ if (!name) {
188
+ warnings.push({
189
+ line: baseLine,
190
+ message: `Missing "name" for content type "${slug}" — using slug as name`,
191
+ });
192
+ }
193
+ // Extract description
194
+ const description = extractPropertyString(configBody, "description");
195
+ // Extract fields block
196
+ const fields = [];
197
+ const fieldsMatch = /fields\s*:\s*\{/.exec(configBody);
198
+ if (fieldsMatch) {
199
+ const fieldsStart = configBody.indexOf("{", fieldsMatch.index + fieldsMatch[0].length - 1);
200
+ const fieldsBlock = extractBalanced(configBody, fieldsStart, "{", "}");
201
+ if (fieldsBlock) {
202
+ const fieldEntries = parseFieldEntries(fieldsBlock.inner, lineAt(source, startIdx), errors, warnings);
203
+ fields.push(...fieldEntries);
204
+ }
205
+ }
206
+ const contentType = {
207
+ slug,
208
+ name: name || slug,
209
+ fields,
210
+ };
211
+ if (description) {
212
+ contentType.description = description;
213
+ }
214
+ return { contentType, errors, warnings };
215
+ }
216
+ /**
217
+ * Parse field entries from the fields object body.
218
+ * Each entry is: fieldName: field.type({ ... }) or field.type()
219
+ */
220
+ function parseFieldEntries(body, baseLine, errors, warnings) {
221
+ const fields = [];
222
+ // Match patterns like: fieldName: field.type(...) or fieldName: field.type()
223
+ const fieldPattern = /(\w+)\s*:\s*field\s*\.\s*(\w+)\s*\(/g;
224
+ let match;
225
+ while ((match = fieldPattern.exec(body)) !== null) {
226
+ const fieldName = match[1];
227
+ const fieldType = match[2];
228
+ const argsStart = match.index + match[0].length;
229
+ if (!FIELD_TYPE_SET.has(fieldType)) {
230
+ errors.push({
231
+ line: baseLine,
232
+ column: 0,
233
+ message: `Unknown field type "${fieldType}" for field "${fieldName}"`,
234
+ });
235
+ continue;
236
+ }
237
+ // Extract the arguments to field.type(...)
238
+ // Find matching closing paren
239
+ const argsResult = extractBalancedFrom(body, argsStart - 1, "(", ")");
240
+ const argsBody = argsResult ? argsResult.inner : "";
241
+ const fieldDef = {
242
+ name: fieldName,
243
+ type: fieldType,
244
+ required: false,
245
+ };
246
+ // Parse options from args body
247
+ if (argsBody.trim()) {
248
+ // Look for required
249
+ const requiredMatch = /required\s*:\s*(true|false)/.exec(argsBody);
250
+ if (requiredMatch) {
251
+ fieldDef.required = requiredMatch[1] === "true";
252
+ }
253
+ // Look for description
254
+ const descMatch = /description\s*:\s*/.exec(argsBody);
255
+ if (descMatch) {
256
+ const descStart = descMatch.index + descMatch[0].length;
257
+ const descStr = parseStringLiteral(argsBody, skipWhitespace(argsBody, descStart));
258
+ if (descStr) {
259
+ fieldDef.description = descStr.value;
260
+ }
261
+ }
262
+ // Look for choices (select type)
263
+ if (fieldType === "select") {
264
+ const choices = parseChoicesArray(argsBody);
265
+ if (choices.length > 0) {
266
+ fieldDef.options = { choices };
267
+ }
268
+ }
269
+ }
270
+ fields.push(fieldDef);
271
+ }
272
+ return fields;
273
+ }
274
+ /**
275
+ * Parse a choices array from text like:
276
+ * choices: [{ label: "Foo", value: "foo" }, ...]
277
+ */
278
+ function parseChoicesArray(text) {
279
+ const choices = [];
280
+ const choicesMatch = /choices\s*:\s*\[/.exec(text);
281
+ if (!choicesMatch)
282
+ return choices;
283
+ const arrayStart = text.indexOf("[", choicesMatch.index);
284
+ const arrayBlock = extractBalanced(text, arrayStart, "[", "]");
285
+ if (!arrayBlock)
286
+ return choices;
287
+ // Find each { ... } in the array
288
+ const objPattern = /\{/g;
289
+ let objMatch;
290
+ while ((objMatch = objPattern.exec(arrayBlock.inner)) !== null) {
291
+ const objBlock = extractBalanced(arrayBlock.inner, objMatch.index, "{", "}");
292
+ if (!objBlock)
293
+ continue;
294
+ const label = extractPropertyString(objBlock.inner, "label");
295
+ const value = extractPropertyString(objBlock.inner, "value");
296
+ if (label && value) {
297
+ choices.push({ label, value });
298
+ }
299
+ }
300
+ return choices;
301
+ }
302
+ // === Utility functions ===
303
+ function skipWhitespace(source, index) {
304
+ while (index < source.length && /\s/.test(source[index])) {
305
+ index++;
306
+ }
307
+ return index;
308
+ }
309
+ /**
310
+ * Parse a string literal (single-quoted, double-quoted, or backtick) at position i.
311
+ */
312
+ function parseStringLiteral(source, i) {
313
+ if (i >= source.length)
314
+ return null;
315
+ const quote = source[i];
316
+ if (quote !== '"' && quote !== "'" && quote !== "`")
317
+ return null;
318
+ let value = "";
319
+ let j = i + 1;
320
+ let escaped = false;
321
+ while (j < source.length) {
322
+ const ch = source[j];
323
+ if (escaped) {
324
+ switch (ch) {
325
+ case "n":
326
+ value += "\n";
327
+ break;
328
+ case "t":
329
+ value += "\t";
330
+ break;
331
+ case "\\":
332
+ value += "\\";
333
+ break;
334
+ default:
335
+ value += ch;
336
+ break;
337
+ }
338
+ escaped = false;
339
+ j++;
340
+ continue;
341
+ }
342
+ if (ch === "\\") {
343
+ escaped = true;
344
+ j++;
345
+ continue;
346
+ }
347
+ if (ch === quote) {
348
+ return { value, end: j + 1 };
349
+ }
350
+ value += ch;
351
+ j++;
352
+ }
353
+ return null; // unterminated string
354
+ }
355
+ /**
356
+ * Extract balanced delimiters starting at position i (which must be the opening delimiter).
357
+ */
358
+ function extractBalanced(source, i, open, close) {
359
+ if (source[i] !== open)
360
+ return null;
361
+ return extractBalancedFrom(source, i, open, close);
362
+ }
363
+ function extractBalancedFrom(source, i, open, close) {
364
+ let depth = 0;
365
+ let inString = null;
366
+ let escaped = false;
367
+ const start = i + 1;
368
+ while (i < source.length) {
369
+ const ch = source[i];
370
+ if (escaped) {
371
+ escaped = false;
372
+ i++;
373
+ continue;
374
+ }
375
+ if (inString) {
376
+ if (ch === "\\") {
377
+ escaped = true;
378
+ i++;
379
+ continue;
380
+ }
381
+ if (ch === inString) {
382
+ inString = null;
383
+ }
384
+ i++;
385
+ continue;
386
+ }
387
+ if (ch === '"' || ch === "'" || ch === "`") {
388
+ inString = ch;
389
+ i++;
390
+ continue;
391
+ }
392
+ if (ch === open) {
393
+ depth++;
394
+ }
395
+ else if (ch === close) {
396
+ depth--;
397
+ if (depth === 0) {
398
+ return { inner: source.slice(start, i), end: i + 1 };
399
+ }
400
+ }
401
+ i++;
402
+ }
403
+ return null;
404
+ }
405
+ /**
406
+ * Extract a string property value from an object literal body.
407
+ * Matches: propName: "value" or propName: 'value'
408
+ */
409
+ function extractPropertyString(body, propName) {
410
+ const pattern = new RegExp(`(?<![\\w])${propName}\\s*:\\s*`);
411
+ const match = pattern.exec(body);
412
+ if (!match)
413
+ return null;
414
+ const valueStart = match.index + match[0].length;
415
+ const i = skipWhitespace(body, valueStart);
416
+ const result = parseStringLiteral(body, i);
417
+ return result ? result.value : null;
418
+ }
419
+ //# sourceMappingURL=parse-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-schema.js","sourceRoot":"","sources":["../../src/schema/parse-schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Schema types that mirror convex/lib/validators.ts Field/FieldType exactly.
3
+ * This is the shared type contract between DSL, parser, serializer, and API.
4
+ */
5
+ export type FieldType = "text" | "textarea" | "number" | "boolean" | "datetime" | "url" | "image" | "select" | "shopifyProduct" | "shopifyCollection";
6
+ export declare const FIELD_TYPES: readonly FieldType[];
7
+ export interface FieldDefinition {
8
+ name: string;
9
+ type: FieldType;
10
+ required: boolean;
11
+ description?: string;
12
+ options?: {
13
+ choices?: {
14
+ label: string;
15
+ value: string;
16
+ }[];
17
+ };
18
+ }
19
+ export interface ContentTypeDefinition {
20
+ slug: string;
21
+ name: string;
22
+ description?: string;
23
+ fields: FieldDefinition[];
24
+ }
25
+ export interface SchemaDefinition {
26
+ contentTypes: ContentTypeDefinition[];
27
+ }
28
+ //# sourceMappingURL=schema-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-types.d.ts","sourceRoot":"","sources":["../../src/schema/schema-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,UAAU,GACV,QAAQ,GACR,SAAS,GACT,UAAU,GACV,KAAK,GACL,OAAO,GACP,QAAQ,GACR,gBAAgB,GAChB,mBAAmB,CAAC;AAExB,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAWlC,CAAC;AAEX,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KAC9C,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,qBAAqB,EAAE,CAAC;CACvC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Schema types that mirror convex/lib/validators.ts Field/FieldType exactly.
3
+ * This is the shared type contract between DSL, parser, serializer, and API.
4
+ */
5
+ export const FIELD_TYPES = [
6
+ "text",
7
+ "textarea",
8
+ "number",
9
+ "boolean",
10
+ "datetime",
11
+ "url",
12
+ "image",
13
+ "select",
14
+ "shopifyProduct",
15
+ "shopifyCollection",
16
+ ];
17
+ //# sourceMappingURL=schema-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-types.js","sourceRoot":"","sources":["../../src/schema/schema-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH,MAAM,CAAC,MAAM,WAAW,GAAyB;IAC/C,MAAM;IACN,UAAU;IACV,QAAQ;IACR,SAAS;IACT,UAAU;IACV,KAAK;IACL,OAAO;IACP,QAAQ;IACR,gBAAgB;IAChB,mBAAmB;CACX,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { ContentTypeDefinition, SchemaDefinition } from "./schema-types";
2
+ /**
3
+ * Generates a complete schema.ts source file from a SchemaDefinition.
4
+ * Round-trip guarantee: parseSchemaSource(generateSchemaSource(s)) matches s.
5
+ */
6
+ export declare function generateSchemaSource(schema: SchemaDefinition): string;
7
+ /**
8
+ * Generates a single defineContentType() call as a string.
9
+ */
10
+ export declare function generateContentTypeSource(ct: ContentTypeDefinition): string;
11
+ //# sourceMappingURL=serialize-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize-schema.d.ts","sourceRoot":"","sources":["../../src/schema/serialize-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EAErB,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AAExB;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAuBrE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,qBAAqB,GAAG,MAAM,CAa3E"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Generates a complete schema.ts source file from a SchemaDefinition.
3
+ * Round-trip guarantee: parseSchemaSource(generateSchemaSource(s)) matches s.
4
+ */
5
+ export function generateSchemaSource(schema) {
6
+ const lines = [];
7
+ lines.push('import { defineSchema, defineContentType, field } from "@no-mess/client/schema";');
8
+ lines.push("");
9
+ const varNames = [];
10
+ for (const ct of schema.contentTypes) {
11
+ const varName = slugToVarName(ct.slug);
12
+ varNames.push(varName);
13
+ lines.push(`const ${varName} = ${generateContentTypeCall(ct)};`);
14
+ lines.push("");
15
+ }
16
+ lines.push(`export default defineSchema({ contentTypes: [${varNames.join(", ")}] });`);
17
+ lines.push("");
18
+ return lines.join("\n");
19
+ }
20
+ /**
21
+ * Generates a single defineContentType() call as a string.
22
+ */
23
+ export function generateContentTypeSource(ct) {
24
+ const lines = [];
25
+ lines.push('import { defineContentType, field } from "@no-mess/client/schema";');
26
+ lines.push("");
27
+ lines.push(`export const ${slugToVarName(ct.slug)} = ${generateContentTypeCall(ct)};`);
28
+ lines.push("");
29
+ return lines.join("\n");
30
+ }
31
+ function generateContentTypeCall(ct) {
32
+ const lines = [];
33
+ lines.push(`defineContentType(${quote(ct.slug)}, {`);
34
+ lines.push(` name: ${quote(ct.name)},`);
35
+ if (ct.description) {
36
+ lines.push(` description: ${quote(ct.description)},`);
37
+ }
38
+ lines.push(" fields: {");
39
+ for (const field of ct.fields) {
40
+ lines.push(` ${field.name}: ${generateFieldCall(field)},`);
41
+ }
42
+ lines.push(" },");
43
+ lines.push("})");
44
+ return lines.join("\n");
45
+ }
46
+ function generateFieldCall(f) {
47
+ const opts = [];
48
+ if (f.required) {
49
+ opts.push("required: true");
50
+ }
51
+ if (f.description) {
52
+ opts.push(`description: ${quote(f.description)}`);
53
+ }
54
+ if (f.type === "select" && f.options?.choices) {
55
+ if (f.options.choices.length === 0) {
56
+ opts.push("choices: []");
57
+ }
58
+ else {
59
+ const choiceEntries = f.options.choices.map((c) => `{ label: ${quote(c.label)}, value: ${quote(c.value)} }`);
60
+ opts.push(`choices: [\n ${choiceEntries.join(",\n ")},\n ]`);
61
+ }
62
+ }
63
+ if (opts.length === 0) {
64
+ return `field.${f.type}()`;
65
+ }
66
+ return `field.${f.type}({ ${opts.join(", ")} })`;
67
+ }
68
+ /**
69
+ * Convert a slug like "blog-post" to a camelCase variable name "blogPost".
70
+ */
71
+ function slugToVarName(slug) {
72
+ return slug.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
73
+ }
74
+ /**
75
+ * Quote a string with double quotes, escaping special characters.
76
+ */
77
+ function quote(s) {
78
+ const escaped = s
79
+ .replace(/\\/g, "\\\\")
80
+ .replace(/"/g, '\\"')
81
+ .replace(/\n/g, "\\n")
82
+ .replace(/\t/g, "\\t");
83
+ return `"${escaped}"`;
84
+ }
85
+ //# sourceMappingURL=serialize-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize-schema.js","sourceRoot":"","sources":["../../src/schema/serialize-schema.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@no-mess/client",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "TypeScript SDK for the no-mess headless CMS",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -13,6 +13,10 @@
13
13
  "./react": {
14
14
  "import": "./dist/react/index.js",
15
15
  "types": "./dist/react/index.d.ts"
16
+ },
17
+ "./schema": {
18
+ "import": "./dist/schema/index.js",
19
+ "types": "./dist/schema/index.d.ts"
16
20
  }
17
21
  },
18
22
  "files": [
@@ -32,12 +36,13 @@
32
36
  },
33
37
  "repository": {
34
38
  "type": "git",
35
- "url": "https://github.com/jjjjjjjjjjjjjjjjacob/no-mess.git",
39
+ "url": "git+https://github.com/jjjjjjjjjjjjjjjjacob/no-mess.git",
36
40
  "directory": "packages/no-mess-client"
37
41
  },
38
42
  "license": "MIT",
39
43
  "publishConfig": {
40
- "access": "public"
44
+ "access": "public",
45
+ "provenance": true
41
46
  },
42
47
  "devDependencies": {
43
48
  "@testing-library/react": "^16.0.0",