@studiocms/devapps 0.1.0-beta.9 → 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.
Files changed (42) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -23
  3. package/dist/effects/WordPressAPI/configs.d.ts +87 -0
  4. package/dist/effects/WordPressAPI/configs.js +88 -0
  5. package/dist/effects/WordPressAPI/converters.d.ts +57 -0
  6. package/dist/effects/WordPressAPI/converters.js +331 -0
  7. package/dist/effects/WordPressAPI/errors.d.ts +12 -0
  8. package/dist/effects/WordPressAPI/errors.js +6 -0
  9. package/dist/effects/WordPressAPI/importers.d.ts +19 -0
  10. package/dist/effects/WordPressAPI/importers.js +122 -0
  11. package/dist/effects/WordPressAPI/schema.d.ts +478 -0
  12. package/dist/effects/WordPressAPI/schema.js +127 -0
  13. package/dist/effects/WordPressAPI/utils.d.ts +17 -0
  14. package/dist/effects/WordPressAPI/utils.js +239 -0
  15. package/dist/effects/wpImporter.d.ts +14 -0
  16. package/dist/effects/wpImporter.js +88 -0
  17. package/dist/index.d.ts +0 -3
  18. package/dist/index.js +0 -16
  19. package/dist/routes/wp-importer.d.ts +0 -25
  20. package/dist/routes/wp-importer.js +9 -54
  21. package/dist/schema/index.d.ts +0 -24
  22. package/dist/schema/index.js +1 -13
  23. package/dist/utils/pathGenerator.js +3 -1
  24. package/dist/virt.d.ts +1 -5
  25. package/package.json +25 -31
  26. package/dist/apps/libsql-viewer.d.ts +0 -46
  27. package/dist/apps/libsql-viewer.js +0 -95
  28. package/dist/schema/wp-api.d.ts +0 -439
  29. package/dist/schema/wp-api.js +0 -72
  30. package/dist/utils/wp-api/converters.d.ts +0 -74
  31. package/dist/utils/wp-api/converters.js +0 -181
  32. package/dist/utils/wp-api/index.d.ts +0 -6
  33. package/dist/utils/wp-api/index.js +0 -3
  34. package/dist/utils/wp-api/pages.d.ts +0 -13
  35. package/dist/utils/wp-api/pages.js +0 -38
  36. package/dist/utils/wp-api/posts.d.ts +0 -10
  37. package/dist/utils/wp-api/posts.js +0 -38
  38. package/dist/utils/wp-api/settings.d.ts +0 -18
  39. package/dist/utils/wp-api/settings.js +0 -45
  40. package/dist/utils/wp-api/utils.d.ts +0 -66
  41. package/dist/utils/wp-api/utils.js +0 -138
  42. package/dist/virt.d.js +0 -0
