@structcms/api 0.1.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/LICENSE +21 -0
- package/README.md +188 -0
- package/dist/index.cjs +1124 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +365 -0
- package/dist/index.d.ts +365 -0
- package/dist/index.js +1047 -0
- package/dist/index.js.map +1 -0
- package/dist/next/index.cjs +1114 -0
- package/dist/next/index.cjs.map +1 -0
- package/dist/next/index.d.cts +143 -0
- package/dist/next/index.d.ts +143 -0
- package/dist/next/index.js +1064 -0
- package/dist/next/index.js.map +1 -0
- package/dist/supabase/index.cjs +494 -0
- package/dist/supabase/index.cjs.map +1 -0
- package/dist/supabase/index.d.cts +18 -0
- package/dist/supabase/index.d.ts +18 -0
- package/dist/supabase/index.js +467 -0
- package/dist/supabase/index.js.map +1 -0
- package/dist/types-Zi0Iyow1.d.cts +204 -0
- package/dist/types-Zi0Iyow1.d.ts +204 -0
- package/package.json +78 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a section within a page
|
|
3
|
+
*/
|
|
4
|
+
interface PageSection {
|
|
5
|
+
id: string;
|
|
6
|
+
type: string;
|
|
7
|
+
data: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Represents a CMS page with sections
|
|
11
|
+
*/
|
|
12
|
+
interface Page {
|
|
13
|
+
id: string;
|
|
14
|
+
slug: string;
|
|
15
|
+
pageType: string;
|
|
16
|
+
title: string;
|
|
17
|
+
sections: PageSection[];
|
|
18
|
+
createdAt: Date;
|
|
19
|
+
updatedAt: Date;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Input for creating a new page
|
|
23
|
+
*/
|
|
24
|
+
interface CreatePageInput {
|
|
25
|
+
slug?: string;
|
|
26
|
+
pageType: string;
|
|
27
|
+
title: string;
|
|
28
|
+
sections?: PageSection[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Input for updating an existing page
|
|
32
|
+
*/
|
|
33
|
+
interface UpdatePageInput {
|
|
34
|
+
id: string;
|
|
35
|
+
slug?: string;
|
|
36
|
+
pageType?: string;
|
|
37
|
+
title?: string;
|
|
38
|
+
sections?: PageSection[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Filter options for listing pages
|
|
42
|
+
*/
|
|
43
|
+
interface PageFilter {
|
|
44
|
+
pageType?: string;
|
|
45
|
+
limit?: number;
|
|
46
|
+
offset?: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Represents a navigation structure
|
|
50
|
+
*/
|
|
51
|
+
interface Navigation {
|
|
52
|
+
id: string;
|
|
53
|
+
name: string;
|
|
54
|
+
items: NavigationItem[];
|
|
55
|
+
updatedAt: Date;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A navigation item (recursive for nested menus)
|
|
59
|
+
*/
|
|
60
|
+
interface NavigationItem {
|
|
61
|
+
label: string;
|
|
62
|
+
href: string;
|
|
63
|
+
children?: NavigationItem[];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Input for creating a navigation
|
|
67
|
+
*/
|
|
68
|
+
interface CreateNavigationInput {
|
|
69
|
+
name: string;
|
|
70
|
+
items: NavigationItem[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Input for updating a navigation
|
|
74
|
+
*/
|
|
75
|
+
interface UpdateNavigationInput {
|
|
76
|
+
id: string;
|
|
77
|
+
name?: string;
|
|
78
|
+
items?: NavigationItem[];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Storage adapter interface for page and navigation persistence
|
|
82
|
+
* This interface is Supabase-agnostic to allow future portability
|
|
83
|
+
*/
|
|
84
|
+
interface StorageAdapter {
|
|
85
|
+
/** Get a page by its slug */
|
|
86
|
+
getPage(slug: string): Promise<Page | null>;
|
|
87
|
+
/** Get a page by its ID */
|
|
88
|
+
getPageById(id: string): Promise<Page | null>;
|
|
89
|
+
/** Create a new page */
|
|
90
|
+
createPage(input: CreatePageInput): Promise<Page>;
|
|
91
|
+
/** Update an existing page */
|
|
92
|
+
updatePage(input: UpdatePageInput): Promise<Page>;
|
|
93
|
+
/** Delete a page by ID */
|
|
94
|
+
deletePage(id: string): Promise<void>;
|
|
95
|
+
/** List pages with optional filtering and pagination */
|
|
96
|
+
listPages(filter?: PageFilter): Promise<Page[]>;
|
|
97
|
+
/** Get a navigation by its name */
|
|
98
|
+
getNavigation(name: string): Promise<Navigation | null>;
|
|
99
|
+
/** Get a navigation by its ID */
|
|
100
|
+
getNavigationById(id: string): Promise<Navigation | null>;
|
|
101
|
+
/** Create a new navigation */
|
|
102
|
+
createNavigation(input: CreateNavigationInput): Promise<Navigation>;
|
|
103
|
+
/** Update an existing navigation */
|
|
104
|
+
updateNavigation(input: UpdateNavigationInput): Promise<Navigation>;
|
|
105
|
+
/** Delete a navigation by ID */
|
|
106
|
+
deleteNavigation(id: string): Promise<void>;
|
|
107
|
+
/** List all navigations */
|
|
108
|
+
listNavigations(): Promise<Navigation[]>;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Allowed MIME types for media uploads
|
|
113
|
+
*/
|
|
114
|
+
declare const ALLOWED_MIME_TYPES: readonly ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"];
|
|
115
|
+
type AllowedMimeType = (typeof ALLOWED_MIME_TYPES)[number];
|
|
116
|
+
/**
|
|
117
|
+
* Represents a media file stored in the CMS
|
|
118
|
+
*/
|
|
119
|
+
interface MediaFile {
|
|
120
|
+
id: string;
|
|
121
|
+
filename: string;
|
|
122
|
+
url: string;
|
|
123
|
+
mimeType: string;
|
|
124
|
+
size: number;
|
|
125
|
+
createdAt: Date;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Input for uploading a media file
|
|
129
|
+
* data accepts ArrayBuffer for platform-agnostic binary data
|
|
130
|
+
*/
|
|
131
|
+
interface UploadMediaInput {
|
|
132
|
+
filename: string;
|
|
133
|
+
mimeType: string;
|
|
134
|
+
size: number;
|
|
135
|
+
data: ArrayBuffer | Uint8Array;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Filter options for listing media files
|
|
139
|
+
*/
|
|
140
|
+
interface MediaFilter {
|
|
141
|
+
limit?: number;
|
|
142
|
+
offset?: number;
|
|
143
|
+
mimeType?: string;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Media adapter interface for file storage operations.
|
|
147
|
+
* This interface is Supabase-agnostic to allow future portability.
|
|
148
|
+
*/
|
|
149
|
+
interface MediaAdapter {
|
|
150
|
+
/**
|
|
151
|
+
* Upload a media file
|
|
152
|
+
*/
|
|
153
|
+
upload(input: UploadMediaInput): Promise<MediaFile>;
|
|
154
|
+
/**
|
|
155
|
+
* Get a media file by ID
|
|
156
|
+
*/
|
|
157
|
+
getMedia(id: string): Promise<MediaFile | null>;
|
|
158
|
+
/**
|
|
159
|
+
* List media files with optional filtering and pagination
|
|
160
|
+
*/
|
|
161
|
+
listMedia(filter?: MediaFilter): Promise<MediaFile[]>;
|
|
162
|
+
/**
|
|
163
|
+
* Delete a media file by ID
|
|
164
|
+
*/
|
|
165
|
+
deleteMedia(id: string): Promise<void>;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
interface AuthUser {
|
|
169
|
+
id: string;
|
|
170
|
+
email: string;
|
|
171
|
+
metadata?: Record<string, unknown>;
|
|
172
|
+
}
|
|
173
|
+
interface AuthSession {
|
|
174
|
+
accessToken: string;
|
|
175
|
+
refreshToken?: string;
|
|
176
|
+
expiresAt?: Date;
|
|
177
|
+
user: AuthUser;
|
|
178
|
+
}
|
|
179
|
+
interface SignInWithOAuthInput {
|
|
180
|
+
provider: 'google' | 'github' | 'gitlab' | 'azure' | 'bitbucket';
|
|
181
|
+
redirectTo?: string;
|
|
182
|
+
}
|
|
183
|
+
interface SignInWithPasswordInput {
|
|
184
|
+
email: string;
|
|
185
|
+
password: string;
|
|
186
|
+
}
|
|
187
|
+
interface OAuthResponse {
|
|
188
|
+
url: string;
|
|
189
|
+
provider: string;
|
|
190
|
+
}
|
|
191
|
+
interface VerifySessionInput {
|
|
192
|
+
accessToken: string;
|
|
193
|
+
expiresAt?: Date | string;
|
|
194
|
+
}
|
|
195
|
+
interface AuthAdapter {
|
|
196
|
+
signInWithOAuth(input: SignInWithOAuthInput): Promise<OAuthResponse>;
|
|
197
|
+
signInWithPassword(input: SignInWithPasswordInput): Promise<AuthSession>;
|
|
198
|
+
signOut(accessToken: string): Promise<void>;
|
|
199
|
+
verifySession(input: VerifySessionInput): Promise<AuthUser | null>;
|
|
200
|
+
refreshSession(refreshToken: string): Promise<AuthSession>;
|
|
201
|
+
getCurrentUser(accessToken: string): Promise<AuthUser | null>;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export { type AuthAdapter as A, type CreatePageInput as C, type MediaAdapter as M, type Navigation as N, type OAuthResponse as O, type Page as P, type StorageAdapter as S, type UpdatePageInput as U, type VerifySessionInput as V, type PageFilter as a, type CreateNavigationInput as b, type UpdateNavigationInput as c, type NavigationItem as d, type PageSection as e, type UploadMediaInput as f, type MediaFile as g, type MediaFilter as h, type SignInWithOAuthInput as i, type SignInWithPasswordInput as j, type AuthSession as k, type AuthUser as l, ALLOWED_MIME_TYPES as m, type AllowedMimeType as n };
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a section within a page
|
|
3
|
+
*/
|
|
4
|
+
interface PageSection {
|
|
5
|
+
id: string;
|
|
6
|
+
type: string;
|
|
7
|
+
data: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Represents a CMS page with sections
|
|
11
|
+
*/
|
|
12
|
+
interface Page {
|
|
13
|
+
id: string;
|
|
14
|
+
slug: string;
|
|
15
|
+
pageType: string;
|
|
16
|
+
title: string;
|
|
17
|
+
sections: PageSection[];
|
|
18
|
+
createdAt: Date;
|
|
19
|
+
updatedAt: Date;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Input for creating a new page
|
|
23
|
+
*/
|
|
24
|
+
interface CreatePageInput {
|
|
25
|
+
slug?: string;
|
|
26
|
+
pageType: string;
|
|
27
|
+
title: string;
|
|
28
|
+
sections?: PageSection[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Input for updating an existing page
|
|
32
|
+
*/
|
|
33
|
+
interface UpdatePageInput {
|
|
34
|
+
id: string;
|
|
35
|
+
slug?: string;
|
|
36
|
+
pageType?: string;
|
|
37
|
+
title?: string;
|
|
38
|
+
sections?: PageSection[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Filter options for listing pages
|
|
42
|
+
*/
|
|
43
|
+
interface PageFilter {
|
|
44
|
+
pageType?: string;
|
|
45
|
+
limit?: number;
|
|
46
|
+
offset?: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Represents a navigation structure
|
|
50
|
+
*/
|
|
51
|
+
interface Navigation {
|
|
52
|
+
id: string;
|
|
53
|
+
name: string;
|
|
54
|
+
items: NavigationItem[];
|
|
55
|
+
updatedAt: Date;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A navigation item (recursive for nested menus)
|
|
59
|
+
*/
|
|
60
|
+
interface NavigationItem {
|
|
61
|
+
label: string;
|
|
62
|
+
href: string;
|
|
63
|
+
children?: NavigationItem[];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Input for creating a navigation
|
|
67
|
+
*/
|
|
68
|
+
interface CreateNavigationInput {
|
|
69
|
+
name: string;
|
|
70
|
+
items: NavigationItem[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Input for updating a navigation
|
|
74
|
+
*/
|
|
75
|
+
interface UpdateNavigationInput {
|
|
76
|
+
id: string;
|
|
77
|
+
name?: string;
|
|
78
|
+
items?: NavigationItem[];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Storage adapter interface for page and navigation persistence
|
|
82
|
+
* This interface is Supabase-agnostic to allow future portability
|
|
83
|
+
*/
|
|
84
|
+
interface StorageAdapter {
|
|
85
|
+
/** Get a page by its slug */
|
|
86
|
+
getPage(slug: string): Promise<Page | null>;
|
|
87
|
+
/** Get a page by its ID */
|
|
88
|
+
getPageById(id: string): Promise<Page | null>;
|
|
89
|
+
/** Create a new page */
|
|
90
|
+
createPage(input: CreatePageInput): Promise<Page>;
|
|
91
|
+
/** Update an existing page */
|
|
92
|
+
updatePage(input: UpdatePageInput): Promise<Page>;
|
|
93
|
+
/** Delete a page by ID */
|
|
94
|
+
deletePage(id: string): Promise<void>;
|
|
95
|
+
/** List pages with optional filtering and pagination */
|
|
96
|
+
listPages(filter?: PageFilter): Promise<Page[]>;
|
|
97
|
+
/** Get a navigation by its name */
|
|
98
|
+
getNavigation(name: string): Promise<Navigation | null>;
|
|
99
|
+
/** Get a navigation by its ID */
|
|
100
|
+
getNavigationById(id: string): Promise<Navigation | null>;
|
|
101
|
+
/** Create a new navigation */
|
|
102
|
+
createNavigation(input: CreateNavigationInput): Promise<Navigation>;
|
|
103
|
+
/** Update an existing navigation */
|
|
104
|
+
updateNavigation(input: UpdateNavigationInput): Promise<Navigation>;
|
|
105
|
+
/** Delete a navigation by ID */
|
|
106
|
+
deleteNavigation(id: string): Promise<void>;
|
|
107
|
+
/** List all navigations */
|
|
108
|
+
listNavigations(): Promise<Navigation[]>;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Allowed MIME types for media uploads
|
|
113
|
+
*/
|
|
114
|
+
declare const ALLOWED_MIME_TYPES: readonly ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"];
|
|
115
|
+
type AllowedMimeType = (typeof ALLOWED_MIME_TYPES)[number];
|
|
116
|
+
/**
|
|
117
|
+
* Represents a media file stored in the CMS
|
|
118
|
+
*/
|
|
119
|
+
interface MediaFile {
|
|
120
|
+
id: string;
|
|
121
|
+
filename: string;
|
|
122
|
+
url: string;
|
|
123
|
+
mimeType: string;
|
|
124
|
+
size: number;
|
|
125
|
+
createdAt: Date;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Input for uploading a media file
|
|
129
|
+
* data accepts ArrayBuffer for platform-agnostic binary data
|
|
130
|
+
*/
|
|
131
|
+
interface UploadMediaInput {
|
|
132
|
+
filename: string;
|
|
133
|
+
mimeType: string;
|
|
134
|
+
size: number;
|
|
135
|
+
data: ArrayBuffer | Uint8Array;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Filter options for listing media files
|
|
139
|
+
*/
|
|
140
|
+
interface MediaFilter {
|
|
141
|
+
limit?: number;
|
|
142
|
+
offset?: number;
|
|
143
|
+
mimeType?: string;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Media adapter interface for file storage operations.
|
|
147
|
+
* This interface is Supabase-agnostic to allow future portability.
|
|
148
|
+
*/
|
|
149
|
+
interface MediaAdapter {
|
|
150
|
+
/**
|
|
151
|
+
* Upload a media file
|
|
152
|
+
*/
|
|
153
|
+
upload(input: UploadMediaInput): Promise<MediaFile>;
|
|
154
|
+
/**
|
|
155
|
+
* Get a media file by ID
|
|
156
|
+
*/
|
|
157
|
+
getMedia(id: string): Promise<MediaFile | null>;
|
|
158
|
+
/**
|
|
159
|
+
* List media files with optional filtering and pagination
|
|
160
|
+
*/
|
|
161
|
+
listMedia(filter?: MediaFilter): Promise<MediaFile[]>;
|
|
162
|
+
/**
|
|
163
|
+
* Delete a media file by ID
|
|
164
|
+
*/
|
|
165
|
+
deleteMedia(id: string): Promise<void>;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
interface AuthUser {
|
|
169
|
+
id: string;
|
|
170
|
+
email: string;
|
|
171
|
+
metadata?: Record<string, unknown>;
|
|
172
|
+
}
|
|
173
|
+
interface AuthSession {
|
|
174
|
+
accessToken: string;
|
|
175
|
+
refreshToken?: string;
|
|
176
|
+
expiresAt?: Date;
|
|
177
|
+
user: AuthUser;
|
|
178
|
+
}
|
|
179
|
+
interface SignInWithOAuthInput {
|
|
180
|
+
provider: 'google' | 'github' | 'gitlab' | 'azure' | 'bitbucket';
|
|
181
|
+
redirectTo?: string;
|
|
182
|
+
}
|
|
183
|
+
interface SignInWithPasswordInput {
|
|
184
|
+
email: string;
|
|
185
|
+
password: string;
|
|
186
|
+
}
|
|
187
|
+
interface OAuthResponse {
|
|
188
|
+
url: string;
|
|
189
|
+
provider: string;
|
|
190
|
+
}
|
|
191
|
+
interface VerifySessionInput {
|
|
192
|
+
accessToken: string;
|
|
193
|
+
expiresAt?: Date | string;
|
|
194
|
+
}
|
|
195
|
+
interface AuthAdapter {
|
|
196
|
+
signInWithOAuth(input: SignInWithOAuthInput): Promise<OAuthResponse>;
|
|
197
|
+
signInWithPassword(input: SignInWithPasswordInput): Promise<AuthSession>;
|
|
198
|
+
signOut(accessToken: string): Promise<void>;
|
|
199
|
+
verifySession(input: VerifySessionInput): Promise<AuthUser | null>;
|
|
200
|
+
refreshSession(refreshToken: string): Promise<AuthSession>;
|
|
201
|
+
getCurrentUser(accessToken: string): Promise<AuthUser | null>;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export { type AuthAdapter as A, type CreatePageInput as C, type MediaAdapter as M, type Navigation as N, type OAuthResponse as O, type Page as P, type StorageAdapter as S, type UpdatePageInput as U, type VerifySessionInput as V, type PageFilter as a, type CreateNavigationInput as b, type UpdateNavigationInput as c, type NavigationItem as d, type PageSection as e, type UploadMediaInput as f, type MediaFile as g, type MediaFilter as h, type SignInWithOAuthInput as i, type SignInWithPasswordInput as j, type AuthSession as k, type AuthUser as l, ALLOWED_MIME_TYPES as m, type AllowedMimeType as n };
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@structcms/api",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Storage, domain API, and delivery API for StructCMS",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"./next": {
|
|
21
|
+
"import": {
|
|
22
|
+
"types": "./dist/next/index.d.ts",
|
|
23
|
+
"default": "./dist/next/index.js"
|
|
24
|
+
},
|
|
25
|
+
"require": {
|
|
26
|
+
"types": "./dist/next/index.d.cts",
|
|
27
|
+
"default": "./dist/next/index.cjs"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"./supabase": {
|
|
31
|
+
"import": {
|
|
32
|
+
"types": "./dist/supabase/index.d.ts",
|
|
33
|
+
"default": "./dist/supabase/index.js"
|
|
34
|
+
},
|
|
35
|
+
"require": {
|
|
36
|
+
"types": "./dist/supabase/index.d.cts",
|
|
37
|
+
"default": "./dist/supabase/index.cjs"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"files": ["dist", "README.md", "LICENSE"],
|
|
42
|
+
"sideEffects": false,
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsup",
|
|
45
|
+
"dev": "tsup --watch",
|
|
46
|
+
"typecheck": "tsc --noEmit",
|
|
47
|
+
"gen:types": "npx supabase gen types typescript --project-id arwaynscjejiwpcurnjs > src/types/database.types.ts",
|
|
48
|
+
"test": "vitest"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@supabase/supabase-js": "^2.45.0",
|
|
52
|
+
"sanitize-html": "^2.17.0"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@types/sanitize-html": "^2.16.0",
|
|
56
|
+
"typescript": "~5.7.0"
|
|
57
|
+
},
|
|
58
|
+
"publishConfig": {
|
|
59
|
+
"access": "public"
|
|
60
|
+
},
|
|
61
|
+
"license": "MIT",
|
|
62
|
+
"author": "Sebastian Krischer",
|
|
63
|
+
"repository": {
|
|
64
|
+
"type": "git",
|
|
65
|
+
"url": "git+https://github.com/skrischer/structcms.git",
|
|
66
|
+
"directory": "packages/api"
|
|
67
|
+
},
|
|
68
|
+
"keywords": [
|
|
69
|
+
"cms",
|
|
70
|
+
"headless-cms",
|
|
71
|
+
"api",
|
|
72
|
+
"supabase",
|
|
73
|
+
"storage",
|
|
74
|
+
"media",
|
|
75
|
+
"content-api",
|
|
76
|
+
"nextjs"
|
|
77
|
+
]
|
|
78
|
+
}
|