@fluid-app/fluid-cli-themes 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.
@@ -0,0 +1,78 @@
1
+ // resources.ts — AUTO-GENERATED, DO NOT EDIT
2
+ import { Command } from "commander";
3
+ import type { CommandContext } from "@fluid-app/fluid-cli";
4
+
5
+ export function registerResources(parent: Command, ctx: CommandContext): void {
6
+ const resource = parent.command("resources").description("resources");
7
+
8
+ resource
9
+ .command("get <application-theme-id>")
10
+ .description("Lists all theme resources")
11
+ .action(async (applicationThemeId) => {
12
+ const client = await ctx.getClient();
13
+ if (ctx.verbose)
14
+ process.stderr.write(
15
+ "GET " +
16
+ `/api/application_themes/${applicationThemeId}/resources` +
17
+ "\n",
18
+ );
19
+ const result = await client.get(
20
+ `/api/application_themes/${applicationThemeId}/resources`,
21
+ );
22
+ ctx.output(result);
23
+ });
24
+
25
+ resource
26
+ .command("update <application-theme-id>")
27
+ .description("Updates a theme resource")
28
+ .option("--body <json>", "Request body as JSON string")
29
+ .option("--body-file <path>", "Read request body from file")
30
+ .action(async (applicationThemeId, opts) => {
31
+ const client = await ctx.getClient();
32
+ let body: unknown;
33
+ if (opts.bodyFile) {
34
+ const { readFileSync } = await import("fs");
35
+ body = ctx.parseBody(readFileSync(opts.bodyFile, "utf-8"));
36
+ } else if (opts.body) {
37
+ body = ctx.parseBody(opts.body);
38
+ }
39
+ if (ctx.verbose)
40
+ process.stderr.write(
41
+ "PUT " +
42
+ `/api/application_themes/${applicationThemeId}/resources` +
43
+ "\n",
44
+ );
45
+ const result = await client.put(
46
+ `/api/application_themes/${applicationThemeId}/resources`,
47
+ body,
48
+ );
49
+ ctx.output(result);
50
+ });
51
+
52
+ resource
53
+ .command("delete <application-theme-id>")
54
+ .description("Deletes a theme resource")
55
+ .option("--body <json>", "Request body as JSON string")
56
+ .option("--body-file <path>", "Read request body from file")
57
+ .action(async (applicationThemeId, opts) => {
58
+ const client = await ctx.getClient();
59
+ let body: unknown;
60
+ if (opts.bodyFile) {
61
+ const { readFileSync } = await import("fs");
62
+ body = ctx.parseBody(readFileSync(opts.bodyFile, "utf-8"));
63
+ } else if (opts.body) {
64
+ body = ctx.parseBody(opts.body);
65
+ }
66
+ if (ctx.verbose)
67
+ process.stderr.write(
68
+ "DELETE " +
69
+ `/api/application_themes/${applicationThemeId}/resources` +
70
+ "\n",
71
+ );
72
+ const result = await client.delete(
73
+ `/api/application_themes/${applicationThemeId}/resources`,
74
+ { body },
75
+ );
76
+ ctx.output(result);
77
+ });
78
+ }
@@ -0,0 +1,119 @@
1
+ // root-themes.ts — AUTO-GENERATED, DO NOT EDIT
2
+ import { Command } from "commander";
3
+ import type { CommandContext } from "@fluid-app/fluid-cli";
4
+
5
+ export function registerRootThemes(parent: Command, ctx: CommandContext): void {
6
+ const resource = parent.command("root-themes").description("root-themes");
7
+
8
+ resource
9
+ .command("list")
10
+ .description("List root themes")
11
+ .option("--page <value>", "Page number for pagination")
12
+ .option("--per-page <value>", "Number of records per page")
13
+ .option(
14
+ "--status <value>",
15
+ "Filter themes by status of their versions (draft, publishing, rejected, published)",
16
+ )
17
+ .action(async (opts) => {
18
+ const client = await ctx.getClient();
19
+ const params: Record<string, unknown> = {};
20
+ if (opts.page !== undefined) params["page"] = Number(opts.page);
21
+ if (opts.perPage !== undefined) params["per_page"] = Number(opts.perPage);
22
+ if (opts.status !== undefined) params["status"] = opts.status;
23
+ if (ctx.verbose) process.stderr.write("GET " + `/api/root_themes` + "\n");
24
+ const result = await client.get(`/api/root_themes`, params);
25
+ ctx.output(result);
26
+ });
27
+
28
+ resource
29
+ .command("create")
30
+ .description("Create a root theme")
31
+ .option("--body <json>", "Request body as JSON string")
32
+ .option("--body-file <path>", "Read request body from file")
33
+ .action(async (opts) => {
34
+ const client = await ctx.getClient();
35
+ let body: unknown;
36
+ if (opts.bodyFile) {
37
+ const { readFileSync } = await import("fs");
38
+ body = ctx.parseBody(readFileSync(opts.bodyFile, "utf-8"));
39
+ } else if (opts.body) {
40
+ body = ctx.parseBody(opts.body);
41
+ }
42
+ if (ctx.verbose)
43
+ process.stderr.write("POST " + `/api/root_themes` + "\n");
44
+ const result = await client.post(`/api/root_themes`, body);
45
+ ctx.output(result);
46
+ });
47
+
48
+ resource
49
+ .command("list-company")
50
+ .description("List company root themes")
51
+ .option("--page <value>", "Page number for pagination")
52
+ .option("--per-page <value>", "Number of records per page")
53
+ .option(
54
+ "--status <value>",
55
+ "Filter themes by status of their versions (draft, publishing, rejected, published, active)",
56
+ )
57
+ .action(async (opts) => {
58
+ const client = await ctx.getClient();
59
+ const params: Record<string, unknown> = {};
60
+ if (opts.page !== undefined) params["page"] = Number(opts.page);
61
+ if (opts.perPage !== undefined) params["per_page"] = Number(opts.perPage);
62
+ if (opts.status !== undefined) params["status"] = opts.status;
63
+ if (ctx.verbose)
64
+ process.stderr.write("GET " + `/api/root_themes/my` + "\n");
65
+ const result = await client.get(`/api/root_themes/my`, params);
66
+ ctx.output(result);
67
+ });
68
+
69
+ resource
70
+ .command("update <id>")
71
+ .description("Update a root theme")
72
+ .option("--body <json>", "Request body as JSON string")
73
+ .option("--body-file <path>", "Read request body from file")
74
+ .action(async (id, opts) => {
75
+ const client = await ctx.getClient();
76
+ let body: unknown;
77
+ if (opts.bodyFile) {
78
+ const { readFileSync } = await import("fs");
79
+ body = ctx.parseBody(readFileSync(opts.bodyFile, "utf-8"));
80
+ } else if (opts.body) {
81
+ body = ctx.parseBody(opts.body);
82
+ }
83
+ if (ctx.verbose)
84
+ process.stderr.write("PATCH " + `/api/root_themes/${id}` + "\n");
85
+ const result = await client.patch(`/api/root_themes/${id}`, body);
86
+ ctx.output(result);
87
+ });
88
+
89
+ resource
90
+ .command("delete <id>")
91
+ .description("Delete a root theme")
92
+ .action(async (id) => {
93
+ const client = await ctx.getClient();
94
+ if (ctx.verbose)
95
+ process.stderr.write("DELETE " + `/api/root_themes/${id}` + "\n");
96
+ const result = await client.delete(`/api/root_themes/${id}`);
97
+ ctx.output(result);
98
+ });
99
+
100
+ resource
101
+ .command("update-status <id>")
102
+ .description("Update a root theme status")
103
+ .option("--body <json>", "Request body as JSON string")
104
+ .option("--body-file <path>", "Read request body from file")
105
+ .action(async (id, opts) => {
106
+ const client = await ctx.getClient();
107
+ let body: unknown;
108
+ if (opts.bodyFile) {
109
+ const { readFileSync } = await import("fs");
110
+ body = ctx.parseBody(readFileSync(opts.bodyFile, "utf-8"));
111
+ } else if (opts.body) {
112
+ body = ctx.parseBody(opts.body);
113
+ }
114
+ if (ctx.verbose)
115
+ process.stderr.write("POST " + `/api/root_themes/${id}/status` + "\n");
116
+ const result = await client.post(`/api/root_themes/${id}/status`, body);
117
+ ctx.output(result);
118
+ });
119
+ }
@@ -0,0 +1,366 @@
1
+ // templates.ts — AUTO-GENERATED, DO NOT EDIT
2
+ import { Command } from "commander";
3
+ import type { CommandContext } from "@fluid-app/fluid-cli";
4
+
5
+ function parseBooleanOption(value: string, flag: string): boolean {
6
+ const normalized = value.trim().toLowerCase();
7
+ if (["true", "1", "yes", "on"].includes(normalized)) return true;
8
+ if (["false", "0", "no", "off"].includes(normalized)) return false;
9
+ throw new Error(`Invalid value for ${flag}: ${value}. Expected true/false.`);
10
+ }
11
+
12
+ export function registerTemplates(parent: Command, ctx: CommandContext): void {
13
+ const resource = parent.command("templates").description("templates");
14
+
15
+ resource
16
+ .command("list")
17
+ .description("Lists all theme templates")
18
+ .option("--application-theme-id <value>", "ID of the application theme")
19
+ .option("--themeable-type <value>", "Filter templates by themeable type")
20
+ .option("--published <value>", "return published versions")
21
+ .action(async (opts) => {
22
+ const client = await ctx.getClient();
23
+ const params: Record<string, unknown> = {};
24
+ if (opts.applicationThemeId !== undefined)
25
+ params["application_theme_id"] = opts.applicationThemeId;
26
+ if (opts.themeableType !== undefined)
27
+ params["themeable_type"] = opts.themeableType;
28
+ if (opts.published !== undefined)
29
+ params["published"] = parseBooleanOption(opts.published, "--published");
30
+ if (ctx.verbose)
31
+ process.stderr.write(
32
+ "GET " + `/api/application_theme_templates` + "\n",
33
+ );
34
+ const result = await client.get(
35
+ `/api/application_theme_templates`,
36
+ params,
37
+ );
38
+ ctx.output(result);
39
+ });
40
+
41
+ resource
42
+ .command("create")
43
+ .description("Creates a theme template")
44
+ .option("--application-theme-id <value>", "ID of the application theme")
45
+ .option("--themeable-type <value>", "Filter templates by themeable type")
46
+ .option("--published <value>", "return published versions")
47
+ .option("--body <json>", "Request body as JSON string")
48
+ .option("--body-file <path>", "Read request body from file")
49
+ .action(async (opts) => {
50
+ const client = await ctx.getClient();
51
+ const params: Record<string, unknown> = {};
52
+ if (opts.applicationThemeId !== undefined)
53
+ params["application_theme_id"] = opts.applicationThemeId;
54
+ if (opts.themeableType !== undefined)
55
+ params["themeable_type"] = opts.themeableType;
56
+ if (opts.published !== undefined)
57
+ params["published"] = parseBooleanOption(opts.published, "--published");
58
+ let body: unknown;
59
+ if (opts.bodyFile) {
60
+ const { readFileSync } = await import("fs");
61
+ body = ctx.parseBody(readFileSync(opts.bodyFile, "utf-8"));
62
+ } else if (opts.body) {
63
+ body = ctx.parseBody(opts.body);
64
+ }
65
+ if (ctx.verbose)
66
+ process.stderr.write(
67
+ "POST " + `/api/application_theme_templates` + "\n",
68
+ );
69
+ const result = await client.post(
70
+ `/api/application_theme_templates`,
71
+ body,
72
+ { params },
73
+ );
74
+ ctx.output(result);
75
+ });
76
+
77
+ resource
78
+ .command("get <id>")
79
+ .description("Retrieves a theme template")
80
+ .option("--version <value>", "Version of the theme template to retrieve")
81
+ .option(
82
+ "--published <value>",
83
+ "Retrieve the published version of the theme template",
84
+ )
85
+ .action(async (id, opts) => {
86
+ const client = await ctx.getClient();
87
+ const params: Record<string, unknown> = {};
88
+ if (opts.version !== undefined) params["version"] = opts.version;
89
+ if (opts.published !== undefined)
90
+ params["published"] = parseBooleanOption(opts.published, "--published");
91
+ if (ctx.verbose)
92
+ process.stderr.write(
93
+ "GET " + `/api/application_theme_templates/${id}` + "\n",
94
+ );
95
+ const result = await client.get(
96
+ `/api/application_theme_templates/${id}`,
97
+ params,
98
+ );
99
+ ctx.output(result);
100
+ });
101
+
102
+ resource
103
+ .command("update <id>")
104
+ .description("Updates a theme template")
105
+ .option("--version <value>", "Version of the theme template to retrieve")
106
+ .option(
107
+ "--published <value>",
108
+ "Retrieve the published version of the theme template",
109
+ )
110
+ .option("--body <json>", "Request body as JSON string")
111
+ .option("--body-file <path>", "Read request body from file")
112
+ .action(async (id, opts) => {
113
+ const client = await ctx.getClient();
114
+ const params: Record<string, unknown> = {};
115
+ if (opts.version !== undefined) params["version"] = opts.version;
116
+ if (opts.published !== undefined)
117
+ params["published"] = parseBooleanOption(opts.published, "--published");
118
+ let body: unknown;
119
+ if (opts.bodyFile) {
120
+ const { readFileSync } = await import("fs");
121
+ body = ctx.parseBody(readFileSync(opts.bodyFile, "utf-8"));
122
+ } else if (opts.body) {
123
+ body = ctx.parseBody(opts.body);
124
+ }
125
+ if (ctx.verbose)
126
+ process.stderr.write(
127
+ "PATCH " + `/api/application_theme_templates/${id}` + "\n",
128
+ );
129
+ const result = await client.patch(
130
+ `/api/application_theme_templates/${id}`,
131
+ body,
132
+ { params },
133
+ );
134
+ ctx.output(result);
135
+ });
136
+
137
+ resource
138
+ .command("delete <id>")
139
+ .description("Deletes a theme template")
140
+ .option("--version <value>", "Version of the theme template to retrieve")
141
+ .option(
142
+ "--published <value>",
143
+ "Retrieve the published version of the theme template",
144
+ )
145
+ .action(async (id, opts) => {
146
+ const client = await ctx.getClient();
147
+ const params: Record<string, unknown> = {};
148
+ if (opts.version !== undefined) params["version"] = opts.version;
149
+ if (opts.published !== undefined)
150
+ params["published"] = parseBooleanOption(opts.published, "--published");
151
+ if (ctx.verbose)
152
+ process.stderr.write(
153
+ "DELETE " + `/api/application_theme_templates/${id}` + "\n",
154
+ );
155
+ const result = await client.delete(
156
+ `/api/application_theme_templates/${id}`,
157
+ { params },
158
+ );
159
+ ctx.output(result);
160
+ });
161
+
162
+ resource
163
+ .command("clone <id>")
164
+ .description("Clones a theme template")
165
+ .action(async (id) => {
166
+ const client = await ctx.getClient();
167
+ if (ctx.verbose)
168
+ process.stderr.write(
169
+ "POST " + `/api/application_theme_templates/${id}/clone` + "\n",
170
+ );
171
+ const result = await client.post(
172
+ `/api/application_theme_templates/${id}/clone`,
173
+ );
174
+ ctx.output(result);
175
+ });
176
+
177
+ resource
178
+ .command("set-default <id>")
179
+ .description("Sets a theme template as default")
180
+ .action(async (id) => {
181
+ const client = await ctx.getClient();
182
+ if (ctx.verbose)
183
+ process.stderr.write(
184
+ "POST " + `/api/application_theme_templates/${id}/set_default` + "\n",
185
+ );
186
+ const result = await client.post(
187
+ `/api/application_theme_templates/${id}/set_default`,
188
+ );
189
+ ctx.output(result);
190
+ });
191
+
192
+ resource
193
+ .command("version-diff <id>")
194
+ .description("Gets version diff information")
195
+ .option("--version <value>", "Version number to compare with")
196
+ .action(async (id, opts) => {
197
+ const client = await ctx.getClient();
198
+ const params: Record<string, unknown> = {};
199
+ if (opts.version !== undefined) params["version"] = Number(opts.version);
200
+ if (ctx.verbose)
201
+ process.stderr.write(
202
+ "GET " + `/api/application_theme_templates/${id}/version_diff` + "\n",
203
+ );
204
+ const result = await client.get(
205
+ `/api/application_theme_templates/${id}/version_diff`,
206
+ params,
207
+ );
208
+ ctx.output(result);
209
+ });
210
+
211
+ resource
212
+ .command("render-page <id>")
213
+ .description("Renders a page for a theme template")
214
+ .option("--version <value>", "Version of the theme template to retrieve")
215
+ .option("--body <json>", "Request body as JSON string")
216
+ .option("--body-file <path>", "Read request body from file")
217
+ .action(async (id, opts) => {
218
+ const client = await ctx.getClient();
219
+ const params: Record<string, unknown> = {};
220
+ if (opts.version !== undefined) params["version"] = opts.version;
221
+ let body: unknown;
222
+ if (opts.bodyFile) {
223
+ const { readFileSync } = await import("fs");
224
+ body = ctx.parseBody(readFileSync(opts.bodyFile, "utf-8"));
225
+ } else if (opts.body) {
226
+ body = ctx.parseBody(opts.body);
227
+ }
228
+ if (ctx.verbose)
229
+ process.stderr.write(
230
+ "POST " + `/api/application_theme_templates/${id}/render_page` + "\n",
231
+ );
232
+ const result = await client.post(
233
+ `/api/application_theme_templates/${id}/render_page`,
234
+ body,
235
+ { params },
236
+ );
237
+ ctx.output(result);
238
+ });
239
+
240
+ resource
241
+ .command("render-section <id>")
242
+ .description("Renders a section template")
243
+ .action(async (id) => {
244
+ const client = await ctx.getClient();
245
+ if (ctx.verbose)
246
+ process.stderr.write(
247
+ "POST " +
248
+ `/api/application_theme_templates/${id}/render_section` +
249
+ "\n",
250
+ );
251
+ const result = await client.post(
252
+ `/api/application_theme_templates/${id}/render_section`,
253
+ );
254
+ ctx.output(result);
255
+ });
256
+
257
+ resource
258
+ .command("get-theme-template-available-variables-api <id>")
259
+ .description("Get available variables for a theme template")
260
+ .action(async (id) => {
261
+ const client = await ctx.getClient();
262
+ if (ctx.verbose)
263
+ process.stderr.write(
264
+ "GET " +
265
+ `/api/application_theme_templates/${id}/available_variables` +
266
+ "\n",
267
+ );
268
+ const result = await client.get(
269
+ `/api/application_theme_templates/${id}/available_variables`,
270
+ );
271
+ ctx.output(result);
272
+ });
273
+
274
+ resource
275
+ .command("publish <id>")
276
+ .description("Publishes the template")
277
+ .option(
278
+ "--version <value>",
279
+ "Version of the theme template to publish. If not specified, the latest version will be published.",
280
+ )
281
+ .action(async (id, opts) => {
282
+ const client = await ctx.getClient();
283
+ const params: Record<string, unknown> = {};
284
+ if (opts.version !== undefined) params["version"] = opts.version;
285
+ if (ctx.verbose)
286
+ process.stderr.write(
287
+ "POST " + `/api/application_theme_templates/${id}/publish` + "\n",
288
+ );
289
+ const result = await client.post(
290
+ `/api/application_theme_templates/${id}/publish`,
291
+ undefined,
292
+ { params },
293
+ );
294
+ ctx.output(result);
295
+ });
296
+
297
+ resource
298
+ .command("available-themeables <id>")
299
+ .description("Returns all available themeables for theme template")
300
+ .option(
301
+ "--selected <value>",
302
+ "Filter themeables that are already assigned to this template",
303
+ )
304
+ .option(
305
+ "--status <value>",
306
+ "Filter themeables by status (active, draft, archived)",
307
+ )
308
+ .action(async (id, opts) => {
309
+ const client = await ctx.getClient();
310
+ const params: Record<string, unknown> = {};
311
+ if (opts.selected !== undefined)
312
+ params["selected"] = parseBooleanOption(opts.selected, "--selected");
313
+ if (opts.status !== undefined) params["status"] = opts.status;
314
+ if (ctx.verbose)
315
+ process.stderr.write(
316
+ "GET " +
317
+ `/api/application_theme_templates/${id}/available_themeables` +
318
+ "\n",
319
+ );
320
+ const result = await client.get(
321
+ `/api/application_theme_templates/${id}/available_themeables`,
322
+ params,
323
+ );
324
+ ctx.output(result);
325
+ });
326
+
327
+ resource
328
+ .command("themeables-update <id>")
329
+ .description(
330
+ "Updates themeable records to be used by the specified template",
331
+ )
332
+ .option("--query-params <value>", "query_params")
333
+ .action(async (id, opts) => {
334
+ const client = await ctx.getClient();
335
+ const params: Record<string, unknown> = {};
336
+ if (opts.queryParams !== undefined)
337
+ params["query_params"] = opts.queryParams;
338
+ if (ctx.verbose)
339
+ process.stderr.write(
340
+ "PUT " +
341
+ `/api/application_theme_templates/${id}/themeables_update` +
342
+ "\n",
343
+ );
344
+ const result = await client.put(
345
+ `/api/application_theme_templates/${id}/themeables_update`,
346
+ undefined,
347
+ { params },
348
+ );
349
+ ctx.output(result);
350
+ });
351
+
352
+ resource
353
+ .command("get-mysite-themes")
354
+ .description("List all mysite themes")
355
+ .action(async () => {
356
+ const client = await ctx.getClient();
357
+ if (ctx.verbose)
358
+ process.stderr.write(
359
+ "GET " + `/api/application_theme_templates/mysite_themes` + "\n",
360
+ );
361
+ const result = await client.get(
362
+ `/api/application_theme_templates/mysite_themes`,
363
+ );
364
+ ctx.output(result);
365
+ });
366
+ }
package/src/index.ts ADDED
@@ -0,0 +1,20 @@
1
+ import type { FluidPlugin } from "@fluid-app/fluid-cli";
2
+ import { createDomainCommand } from "@fluid-app/fluid-cli";
3
+
4
+ import { registerAllCommands } from "./generated/index.js";
5
+
6
+ const plugin: FluidPlugin = {
7
+ name: "@fluid-app/fluid-cli-themes",
8
+ version: "0.1.0",
9
+ register(ctx) {
10
+ ctx.program.addCommand(
11
+ createDomainCommand(
12
+ "themes",
13
+ "Manage Fluid application themes and templates",
14
+ registerAllCommands,
15
+ ),
16
+ );
17
+ },
18
+ };
19
+
20
+ export default plugin;
package/tsconfig.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "@fluid-app/typescript-config/base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src",
6
+ "incremental": false
7
+ },
8
+ "include": ["src/**/*"],
9
+ "exclude": ["node_modules", "dist"]
10
+ }
@@ -0,0 +1,12 @@
1
+ import { defineConfig } from "tsdown";
2
+
3
+ export default defineConfig({
4
+ entry: { index: "src/index.ts" },
5
+ format: ["esm"],
6
+ dts: true,
7
+ clean: true,
8
+ target: "node18",
9
+ deps: {
10
+ neverBundle: ["commander", "@fluid-app/fluid-cli"],
11
+ },
12
+ });