@@ -0,0 +1,127 @@
1
+ import { Schema } from "studiocms/effect";
2
+ const OpenClosedSchema = Schema.Union(
3
+ Schema.Literal("open"),
4
+ Schema.Literal("closed"),
5
+ Schema.Literal("")
6
+ );
7
+ const StatusSchema = Schema.Union(
8
+ Schema.Literal("publish"),
9
+ Schema.Literal("future"),
10
+ Schema.Literal("draft"),
11
+ Schema.Literal("pending"),
12
+ Schema.Literal("private")
13
+ );
14
+ const PostFormatSchema = Schema.Union(
15
+ Schema.Literal("standard"),
16
+ Schema.Literal("aside"),
17
+ Schema.Literal("chat"),
18
+ Schema.Literal("gallery"),
19
+ Schema.Literal("link"),
20
+ Schema.Literal("image"),
21
+ Schema.Literal("quote"),
22
+ Schema.Literal("status"),
23
+ Schema.Literal("video"),
24
+ Schema.Literal("audio"),
25
+ Schema.Literal("")
26
+ );
27
+ const MetaDataSchema = Schema.Array(
28
+ Schema.Union(Schema.Any, Schema.Record({ key: Schema.String, value: Schema.Any }))
29
+ );
30
+ const RenderedData = Schema.Struct({ rendered: Schema.String });
31
+ const RenderedProtectData = Schema.Struct({
32
+ ...RenderedData.fields,
33
+ protected: Schema.Boolean
34
+ });
35
+ const NumberArray = Schema.Array(Schema.Number);
36
+ class Page extends Schema.Class("Page")({
37
+ id: Schema.Number,
38
+ date: Schema.Date,
39
+ date_gmt: Schema.Date,
40
+ guid: RenderedData,
41
+ modified: Schema.Date,
42
+ modified_gmt: Schema.Date,
43
+ slug: Schema.String,
44
+ status: StatusSchema,
45
+ type: Schema.String,
46
+ title: RenderedData,
47
+ content: RenderedProtectData,
48
+ excerpt: RenderedProtectData,
49
+ author: Schema.Number,
50
+ featured_media: Schema.Number,
51
+ parent: Schema.Number,
52
+ menu_order: Schema.Number,
53
+ comment_status: OpenClosedSchema,
54
+ ping_status: OpenClosedSchema,
55
+ template: Schema.String,
56
+ meta: MetaDataSchema
57
+ }) {
58
+ }
59
+ class PagesSchema extends Schema.Class("PagesSchema")({
60
+ pages: Schema.Array(Page)
61
+ }) {
62
+ }
63
+ class Post extends Schema.Class("Post")({
64
+ ...Page.fields,
65
+ format: PostFormatSchema,
66
+ categories: NumberArray,
67
+ tags: NumberArray
68
+ }) {
69
+ }
70
+ class PostsSchema extends Schema.Class("PostsSchema")({
71
+ posts: Schema.Array(Post)
72
+ }) {
73
+ }
74
+ class Tag extends Schema.Class("Tag")({
75
+ id: Schema.Number,
76
+ count: Schema.Number,
77
+ description: Schema.String,
78
+ link: Schema.String,
79
+ name: Schema.String,
80
+ slug: Schema.String,
81
+ taxonomy: Schema.String,
82
+ meta: MetaDataSchema
83
+ }) {
84
+ }
85
+ class TagsSchema extends Schema.Class("TagsSchema")({
86
+ tags: Schema.Array(Tag)
87
+ }) {
88
+ }
89
+ class Category extends Schema.Class("Category")({
90
+ ...Tag.fields,
91
+ parent: Schema.Number
92
+ }) {
93
+ }
94
+ class CategoriesSchema extends Schema.Class("CategoriesSchema")({
95
+ categories: Schema.Array(Category)
96
+ }) {
97
+ }
98
+ class SiteSettings extends Schema.Class("SiteSettings")({
99
+ name: Schema.String,
100
+ description: Schema.String,
101
+ url: Schema.String,
102
+ home: Schema.String,
103
+ gmt_offset: Schema.Number,
104
+ timezone_string: Schema.String,
105
+ site_logo: Schema.optional(Schema.Number),
106
+ site_icon: Schema.optional(Schema.Number),
107
+ site_icon_url: Schema.optional(Schema.String)
108
+ }) {
109
+ }
110
+ export {
111
+ CategoriesSchema,
112
+ Category,
113
+ MetaDataSchema,
114
+ NumberArray,
115
+ OpenClosedSchema,
116
+ Page,
117
+ PagesSchema,
118
+ Post,
119
+ PostFormatSchema,
120
+ PostsSchema,
121
+ RenderedData,
122
+ RenderedProtectData,
123
+ SiteSettings,
124
+ StatusSchema,
125
+ Tag,
126
+ TagsSchema
127
+ };
@@ -0,0 +1,17 @@
1
+ import { AstroError } from 'astro/errors';
2
+ import { type ConfigError, Effect } from 'studiocms/effect';
3
+ import { APIEndpointConfig, DownloadPostImageConfig, StringConfig } from './configs.js';
4
+ declare const WordPressAPIUtils_base: Effect.Service.Class<WordPressAPIUtils, "WordPressAPIUtils", {
5
+ readonly effect: Effect.Effect<{
6
+ turndown: Effect.Effect<string, ConfigError.ConfigError | AstroError, StringConfig>;
7
+ stripHtml: Effect.Effect<string, ConfigError.ConfigError | import("effect/Cause").UnknownException, StringConfig>;
8
+ cleanUpHtml: Effect.Effect<string, ConfigError.ConfigError | AstroError, StringConfig>;
9
+ fetchAll: (url: URL, page?: number, results?: any[]) => Effect.Effect<any[], ConfigError.ConfigError | AstroError, never>;
10
+ apiEndpoint: Effect.Effect<URL, ConfigError.ConfigError | AstroError, APIEndpointConfig>;
11
+ downloadPostImage: Effect.Effect<string | undefined, boolean | ConfigError.ConfigError | import("effect/Cause").UnknownException, DownloadPostImageConfig>;
12
+ downloadAndUpdateImages: Effect.Effect<string, boolean | ConfigError.ConfigError | AstroError | import("effect/Cause").UnknownException, DownloadPostImageConfig>;
13
+ }, never, never>;
14
+ }>;
15
+ export declare class WordPressAPIUtils extends WordPressAPIUtils_base {
16
+ }
17
+ export {};
@@ -0,0 +1,239 @@
1
+ import fs, { constants } from "node:fs";
2
+ import { access, writeFile } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { AstroError } from "astro/errors";
5
+ import * as cheerio from "cheerio";
6
+ import sanitizeHtml from "sanitize-html";
7
+ import { Console, Effect, genLogger } from "studiocms/effect";
8
+ import TurndownService from "turndown";
9
+ import {
10
+ APIEndpointConfig,
11
+ DownloadImageConfig,
12
+ DownloadPostImageConfig,
13
+ StringConfig
14
+ } from "./configs.js";
15
+ const _TurndownService = new TurndownService({
16
+ bulletListMarker: "-",
17
+ codeBlockStyle: "fenced",
18
+ emDelimiter: "*"
19
+ });
20
+ class WordPressAPIUtils extends Effect.Service()("WordPressAPIUtils", {
21
+ effect: genLogger("@studiocms/devapps/effects/WordPressAPI/utils.effect")(function* () {
22
+ const failedDownloads = /* @__PURE__ */ new Set();
23
+ const TDService = Effect.fn(
24
+ (fn) => Effect.try({
25
+ try: () => fn(_TurndownService),
26
+ catch: (cause) => new AstroError(
27
+ "Turndown Error",
28
+ `Failed to convert HTML to Markdown: ${cause.message}`
29
+ )
30
+ })
31
+ );
32
+ const turndown = genLogger("@studiocms/devapps/effects/WordPressAPI/utils.effect.turndown")(
33
+ function* () {
34
+ const { str } = yield* StringConfig;
35
+ return yield* TDService((TD) => TD.turndown(str));
36
+ }
37
+ );
38
+ const stripHtml = genLogger("@studiocms/devapps/effects/WordPressAPI/utils.effect.stripHtml")(
39
+ function* () {
40
+ const { str } = yield* StringConfig;
41
+ return yield* Effect.try(() => sanitizeHtml(str));
42
+ }
43
+ );
44
+ const loadHTML = Effect.fn(
45
+ (fn) => Effect.try({
46
+ try: () => fn(cheerio.load),
47
+ catch: (err) => new AstroError("Error loading content", err instanceof Error ? err.message : `${err}`)
48
+ })
49
+ );
50
+ const cleanUpHtml = genLogger(
51
+ "@studiocms/devapps/effects/WordPressAPI/utils.effect.cleanUpHtml"
52
+ )(function* () {
53
+ const { str } = yield* StringConfig;
54
+ const data = yield* loadHTML((fn) => fn(str));
55
+ const images = data("img");
56
+ for (const image of images) {
57
+ data(image).removeAttr("class").removeAttr("width").removeAttr("height").removeAttr("data-recalc-dims").removeAttr("sizes").removeAttr("srcset");
58
+ }
59
+ data(".wp-polls").html(
60
+ "<em>Polls have been temporarily removed while we migrate to a new platform.</em>"
61
+ );
62
+ data(".wp-polls.loading").remove();
63
+ return data.html();
64
+ });
65
+ const fetchAll = (url, page = 1, results = []) => genLogger("@studiocms/devapps/effects/WordPressAPI/utils.effect.fetchAll")(function* () {
66
+ url.searchParams.set("per_page", "100");
67
+ url.searchParams.set("page", String(page));
68
+ const res = yield* Effect.tryPromise({
69
+ try: () => fetch(url),
70
+ catch: (err) => new AstroError(
71
+ "Unknown Error while querying API",
72
+ err instanceof Error ? err.message : `${err}`
73
+ )
74
+ });
75
+ let data = yield* Effect.tryPromise({
76
+ try: () => res.json(),
77
+ catch: (err) => new AstroError(
78
+ "Unknown Error while reading API data",
79
+ err instanceof Error ? err.message : `${err}`
80
+ )
81
+ });
82
+ if (!Array.isArray(data)) {
83
+ if (typeof data === "object") {
84
+ data = Object.entries(data).map(([id, val]) => {
85
+ if (typeof val === "object") return { id, ...val };
86
+ return { id };
87
+ });
88
+ } else {
89
+ return yield* Effect.fail(
90
+ new AstroError(
91
+ "Expected WordPress API to return an array of items.",
92
+ `Received ${typeof data}:
93
+
94
+ \`\`\`json
95
+ ${JSON.stringify(data, null, 2)}
96
+ \`\`\``
97
+ )
98
+ );
99
+ }
100
+ }
101
+ results.push(...data);
102
+ const totalPages = Number.parseInt(res.headers.get("X-WP-TotalPages") || "1", 10);
103
+ yield* Console.log("Fetched page", page, "of", totalPages);
104
+ if (page < totalPages) {
105
+ yield* Console.log("Fetching next page...");
106
+ return yield* fetchAll(url, page + 1, results);
107
+ }
108
+ return results;
109
+ });
110
+ const apiEndpoint = genLogger(
111
+ "@studiocms/devapps/effects/WordPressAPI/utils.effect.apiEndpoint"
112
+ )(function* () {
113
+ const { endpoint, type, path: path2 } = yield* APIEndpointConfig;
114
+ if (!endpoint) {
115
+ return yield* Effect.fail(
116
+ new AstroError(
117
+ "Missing `endpoint` argument.",
118
+ "Please pass a URL to your WordPress website as the `endpoint` option to the WordPress importer. Most commonly this looks something like `https://example.com/`"
119
+ )
120
+ );
121
+ }
122
+ let newEndpoint = endpoint;
123
+ if (!newEndpoint.endsWith("/")) newEndpoint += "/";
124
+ const apiBase = new URL(newEndpoint);
125
+ if (type === "settings") {
126
+ apiBase.pathname = "wp-json/";
127
+ return apiBase;
128
+ }
129
+ apiBase.pathname = `wp-json/wp/v2/${type}/${path2 ? `${path2}/` : ""}`;
130
+ return apiBase;
131
+ });
132
+ const downloadImage = genLogger(
133
+ "@studiocms/devapps/effects/WordPressAPI/utils.effect.downloadImage"
134
+ )(function* () {
135
+ const { destination, imageUrl } = yield* DownloadImageConfig;
136
+ const fileExists = yield* Effect.tryPromise({
137
+ try: () => access(destination, constants.F_OK).then(() => true),
138
+ catch: () => false
139
+ });
140
+ if (fileExists) {
141
+ yield* Console.error("File already exists:", destination);
142
+ return true;
143
+ }
144
+ const allowedExtensions = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg"];
145
+ const ext = path.extname(destination.toString()).toLowerCase();
146
+ if (!allowedExtensions.includes(ext)) {
147
+ yield* Console.error("Invalid file extension:", ext);
148
+ return false;
149
+ }
150
+ const response = yield* Effect.tryPromise(() => fetch(imageUrl));
151
+ const contentType = response.headers.get("content-type");
152
+ if (!contentType?.startsWith("image/")) {
153
+ yield* Console.error("Invalid content type:", contentType);
154
+ return false;
155
+ }
156
+ const contentLength = response.headers.get("content-length");
157
+ const maxSize = 100 * 1024 * 1024;
158
+ if (contentLength && Number.parseInt(contentLength, 10) > maxSize) {
159
+ yield* Console.error("File too large:", contentLength);
160
+ return false;
161
+ }
162
+ if (response.ok && response.body) {
163
+ const reader = response.body.getReader();
164
+ const chunks = [];
165
+ let done = false;
166
+ while (!done) {
167
+ const { done: readerDone, value } = yield* Effect.tryPromise(() => reader.read());
168
+ if (value) chunks.push(value);
169
+ done = readerDone;
170
+ }
171
+ const fileBuffer = Buffer.concat(chunks);
172
+ yield* Effect.tryPromise(() => writeFile(destination, fileBuffer, { flag: "wx" }));
173
+ yield* Console.log("Downloaded image:", imageUrl);
174
+ return true;
175
+ }
176
+ yield* Console.error("Failed to download image:", imageUrl);
177
+ return false;
178
+ });
179
+ const downloadPostImage = genLogger(
180
+ "@studiocms/devapps/effects/WordPressAPI/utils.effect.downloadPostImage"
181
+ )(function* () {
182
+ const { str: src, pathToFolder } = yield* DownloadPostImageConfig;
183
+ if (!src || !pathToFolder) return;
184
+ if (!fs.existsSync(pathToFolder)) {
185
+ fs.mkdirSync(pathToFolder, { recursive: true });
186
+ }
187
+ const baseName = path.basename(src);
188
+ const fileName = baseName.split("?")[0];
189
+ if (!fileName) {
190
+ yield* Console.error("Invalid image URL:", src);
191
+ return void 0;
192
+ }
193
+ const destinationFile = path.resolve(pathToFolder, fileName);
194
+ if (fs.existsSync(destinationFile)) {
195
+ yield* Console.log(`Post/Page image "${destinationFile}" already exists, skipping...`);
196
+ return fileName;
197
+ }
198
+ const imageDownloaded = yield* downloadImage.pipe(
199
+ DownloadImageConfig.makeProvide(src, destinationFile)
200
+ );
201
+ if (!imageDownloaded) failedDownloads.add(src);
202
+ return imageDownloaded ? fileName : void 0;
203
+ });
204
+ const downloadAndUpdateImages = genLogger(
205
+ "@studiocms/devapps/effects/WordPressAPI/utils.effect.downloadAndUpdateImages"
206
+ )(function* () {
207
+ const { str: html, pathToFolder } = yield* DownloadPostImageConfig;
208
+ const data = yield* loadHTML((fn) => fn(html));
209
+ const images = data("img");
210
+ for (const image of images) {
211
+ const src = data(image).attr("src");
212
+ if (src) {
213
+ const newSrc = yield* downloadPostImage.pipe(
214
+ DownloadPostImageConfig.makeProvide(src, pathToFolder)
215
+ );
216
+ if (newSrc) {
217
+ data(image).attr("src", newSrc);
218
+ } else {
219
+ data(image).attr("src", src);
220
+ }
221
+ }
222
+ }
223
+ return data.html();
224
+ });
225
+ return {
226
+ turndown,
227
+ stripHtml,
228
+ cleanUpHtml,
229
+ fetchAll,
230
+ apiEndpoint,
231
+ downloadPostImage,
232
+ downloadAndUpdateImages
233
+ };
234
+ })
235
+ }) {
236
+ }
237
+ export {
238
+ WordPressAPIUtils
239
+ };
@@ -0,0 +1,14 @@
1
+ import { Effect } from 'studiocms/effect';
2
+ import { AstroAPIContextProvider } from './WordPressAPI/configs.js';
3
+ import { WPAPIError } from './WordPressAPI/errors.js';
4
+ import { WordPressAPI } from './WordPressAPI/importers.js';
5
+ declare const WPImporter_base: Effect.Service.Class<WPImporter, "WPImporter", {
6
+ readonly dependencies: readonly [import("effect/Layer").Layer<WordPressAPI, import("effect/ConfigError").ConfigError | import("studiocms/sdk/base").DBClientInitializationError | import("studiocms/sdk/base").SDKInitializationError, never>];
7
+ readonly effect: Effect.Effect<{
8
+ runPostEvent: Effect.Effect<Response, boolean | WPAPIError | import("effect/ConfigError").ConfigError | import("astro/errors").AstroError | import("effect/Cause").UnknownException | import("effect/ParseResult").ParseError | import("@withstudiocms/kysely/client").DBCallbackFailure | import("@withstudiocms/kysely/core/errors").DatabaseError, AstroAPIContextProvider>;
9
+ }, import("effect/ConfigError").ConfigError, WordPressAPI>;
10
+ }>;
11
+ export declare class WPImporter extends WPImporter_base {
12
+ static Provide: <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, import("effect/ConfigError").ConfigError | import("studiocms/sdk/base").DBClientInitializationError | import("studiocms/sdk/base").SDKInitializationError | E, Exclude<R, WPImporter>>;
13
+ }
14
+ export {};
@@ -0,0 +1,88 @@
1
+ import { Console, Effect, genLogger } from "studiocms/effect";
2
+ import {
3
+ AstroAPIContextProvider,
4
+ ImportEndpointConfig,
5
+ ImportPostsEndpointConfig
6
+ } from "./WordPressAPI/configs.js";
7
+ import { WPAPIError } from "./WordPressAPI/errors.js";
8
+ import { WordPressAPI } from "./WordPressAPI/importers.js";
9
+ const createResponse = (status, statusText) => new Response(null, {
10
+ status,
11
+ statusText,
12
+ headers: {
13
+ "Content-Type": "application/json",
14
+ "Access-Control-Allow-Headers": "*"
15
+ }
16
+ });
17
+ const createErrorResponse = (statusText) => createResponse(400, statusText);
18
+ class WPImporter extends Effect.Service()("WPImporter", {
19
+ dependencies: [WordPressAPI.Default],
20
+ effect: genLogger("@studiocms/devapps/effects/wpImporter.effect")(function* () {
21
+ const WPAPI = yield* WordPressAPI;
22
+ const parseFormData = (formData, name, type, optional = false) => Effect.gen(function* () {
23
+ const data = formData.get(name);
24
+ if (!optional && !data || data === null) {
25
+ return yield* new WPAPIError({ message: `Missing required form field: ${name}` });
26
+ }
27
+ switch (type) {
28
+ case "string":
29
+ return data.toString();
30
+ case "boolean": {
31
+ const value = data.toString().toLowerCase();
32
+ return value === "true" || value === "1" || value === "yes";
33
+ }
34
+ default:
35
+ return yield* new WPAPIError({
36
+ message: `Unsupported type '${type}' for form field: ${name}`
37
+ });
38
+ }
39
+ });
40
+ const runPostEvent = genLogger("@studiocms/devapps/effects/wpImporter.effect.runPostEvent")(
41
+ function* () {
42
+ const { context } = yield* AstroAPIContextProvider;
43
+ const formData = yield* Effect.tryPromise(() => context.request.formData());
44
+ const url = yield* parseFormData(formData, "url", "string");
45
+ const type = yield* parseFormData(formData, "type", "string");
46
+ const useBlogPlugin = yield* Effect.orElse(
47
+ parseFormData(formData, "useBlogPlugin", "boolean", true),
48
+ () => Effect.succeed(false)
49
+ );
50
+ if (!url || !type) {
51
+ return createErrorResponse("Bad Request");
52
+ }
53
+ yield* Console.log(
54
+ "Starting Import:",
55
+ url,
56
+ "\n Type:",
57
+ type,
58
+ "\n useBlogPlugin:",
59
+ useBlogPlugin
60
+ );
61
+ switch (type) {
62
+ case "pages":
63
+ yield* WPAPI.importPagesFromWPAPI.pipe(ImportEndpointConfig.makeProvide(url));
64
+ break;
65
+ case "posts":
66
+ yield* WPAPI.importPostsFromWPAPI.pipe(
67
+ ImportPostsEndpointConfig.makeProvide(url, useBlogPlugin)
68
+ );
69
+ break;
70
+ case "settings":
71
+ yield* WPAPI.importSettingsFromWPAPI.pipe(ImportEndpointConfig.makeProvide(url));
72
+ break;
73
+ default:
74
+ return createErrorResponse("Bad Request: Invalid import type");
75
+ }
76
+ return createResponse(200, "success");
77
+ }
78
+ );
79
+ return {
80
+ runPostEvent
81
+ };
82
+ })
83
+ }) {
84
+ static Provide = Effect.provide(this.Default);
85
+ }
86
+ export {
87
+ WPImporter
88
+ };
package/dist/index.d.ts CHANGED
@@ -26,9 +26,6 @@ import { type StudioCMSDevAppsOptions } from './schema/index.js';
26
26
  * enabled: true,
27
27
  * endpoint: '/wp-import',
28
28
  * },
29
- * libSQLViewer: {
30
- * enabled: true,
31
- * },
32
29
  * },
33
30
  * verbose: true,
34
31
  * }),
package/dist/index.js CHANGED
@@ -1,12 +1,10 @@
1
1
  import { addVirtualImports, createResolver, injectDevRoute } from "astro-integration-kit";
2
- import { loadEnv } from "vite";
3
2
  import { StudioCMSDevAppsSchema } from "./schema/index.js";
4
3
  import { pathGenerator } from "./utils/pathGenerator.js";
5
4
  function studioCMSDevApps(opts) {
6
5
  const options = StudioCMSDevAppsSchema.parse(opts);
7
6
  const { resolve } = createResolver(import.meta.url);
8
7
  let makeEndpointPath;
9
- const astroDbEnv = loadEnv("all", process.cwd(), "ASTRO_DB");
10
8
  return {
11
9
  name: "@studiocms/devapps",
12
10
  hooks: {
@@ -24,23 +22,9 @@ function studioCMSDevApps(opts) {
24
22
  `,
25
23
  "virtual:studiocms-devapps/config": `
26
24
  export const userProjectRoot = "${config.root.pathname}";
27
-
28
- export const dbEnv = {
29
- remoteUrl: "${astroDbEnv.ASTRO_DB_REMOTE_URL}",
30
- token: "${astroDbEnv.ASTRO_DB_APP_TOKEN}",
31
- };
32
25
  `
33
26
  }
34
27
  });
35
- if (options.appsConfig.libSQLViewer.enabled) {
36
- options.verbose && logger.info("Adding Dev Toolbar App: LibSQL Viewer");
37
- addDevToolbarApp({
38
- name: "LibSQL Viewer",
39
- id: "studiocms-devapps-libsql-viewer",
40
- entrypoint: resolve("./apps/libsql-viewer.js"),
41
- icon: '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6"><path stroke-linecap="round" stroke-linejoin="round" d="M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125" /></svg>'
42
- });
43
- }
44
28
  if (options.appsConfig.wpImporter.enabled) {
45
29
  options.verbose && logger.info("Adding Dev Toolbar App: WP API Importer");
46
30
  injectDevRoute(params, {
@@ -1,27 +1,2 @@
1
1
  import type { APIRoute } from 'astro';
2
- /**
3
- * Handles the POST request for importing data from a WordPress site.
4
- *
5
- * @param {APIContext} context - The context of the API request.
6
- * @param {Request} context.request - The incoming request object.
7
- *
8
- * @returns {Promise<Response>} The response object indicating the result of the import operation.
9
- *
10
- * The function expects the request to contain form data with the following fields:
11
- * - `url`: The URL of the WordPress site to import data from.
12
- * - `type`: The type of data to import (e.g., 'pages', 'posts', 'settings').
13
- * - `useBlogPlugin` (optional): A boolean value indicating whether to use the blog plugin for importing posts.
14
- *
15
- * The function performs the following steps:
16
- * 1. Extracts the form data from the request.
17
- * 2. Validates the presence and types of the `url` and `type` fields.
18
- * 3. Logs the import operation details.
19
- * 4. Based on the `type` field, calls the appropriate import function:
20
- * - `importPagesFromWPAPI` for importing pages.
21
- * - `importPostsFromWPAPI` for importing posts, optionally using the blog plugin.
22
- * - `importSettingsFromWPAPI` for importing settings.
23
- * 5. Returns a response indicating success or failure.
24
- *
25
- * @throws {Error} If the `type` field contains an invalid value.
26
- */
27
2
  export declare const POST: APIRoute;
@@ -1,57 +1,12 @@
1
- import {
2
- importPagesFromWPAPI,
3
- importPostsFromWPAPI,
4
- importSettingsFromWPAPI
5
- } from "../utils/wp-api/index.js";
6
- const POST = async ({ request }) => {
7
- const data = await request.formData();
8
- const url = data.get("url");
9
- const type = data.get("type");
10
- const useBlogPlugin = data.get("useBlogPlugin");
11
- if (!url || !type) {
12
- return new Response(null, {
13
- status: 400,
14
- statusText: "Bad Request",
15
- headers: {
16
- "Content-Type": "application/json",
17
- "Access-Control-Allow-Headers": "*"
18
- }
19
- });
20
- }
21
- if (typeof url !== "string" || typeof type !== "string") {
22
- return new Response(null, {
23
- status: 400,
24
- statusText: "Bad Request",
25
- headers: {
26
- "Content-Type": "application/json",
27
- "Access-Control-Allow-Headers": "*"
28
- }
29
- });
30
- }
31
- console.log("Starting Import:", url, "\n Type:", type, "\n useBlogPlugin:", useBlogPlugin);
32
- const useBlogPluginValue = useBlogPlugin === "true";
33
- switch (type) {
34
- case "pages":
35
- await importPagesFromWPAPI(url);
36
- break;
37
- case "posts":
38
- await importPostsFromWPAPI(url, useBlogPluginValue);
39
- break;
40
- case "settings":
41
- await importSettingsFromWPAPI(url);
42
- break;
43
- default:
44
- throw new Error("Invalid import type");
45
- }
46
- return new Response(null, {
47
- status: 200,
48
- statusText: "success",
49
- headers: {
50
- "Content-Type": "application/json",
51
- "Access-Control-Allow-Headers": "*"
52
- }
53
- });
54
- };
1
+ import { genLogger, runEffect } from "studiocms/effect";
2
+ import { AstroAPIContextProvider } from "../effects/WordPressAPI/configs.js";
3
+ import { WPImporter } from "../effects/wpImporter.js";
4
+ const POST = async (context) => await runEffect(
5
+ genLogger("@studiocms/devapps/routes/wp-importer.POST")(function* () {
6
+ const WP = yield* WPImporter;
7
+ return yield* WP.runPostEvent.pipe(AstroAPIContextProvider.makeProvide(context));
8
+ }).pipe(WPImporter.Provide)
9
+ );
55
10
  export {
56
11
  POST
57
12
  };