@antlur/backstage 1.12.12 → 1.12.14
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/dist/cli/actions/sync-blueprints.d.ts +3 -0
- package/dist/cli/actions/sync-blueprints.d.ts.map +1 -0
- package/dist/cli/actions/sync-blueprints.js +42 -0
- package/dist/cli/cli.js +8 -2
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -0
- package/dist/config.d.ts +26 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/endpoints/blueprints.d.ts +37 -0
- package/dist/endpoints/blueprints.d.ts.map +1 -0
- package/dist/endpoints/blueprints.js +27 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/studio/define-blueprint.d.ts +3 -0
- package/dist/studio/define-blueprint.d.ts.map +1 -0
- package/dist/studio/define-blueprint.js +3 -0
- package/dist/studio/index.d.ts +1 -0
- package/dist/studio/index.d.ts.map +1 -1
- package/dist/studio/index.js +1 -0
- package/dist/studio/types/block.d.ts +9 -2
- package/dist/studio/types/block.d.ts.map +1 -1
- package/dist/studio/types/field.d.ts +23 -1
- package/dist/studio/types/field.d.ts.map +1 -1
- package/dist/studio/types/layout.d.ts +9 -2
- package/dist/studio/types/layout.d.ts.map +1 -1
- package/dist/types/blueprint.d.ts +25 -1
- package/dist/types/blueprint.d.ts.map +1 -1
- package/package.json +1 -1
- package/readme.md +199 -4
- package/src/cli/actions/sync-blueprints.ts +45 -0
- package/src/cli/cli.ts +9 -2
- package/src/client.ts +3 -0
- package/src/config.ts +24 -0
- package/src/endpoints/blueprints.ts +58 -0
- package/src/index.ts +1 -0
- package/src/studio/define-blueprint.ts +5 -0
- package/src/studio/index.ts +1 -0
- package/src/studio/types/block.ts +13 -4
- package/src/studio/types/field.ts +28 -4
- package/src/studio/types/layout.ts +13 -4
- package/src/types/blueprint.ts +23 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-blueprints.d.ts","sourceRoot":"","sources":["../../../src/cli/actions/sync-blueprints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG3D,wBAAsB,cAAc,CAAC,MAAM,EAAE,mBAAmB,iBAyC/D"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { BackstageClient } from "../../client.js";
|
|
2
|
+
export async function syncBlueprints(config) {
|
|
3
|
+
const client = new BackstageClient(config);
|
|
4
|
+
if (!config.blueprints || !config.blueprints.length) {
|
|
5
|
+
console.log("No blueprints found in config");
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const syncPromises = config.blueprints.map(async (blueprint) => {
|
|
9
|
+
const blueprintData = {
|
|
10
|
+
name: blueprint.name,
|
|
11
|
+
slug: blueprint.slug,
|
|
12
|
+
slug_single: blueprint.slug_single,
|
|
13
|
+
description: blueprint.description,
|
|
14
|
+
is_routable: blueprint.is_routable,
|
|
15
|
+
has_location: blueprint.has_location,
|
|
16
|
+
has_route_index: blueprint.has_route_index,
|
|
17
|
+
fields: blueprint.fields,
|
|
18
|
+
};
|
|
19
|
+
try {
|
|
20
|
+
await client.blueprints.create(blueprintData);
|
|
21
|
+
console.log(`✓ Blueprint ${blueprint.slug} created`);
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
if (err?.response?.status === 409) {
|
|
25
|
+
const id = err.response.data;
|
|
26
|
+
console.log(`⚠ Blueprint ${blueprint.slug} already exists with id ${id}. Updating...`);
|
|
27
|
+
try {
|
|
28
|
+
await client.blueprints.update(id, blueprintData);
|
|
29
|
+
console.log(`✓ Blueprint ${blueprint.slug} updated`);
|
|
30
|
+
}
|
|
31
|
+
catch (updateErr) {
|
|
32
|
+
console.error(`✗ Failed to update blueprint ${blueprint.slug}:`, updateErr?.message || updateErr);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.error(`✗ Failed to create blueprint ${blueprint.slug}:`, err?.message || err);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
await Promise.all(syncPromises);
|
|
41
|
+
console.log(`\nSync complete: ${config.blueprints.length} blueprint(s) processed`);
|
|
42
|
+
}
|
package/dist/cli/cli.js
CHANGED
|
@@ -4,6 +4,7 @@ import { resolve } from "path";
|
|
|
4
4
|
import { program } from "commander";
|
|
5
5
|
import { loadBackstageConfig } from "./load-config.js";
|
|
6
6
|
import { syncBlocks } from "./actions/sync-blocks.js";
|
|
7
|
+
import { syncBlueprints } from "./actions/sync-blueprints.js";
|
|
7
8
|
import { syncLayouts } from "./actions/sync-layouts.js";
|
|
8
9
|
config({ path: resolve(process.cwd(), ".env") });
|
|
9
10
|
program
|
|
@@ -12,7 +13,7 @@ program
|
|
|
12
13
|
.version(process.env.npm_package_version || "1.0.0");
|
|
13
14
|
program
|
|
14
15
|
.command("sync <type>")
|
|
15
|
-
.description("Sync blocks and layouts with the Backstage CMS")
|
|
16
|
+
.description("Sync blocks, blueprints, and layouts with the Backstage CMS")
|
|
16
17
|
.action(async (type) => {
|
|
17
18
|
const backstageConfig = await loadBackstageConfig();
|
|
18
19
|
if (!backstageConfig) {
|
|
@@ -23,16 +24,21 @@ program
|
|
|
23
24
|
await syncBlocks(backstageConfig);
|
|
24
25
|
return;
|
|
25
26
|
}
|
|
27
|
+
if (type === "blueprints") {
|
|
28
|
+
await syncBlueprints(backstageConfig);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
26
31
|
if (type === "layouts") {
|
|
27
32
|
await syncLayouts(backstageConfig);
|
|
28
33
|
return;
|
|
29
34
|
}
|
|
30
35
|
if (type === "all") {
|
|
31
36
|
await syncBlocks(backstageConfig);
|
|
37
|
+
await syncBlueprints(backstageConfig);
|
|
32
38
|
await syncLayouts(backstageConfig);
|
|
33
39
|
return;
|
|
34
40
|
}
|
|
35
|
-
console.error(`Unknown type: ${type}. Valid types are: blocks, layouts, all`);
|
|
41
|
+
console.error(`Unknown type: ${type}. Valid types are: blocks, blueprints, layouts, all`);
|
|
36
42
|
process.exit(1);
|
|
37
43
|
});
|
|
38
44
|
program.parse();
|
package/dist/client.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { BackstageUserConfig } from "./config.js";
|
|
|
2
2
|
import { AlertService } from "./endpoints/alerts.js";
|
|
3
3
|
import { AuthService } from "./endpoints/auth.js";
|
|
4
4
|
import { BlocksService } from "./endpoints/blocks.js";
|
|
5
|
+
import { BlueprintsService } from "./endpoints/blueprints.js";
|
|
5
6
|
import { EntryService } from "./endpoints/entries.js";
|
|
6
7
|
import { EventService } from "./endpoints/events.js";
|
|
7
8
|
import { FormService } from "./endpoints/forms.js";
|
|
@@ -24,6 +25,7 @@ export declare class BackstageClient {
|
|
|
24
25
|
readonly alerts: AlertService;
|
|
25
26
|
readonly auth: AuthService;
|
|
26
27
|
readonly blocks: BlocksService;
|
|
28
|
+
readonly blueprints: BlueprintsService;
|
|
27
29
|
readonly entries: EntryService;
|
|
28
30
|
readonly events: EventService;
|
|
29
31
|
readonly forms: FormService;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAC,CAAyB;IAGzC,SAAgB,MAAM,EAAE,YAAY,CAAC;IACrC,SAAgB,IAAI,EAAE,WAAW,CAAC;IAClC,SAAgB,MAAM,EAAE,aAAa,CAAC;IACtC,SAAgB,OAAO,EAAE,YAAY,CAAC;IACtC,SAAgB,MAAM,EAAE,YAAY,CAAC;IACrC,SAAgB,KAAK,EAAE,WAAW,CAAC;IACnC,SAAgB,SAAS,EAAE,gBAAgB,CAAC;IAC5C,SAAgB,OAAO,EAAE,aAAa,CAAC;IACvC,SAAgB,SAAS,EAAE,eAAe,CAAC;IAC3C,SAAgB,KAAK,EAAE,YAAY,CAAC;IACpC,SAAgB,KAAK,EAAE,WAAW,CAAC;IACnC,SAAgB,UAAU,EAAE,iBAAiB,CAAC;IAC9C,SAAgB,KAAK,EAAE,WAAW,CAAC;IACnC,SAAgB,KAAK,EAAE,YAAY,CAAC;IACpC,SAAgB,SAAS,EAAE,eAAe,CAAC;IAC3C,SAAgB,MAAM,EAAE,YAAY,CAAC;IACrC,SAAgB,OAAO,EAAE,cAAc,CAAC;gBAE5B,MAAM,CAAC,EAAE,mBAAmB;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -2,6 +2,7 @@ import { getGlobalConfig } from "./config.js";
|
|
|
2
2
|
import { AlertService } from "./endpoints/alerts.js";
|
|
3
3
|
import { AuthService } from "./endpoints/auth.js";
|
|
4
4
|
import { BlocksService } from "./endpoints/blocks.js";
|
|
5
|
+
import { BlueprintsService } from "./endpoints/blueprints.js";
|
|
5
6
|
import { EntryService } from "./endpoints/entries.js";
|
|
6
7
|
import { EventService } from "./endpoints/events.js";
|
|
7
8
|
import { FormService } from "./endpoints/forms.js";
|
|
@@ -25,6 +26,7 @@ export class BackstageClient {
|
|
|
25
26
|
alerts;
|
|
26
27
|
auth;
|
|
27
28
|
blocks;
|
|
29
|
+
blueprints;
|
|
28
30
|
entries;
|
|
29
31
|
events;
|
|
30
32
|
forms;
|
|
@@ -61,6 +63,7 @@ export class BackstageClient {
|
|
|
61
63
|
this.alerts = new AlertService(this);
|
|
62
64
|
this.auth = new AuthService(this);
|
|
63
65
|
this.blocks = new BlocksService(this);
|
|
66
|
+
this.blueprints = new BlueprintsService(this);
|
|
64
67
|
this.entries = new EntryService(this);
|
|
65
68
|
this.events = new EventService(this);
|
|
66
69
|
this.forms = new FormService(this);
|
package/dist/config.d.ts
CHANGED
|
@@ -1,9 +1,35 @@
|
|
|
1
1
|
import type { BlockDefinition } from "./studio/types/index.js";
|
|
2
|
+
export interface BlueprintDefinition {
|
|
3
|
+
name: string;
|
|
4
|
+
slug: string;
|
|
5
|
+
slug_single?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
is_routable?: boolean;
|
|
8
|
+
has_location?: boolean;
|
|
9
|
+
has_route_index?: boolean;
|
|
10
|
+
fields: Array<{
|
|
11
|
+
name: string;
|
|
12
|
+
slug: string;
|
|
13
|
+
type: string;
|
|
14
|
+
type_id?: string | null;
|
|
15
|
+
is_primary?: boolean;
|
|
16
|
+
is_multiple?: boolean;
|
|
17
|
+
show_in_list?: boolean;
|
|
18
|
+
order: number;
|
|
19
|
+
allowed_references?: string[];
|
|
20
|
+
options?: Array<{
|
|
21
|
+
label: string;
|
|
22
|
+
value: any;
|
|
23
|
+
}>;
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
2
27
|
export interface BackstageUserConfig {
|
|
3
28
|
accountId?: string | undefined;
|
|
4
29
|
token?: string | undefined;
|
|
5
30
|
baseURL?: string;
|
|
6
31
|
blocks?: BlockDefinition<any>[] | undefined;
|
|
32
|
+
blueprints?: BlueprintDefinition[] | undefined;
|
|
7
33
|
layouts?: any[] | undefined;
|
|
8
34
|
onError?: (error: Error) => void;
|
|
9
35
|
}
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAI/D,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,CAAC;IAC5C,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC;IAC5B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAQD,wBAAgB,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,mBAAmB,CAM7E;AAED,wBAAgB,eAAe,IAAI,mBAAmB,CAGrD"}
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAI/D,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;QACd,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC9B,OAAO,CAAC,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,GAAG,CAAA;SAAE,CAAC,CAAC;QAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,CAAC;IAC5C,UAAU,CAAC,EAAE,mBAAmB,EAAE,GAAG,SAAS,CAAC;IAC/C,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC;IAC5B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAQD,wBAAgB,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,mBAAmB,CAM7E;AAED,wBAAgB,eAAe,IAAI,mBAAmB,CAGrD"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Blueprint } from "../types/blueprint";
|
|
2
|
+
import { BaseService } from "./base.js";
|
|
3
|
+
export interface CreateBlueprintParams {
|
|
4
|
+
name: string;
|
|
5
|
+
slug: string;
|
|
6
|
+
slug_single?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
is_routable?: boolean;
|
|
9
|
+
has_location?: boolean;
|
|
10
|
+
has_route_index?: boolean;
|
|
11
|
+
fields: Array<{
|
|
12
|
+
name: string;
|
|
13
|
+
slug: string;
|
|
14
|
+
type: string;
|
|
15
|
+
type_id?: string | null;
|
|
16
|
+
is_primary?: boolean;
|
|
17
|
+
is_multiple?: boolean;
|
|
18
|
+
show_in_list?: boolean;
|
|
19
|
+
order: number;
|
|
20
|
+
allowed_references?: string[];
|
|
21
|
+
options?: Array<{
|
|
22
|
+
label: string;
|
|
23
|
+
value: any;
|
|
24
|
+
}>;
|
|
25
|
+
placeholder?: string;
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
export interface UpdateBlueprintParams extends Partial<CreateBlueprintParams> {
|
|
29
|
+
}
|
|
30
|
+
export declare class BlueprintsService extends BaseService {
|
|
31
|
+
list(options?: RequestInit): Promise<Blueprint[]>;
|
|
32
|
+
get(id: string, options?: RequestInit): Promise<Blueprint | null>;
|
|
33
|
+
create(params: CreateBlueprintParams, options?: RequestInit): Promise<Blueprint>;
|
|
34
|
+
update(id: string, params: UpdateBlueprintParams, options?: RequestInit): Promise<Blueprint>;
|
|
35
|
+
delete(id: string, options?: RequestInit): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=blueprints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blueprints.d.ts","sourceRoot":"","sources":["../../src/endpoints/blueprints.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;QACd,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC9B,OAAO,CAAC,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,GAAG,CAAA;SAAE,CAAC,CAAC;QAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,qBAAsB,SAAQ,OAAO,CAAC,qBAAqB,CAAC;CAAG;AAEhF,qBAAa,iBAAkB,SAAQ,WAAW;IAC1C,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAKjD,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IASjE,MAAM,CAAC,MAAM,EAAE,qBAAqB,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC;IAKhF,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC;IAK5F,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAG/D"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BaseService } from "./base.js";
|
|
2
|
+
export class BlueprintsService extends BaseService {
|
|
3
|
+
async list(options) {
|
|
4
|
+
const { data } = await this.client.get("/blueprints", options);
|
|
5
|
+
return data;
|
|
6
|
+
}
|
|
7
|
+
async get(id, options) {
|
|
8
|
+
try {
|
|
9
|
+
const { data } = await this.client.get(`/blueprints/${id}`, options);
|
|
10
|
+
return data;
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
async create(params, options) {
|
|
17
|
+
const { data } = await this.client.post("/blueprints", params, options);
|
|
18
|
+
return data;
|
|
19
|
+
}
|
|
20
|
+
async update(id, params, options) {
|
|
21
|
+
const { data } = await this.client.put(`/blueprints/${id}`, params, options);
|
|
22
|
+
return data;
|
|
23
|
+
}
|
|
24
|
+
async delete(id, options) {
|
|
25
|
+
await this.client.delete(`/blueprints/${id}`, options);
|
|
26
|
+
}
|
|
27
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export { BackstageClient } from "./client.js";
|
|
|
3
3
|
export * from "./endpoints/alerts.js";
|
|
4
4
|
export * from "./endpoints/auth.js";
|
|
5
5
|
export * from "./endpoints/blocks.js";
|
|
6
|
+
export * from "./endpoints/blueprints.js";
|
|
6
7
|
export * from "./endpoints/entries.js";
|
|
7
8
|
export * from "./endpoints/events.js";
|
|
8
9
|
export * from "./endpoints/forms.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG5D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG5D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export { BackstageClient } from "./client.js";
|
|
|
6
6
|
export * from "./endpoints/alerts.js";
|
|
7
7
|
export * from "./endpoints/auth.js";
|
|
8
8
|
export * from "./endpoints/blocks.js";
|
|
9
|
+
export * from "./endpoints/blueprints.js";
|
|
9
10
|
export * from "./endpoints/entries.js";
|
|
10
11
|
export * from "./endpoints/events.js";
|
|
11
12
|
export * from "./endpoints/forms.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-blueprint.d.ts","sourceRoot":"","sources":["../../src/studio/define-blueprint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,wBAAgB,eAAe,CAAC,SAAS,EAAE,mBAAmB,GAAG,mBAAmB,CAEnF"}
|
package/dist/studio/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/studio/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AAExB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/studio/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AAExB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,SAAS,CAAC"}
|
package/dist/studio/index.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { Field, FieldType, FieldTypeToValue } from "./field";
|
|
2
|
+
import { Entry } from "../../types/entry";
|
|
3
|
+
type Nullable<T> = T | null;
|
|
2
4
|
type FieldValues<T extends readonly Field[]> = {
|
|
3
5
|
[K in T[number]["slug"]]: Extract<T[number], {
|
|
4
6
|
slug: K;
|
|
5
|
-
}> extends {
|
|
7
|
+
}> extends infer FieldDef ? FieldDef extends {
|
|
8
|
+
type: 'reference';
|
|
9
|
+
is_multiple: true;
|
|
10
|
+
} ? Nullable<Entry[]> : FieldDef extends {
|
|
11
|
+
type: 'reference';
|
|
12
|
+
} ? Nullable<Entry> : FieldDef extends {
|
|
6
13
|
type: infer Type;
|
|
7
|
-
} ? Type extends FieldType ? FieldTypeToValue[Type] : never : never;
|
|
14
|
+
} ? Type extends FieldType ? FieldTypeToValue[Type] : never : never : never;
|
|
8
15
|
};
|
|
9
16
|
export interface BlockSchema<TFields extends readonly Field[]> {
|
|
10
17
|
fields: TFields;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../../src/studio/types/block.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../../src/studio/types/block.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAG5B,KAAK,WAAW,CAAC,CAAC,SAAS,SAAS,KAAK,EAAE,IAAI;KAC5C,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,SAAS,MAAM,QAAQ,GAC5E,QAAQ,SAAS;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,WAAW,EAAE,IAAI,CAAA;KAAE,GACvD,QAAQ,CAAC,KAAK,EAAE,CAAC,GACjB,QAAQ,SAAS;QAAE,IAAI,EAAE,WAAW,CAAA;KAAE,GACpC,QAAQ,CAAC,KAAK,CAAC,GACf,QAAQ,SAAS;QAAE,IAAI,EAAE,MAAM,IAAI,CAAA;KAAE,GACnC,IAAI,SAAS,SAAS,GACpB,gBAAgB,CAAC,IAAI,CAAC,GACtB,KAAK,GACP,KAAK,GACX,KAAK;CACV,CAAC;AAEF,MAAM,WAAW,WAAW,CAAC,OAAO,SAAS,SAAS,KAAK,EAAE;IAC3D,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe,CAAC,OAAO,SAAS,SAAS,KAAK,EAAE;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7B,SAAS,EAAE,cAAc,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,eAAe;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY,CAAC,OAAO,SAAS,WAAW,CAAC,SAAS,KAAK,EAAE,CAAC;IACzE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvC,UAAU,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB,CAAC,OAAO,SAAS,WAAW,CAAC,SAAS,KAAK,EAAE,CAAC;IAChF,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;IAC7B,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;CACpG;AAED,MAAM,MAAM,cAAc,CAAC,OAAO,SAAS,WAAW,CAAC,SAAS,KAAK,EAAE,CAAC,IAAI,KAAK,CAAC,aAAa,CAC7F,mBAAmB,CAAC,OAAO,CAAC,CAC7B,CAAC"}
|
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
import { MediaItem } from "../../types";
|
|
2
|
+
import { Entry } from "../../types/entry";
|
|
2
3
|
type Nullable<T> = T | null;
|
|
3
4
|
export type FieldTypeToValue = {
|
|
4
5
|
boolean: Nullable<boolean>;
|
|
6
|
+
date: Nullable<string>;
|
|
7
|
+
datetime: Nullable<string>;
|
|
8
|
+
email: Nullable<string>;
|
|
5
9
|
event_select: Nullable<string>;
|
|
10
|
+
fieldset: never;
|
|
6
11
|
form_select: Nullable<string>;
|
|
7
12
|
image: Nullable<MediaItem>;
|
|
8
13
|
image_list: Nullable<MediaItem[]>;
|
|
14
|
+
json: Nullable<any>;
|
|
9
15
|
list_array: Nullable<string[]>;
|
|
16
|
+
location: Nullable<string>;
|
|
17
|
+
markdown: Nullable<string>;
|
|
10
18
|
media: Nullable<MediaItem>;
|
|
11
19
|
menu_select: Nullable<string>;
|
|
12
20
|
number: Nullable<number>;
|
|
13
21
|
press_select: Nullable<string>;
|
|
22
|
+
reference: Nullable<Entry | Entry[]>;
|
|
14
23
|
repeater: Nullable<any[]>;
|
|
15
24
|
rich_text: Nullable<string>;
|
|
25
|
+
select: Nullable<string>;
|
|
16
26
|
separator: never;
|
|
27
|
+
slug: Nullable<string>;
|
|
17
28
|
spacer: never;
|
|
18
29
|
text: Nullable<string>;
|
|
19
30
|
textarea: Nullable<string>;
|
|
31
|
+
time: Nullable<string>;
|
|
20
32
|
url: Nullable<string>;
|
|
21
33
|
navigation_select: Nullable<string>;
|
|
22
34
|
page_select: Nullable<string>;
|
|
@@ -32,10 +44,20 @@ export type BaseField = {
|
|
|
32
44
|
label: string;
|
|
33
45
|
value: any;
|
|
34
46
|
}>;
|
|
47
|
+
allowed_references?: string[];
|
|
48
|
+
is_multiple?: boolean;
|
|
49
|
+
is_primary?: boolean;
|
|
50
|
+
show_in_list?: boolean;
|
|
51
|
+
order?: number;
|
|
52
|
+
type_id?: string | null;
|
|
35
53
|
fields?: Field[];
|
|
36
54
|
};
|
|
37
55
|
export type Field = {
|
|
38
|
-
[K in FieldType]: BaseField & {
|
|
56
|
+
[K in FieldType]: K extends 'reference' ? BaseField & {
|
|
57
|
+
type: K;
|
|
58
|
+
value?: FieldTypeToValue[K];
|
|
59
|
+
is_multiple?: boolean;
|
|
60
|
+
} : BaseField & {
|
|
39
61
|
type: K;
|
|
40
62
|
value?: FieldTypeToValue[K];
|
|
41
63
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../../src/studio/types/field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../../src/studio/types/field.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { Field, FieldType, FieldTypeToValue } from "./field";
|
|
2
|
+
import { Entry } from "../../types/entry";
|
|
3
|
+
type Nullable<T> = T | null;
|
|
2
4
|
type FieldValues<T extends readonly Field[]> = {
|
|
3
5
|
[K in T[number]["slug"]]: Extract<T[number], {
|
|
4
6
|
slug: K;
|
|
5
|
-
}> extends {
|
|
7
|
+
}> extends infer FieldDef ? FieldDef extends {
|
|
8
|
+
type: 'reference';
|
|
9
|
+
is_multiple: true;
|
|
10
|
+
} ? Nullable<Entry[]> : FieldDef extends {
|
|
11
|
+
type: 'reference';
|
|
12
|
+
} ? Nullable<Entry> : FieldDef extends {
|
|
6
13
|
type: infer Type;
|
|
7
|
-
} ? Type extends FieldType ? FieldTypeToValue[Type] : never : never;
|
|
14
|
+
} ? Type extends FieldType ? FieldTypeToValue[Type] : never : never : never;
|
|
8
15
|
};
|
|
9
16
|
export interface LayoutSchema<TFields extends readonly Field[]> {
|
|
10
17
|
fields: TFields;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/studio/types/layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/studio/types/layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAG5B,KAAK,WAAW,CAAC,CAAC,SAAS,SAAS,KAAK,EAAE,IAAI;KAC5C,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,SAAS,MAAM,QAAQ,GAC5E,QAAQ,SAAS;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,WAAW,EAAE,IAAI,CAAA;KAAE,GACvD,QAAQ,CAAC,KAAK,EAAE,CAAC,GACjB,QAAQ,SAAS;QAAE,IAAI,EAAE,WAAW,CAAA;KAAE,GACpC,QAAQ,CAAC,KAAK,CAAC,GACf,QAAQ,SAAS;QAAE,IAAI,EAAE,MAAM,IAAI,CAAA;KAAE,GACnC,IAAI,SAAS,SAAS,GACpB,gBAAgB,CAAC,IAAI,CAAC,GACtB,KAAK,GACP,KAAK,GACX,KAAK;CACV,CAAC;AAEF,MAAM,WAAW,YAAY,CAAC,OAAO,SAAS,SAAS,KAAK,EAAE;IAC5D,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB,CAAC,OAAO,SAAS,SAAS,KAAK,EAAE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;IAC9B,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,oBAAoB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;CAC7E;AAED,MAAM,WAAW,oBAAoB,CAAC,OAAO,SAAS,YAAY,CAAC,SAAS,KAAK,EAAE,CAAC;IAClF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;CACrG"}
|
|
@@ -1,10 +1,34 @@
|
|
|
1
|
+
export interface BlueprintField {
|
|
2
|
+
id: string;
|
|
3
|
+
blueprint_id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
slug: string;
|
|
6
|
+
type: string;
|
|
7
|
+
type_id: string | null;
|
|
8
|
+
is_primary: boolean;
|
|
9
|
+
is_multiple: boolean;
|
|
10
|
+
show_in_list: boolean;
|
|
11
|
+
order: number;
|
|
12
|
+
allowed_references: string[] | null;
|
|
13
|
+
options: Array<{
|
|
14
|
+
label: string;
|
|
15
|
+
value: any;
|
|
16
|
+
}> | null;
|
|
17
|
+
placeholder: string | null;
|
|
18
|
+
created_at: string;
|
|
19
|
+
updated_at: string;
|
|
20
|
+
}
|
|
1
21
|
export interface Blueprint {
|
|
2
22
|
id: string;
|
|
3
23
|
account_id: string;
|
|
4
24
|
name: string;
|
|
5
25
|
slug: string;
|
|
26
|
+
slug_single: string;
|
|
6
27
|
description: string | null;
|
|
7
|
-
|
|
28
|
+
is_routable: boolean;
|
|
29
|
+
has_location: boolean;
|
|
30
|
+
has_route_index: boolean;
|
|
31
|
+
fields: BlueprintField[];
|
|
8
32
|
created_at: string;
|
|
9
33
|
updated_at: string;
|
|
10
34
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blueprint.d.ts","sourceRoot":"","sources":["../../src/types/blueprint.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"blueprint.d.ts","sourceRoot":"","sources":["../../src/types/blueprint.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACpC,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC;IACrD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB"}
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -7,7 +7,8 @@ A TypeScript client library for [Backstage CMS](https://bckstg.app) with type-sa
|
|
|
7
7
|
- 🔐 Type-safe API client for Backstage CMS
|
|
8
8
|
- 🧱 Define custom blocks with full TypeScript support
|
|
9
9
|
- 📐 Define custom layouts with schema validation
|
|
10
|
-
-
|
|
10
|
+
- � Define custom blueprints (content types) with field schemas
|
|
11
|
+
- 🔄 CLI tools for syncing blocks, blueprints, and layouts
|
|
11
12
|
- ⚛️ React components for page metadata and structured data
|
|
12
13
|
- 🎨 Framework-agnostic design (works with Next.js, React, etc.)
|
|
13
14
|
|
|
@@ -90,11 +91,13 @@ const heroFields = [
|
|
|
90
91
|
slug: "title",
|
|
91
92
|
type: "text",
|
|
92
93
|
required: true,
|
|
94
|
+
placeholder: "Enter hero title...",
|
|
93
95
|
}),
|
|
94
96
|
defineField({
|
|
95
97
|
name: "Subtitle",
|
|
96
98
|
slug: "subtitle",
|
|
97
|
-
type: "
|
|
99
|
+
type: "textarea",
|
|
100
|
+
description: "Optional subtitle text",
|
|
98
101
|
}),
|
|
99
102
|
defineField({
|
|
100
103
|
name: "Background Image",
|
|
@@ -102,6 +105,25 @@ const heroFields = [
|
|
|
102
105
|
type: "image",
|
|
103
106
|
required: true,
|
|
104
107
|
}),
|
|
108
|
+
defineField({
|
|
109
|
+
name: "Display Style",
|
|
110
|
+
slug: "displayStyle",
|
|
111
|
+
type: "select",
|
|
112
|
+
options: [
|
|
113
|
+
{ label: "Full Width", value: "full" },
|
|
114
|
+
{ label: "Centered", value: "centered" },
|
|
115
|
+
{ label: "Left Aligned", value: "left" },
|
|
116
|
+
],
|
|
117
|
+
required: true,
|
|
118
|
+
}),
|
|
119
|
+
defineField({
|
|
120
|
+
name: "Featured Products",
|
|
121
|
+
slug: "featuredProducts",
|
|
122
|
+
type: "reference",
|
|
123
|
+
allowed_references: ["products"],
|
|
124
|
+
is_multiple: true,
|
|
125
|
+
description: "Select products to feature",
|
|
126
|
+
}),
|
|
105
127
|
] as const;
|
|
106
128
|
|
|
107
129
|
export const schema = defineBlockSchema({
|
|
@@ -143,14 +165,175 @@ export const heroBlock = defineBlock({
|
|
|
143
165
|
});
|
|
144
166
|
```
|
|
145
167
|
|
|
168
|
+
## Defining Custom Blueprints
|
|
169
|
+
|
|
170
|
+
Create content types (blueprints) with custom field schemas:
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
// blueprints/customer.ts
|
|
174
|
+
import { defineBlueprint } from "@antlur/backstage/studio";
|
|
175
|
+
|
|
176
|
+
export const customerBlueprint = defineBlueprint({
|
|
177
|
+
name: "Customer",
|
|
178
|
+
slug: "customers",
|
|
179
|
+
description: "Customer testimonials and information",
|
|
180
|
+
fields: [
|
|
181
|
+
{
|
|
182
|
+
name: "Name",
|
|
183
|
+
slug: "name",
|
|
184
|
+
type: "text",
|
|
185
|
+
is_primary: true, // Primary field for display
|
|
186
|
+
required: true,
|
|
187
|
+
placeholder: "Customer full name",
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: "Email",
|
|
191
|
+
slug: "email",
|
|
192
|
+
type: "email",
|
|
193
|
+
required: true,
|
|
194
|
+
placeholder: "customer@example.com",
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: "Company",
|
|
198
|
+
slug: "company",
|
|
199
|
+
type: "text",
|
|
200
|
+
placeholder: "Company name",
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: "Photo",
|
|
204
|
+
slug: "photo",
|
|
205
|
+
type: "image",
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
name: "Testimonial",
|
|
209
|
+
slug: "testimonial",
|
|
210
|
+
type: "textarea",
|
|
211
|
+
required: true,
|
|
212
|
+
placeholder: "Customer testimonial...",
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
name: "Rating",
|
|
216
|
+
slug: "rating",
|
|
217
|
+
type: "select",
|
|
218
|
+
options: [
|
|
219
|
+
{ label: "5 Stars", value: 5 },
|
|
220
|
+
{ label: "4 Stars", value: 4 },
|
|
221
|
+
{ label: "3 Stars", value: 3 },
|
|
222
|
+
{ label: "2 Stars", value: 2 },
|
|
223
|
+
{ label: "1 Star", value: 1 },
|
|
224
|
+
],
|
|
225
|
+
required: true,
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
name: "Show in Testimonials",
|
|
229
|
+
slug: "showInTestimonials",
|
|
230
|
+
type: "boolean",
|
|
231
|
+
show_in_list: true, // Show in admin list view
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
});
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Add blueprints to your config:
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
import { defineConfig } from "@antlur/backstage";
|
|
241
|
+
import { customerBlueprint } from "./blueprints/customer";
|
|
242
|
+
|
|
243
|
+
export default defineConfig({
|
|
244
|
+
accountId: process.env.BACKSTAGE_ACCOUNT_ID,
|
|
245
|
+
token: process.env.BACKSTAGE_API_KEY,
|
|
246
|
+
blueprints: [customerBlueprint],
|
|
247
|
+
});
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Using Reference Fields
|
|
251
|
+
|
|
252
|
+
Reference fields allow you to link to entries from specific blueprints. You can constrain which blueprints are allowed:
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
// blocks/testimonials/schema.ts
|
|
256
|
+
import { defineBlockSchema, defineField } from "@antlur/backstage/studio";
|
|
257
|
+
|
|
258
|
+
const testimonialFields = [
|
|
259
|
+
defineField({
|
|
260
|
+
name: "Customers",
|
|
261
|
+
slug: "customers",
|
|
262
|
+
type: "reference",
|
|
263
|
+
description: "Select customer entries",
|
|
264
|
+
allowed_references: ["customers"], // Only allow entries from the "customers" blueprint
|
|
265
|
+
is_multiple: true, // Allow multiple customer selections
|
|
266
|
+
required: true,
|
|
267
|
+
}),
|
|
268
|
+
defineField({
|
|
269
|
+
name: "Quote",
|
|
270
|
+
slug: "quote",
|
|
271
|
+
type: "textarea",
|
|
272
|
+
description: "The testimonial quote",
|
|
273
|
+
required: true,
|
|
274
|
+
}),
|
|
275
|
+
];
|
|
276
|
+
|
|
277
|
+
export const schema = defineBlockSchema({
|
|
278
|
+
fields: testimonialFields,
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
In your component, the reference field will contain the full entry data:
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
// blocks/testimonials/component.tsx
|
|
286
|
+
import type { BlockComponentProps } from "@antlur/backstage/studio";
|
|
287
|
+
import schema from "./schema";
|
|
288
|
+
|
|
289
|
+
export default function Testimonials({ block }: BlockComponentProps<typeof schema>) {
|
|
290
|
+
const { customers, quote } = block.fields;
|
|
291
|
+
|
|
292
|
+
return (
|
|
293
|
+
<div className="testimonial">
|
|
294
|
+
<blockquote>"{quote}"</blockquote>
|
|
295
|
+
<cite>
|
|
296
|
+
- {customers.map(customer => customer.name).join(", ")}
|
|
297
|
+
</cite> {/* Access entry properties */}
|
|
298
|
+
</div>
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
## Field Options
|
|
304
|
+
|
|
305
|
+
When defining fields for blocks and blueprints, you can set various options to customize their behavior:
|
|
306
|
+
|
|
307
|
+
### Common Field Options
|
|
308
|
+
|
|
309
|
+
- `name` (required): Display name for the field
|
|
310
|
+
- `slug` (required): Unique identifier for the field
|
|
311
|
+
- `type` (required): Field type (see supported types below)
|
|
312
|
+
- `description`: Help text shown to content editors
|
|
313
|
+
- `placeholder`: Placeholder text shown in input fields
|
|
314
|
+
- `required`: Whether the field is required
|
|
315
|
+
- `options`: For select fields, array of `{ label: string, value: any }` options
|
|
316
|
+
- `allowed_references`: For reference fields, array of blueprint slugs to reference
|
|
317
|
+
- `is_multiple`: For reference fields, allow multiple selections
|
|
318
|
+
|
|
319
|
+
### Blueprint-Specific Options
|
|
320
|
+
|
|
321
|
+
- `is_primary`: Mark as the primary field (used for display in lists)
|
|
322
|
+
- `show_in_list`: Show this field in admin list views
|
|
323
|
+
- `order`: Display order in forms (number)
|
|
324
|
+
- `type_id`: For fieldset references, the ID of the fieldset
|
|
325
|
+
|
|
146
326
|
## CLI Commands
|
|
147
327
|
|
|
148
|
-
Sync your blocks and layouts to Backstage CMS:
|
|
328
|
+
Sync your blocks, blueprints, and layouts to Backstage CMS:
|
|
149
329
|
|
|
150
330
|
```bash
|
|
151
331
|
# Sync blocks only
|
|
152
332
|
npx backstage sync blocks
|
|
153
333
|
|
|
334
|
+
# Sync blueprints only
|
|
335
|
+
npx backstage sync blueprints
|
|
336
|
+
|
|
154
337
|
# Sync layouts only
|
|
155
338
|
npx backstage sync layouts
|
|
156
339
|
|
|
@@ -177,6 +360,7 @@ The client provides the following services:
|
|
|
177
360
|
|
|
178
361
|
- `client.pages` - Page management
|
|
179
362
|
- `client.blocks` - Block management
|
|
363
|
+
- `client.blueprints` - Blueprint (content type) management
|
|
180
364
|
- `client.layouts` - Layout management
|
|
181
365
|
- `client.locations` - Location management
|
|
182
366
|
- `client.events` - Event management
|
|
@@ -190,24 +374,35 @@ The client provides the following services:
|
|
|
190
374
|
|
|
191
375
|
## Field Types
|
|
192
376
|
|
|
193
|
-
Supported field types for blocks and layouts:
|
|
377
|
+
Supported field types for blocks, blueprints, and layouts:
|
|
194
378
|
|
|
195
379
|
- `text` - Single-line text input
|
|
196
380
|
- `textarea` - Multi-line text input
|
|
197
381
|
- `rich_text` - Rich text editor
|
|
382
|
+
- `markdown` - Markdown editor
|
|
198
383
|
- `number` - Numeric input
|
|
199
384
|
- `boolean` - Checkbox
|
|
385
|
+
- `select` - Select from predefined options
|
|
386
|
+
- `reference` - Reference to entries from specific blueprints (supports `is_multiple` for multiple selections)
|
|
200
387
|
- `url` - URL input
|
|
388
|
+
- `email` - Email input
|
|
389
|
+
- `slug` - URL slug input
|
|
390
|
+
- `date` - Date picker
|
|
391
|
+
- `time` - Time picker
|
|
392
|
+
- `datetime` - Date and time picker
|
|
393
|
+
- `location` - Location picker
|
|
201
394
|
- `image` - Single image picker
|
|
202
395
|
- `image_list` - Multiple image picker
|
|
203
396
|
- `media` - Media item picker
|
|
204
397
|
- `list_array` - Array of strings
|
|
205
398
|
- `repeater` - Repeatable field group
|
|
399
|
+
- `fieldset` - Grouped fields
|
|
206
400
|
- `event_select` - Event selector
|
|
207
401
|
- `menu_select` - Menu selector
|
|
208
402
|
- `form_select` - Form selector
|
|
209
403
|
- `press_select` - Press release selector
|
|
210
404
|
- `navigation_select` - Navigation selector
|
|
405
|
+
- `page_select` - Page selector
|
|
211
406
|
|
|
212
407
|
## React Components
|
|
213
408
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { BackstageUserConfig } from "../../config.js";
|
|
2
|
+
import { BackstageClient } from "../../client.js";
|
|
3
|
+
|
|
4
|
+
export async function syncBlueprints(config: BackstageUserConfig) {
|
|
5
|
+
const client = new BackstageClient(config);
|
|
6
|
+
|
|
7
|
+
if (!config.blueprints || !config.blueprints.length) {
|
|
8
|
+
console.log("No blueprints found in config");
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const syncPromises = config.blueprints.map(async (blueprint) => {
|
|
13
|
+
const blueprintData = {
|
|
14
|
+
name: blueprint.name,
|
|
15
|
+
slug: blueprint.slug,
|
|
16
|
+
slug_single: blueprint.slug_single,
|
|
17
|
+
description: blueprint.description,
|
|
18
|
+
is_routable: blueprint.is_routable,
|
|
19
|
+
has_location: blueprint.has_location,
|
|
20
|
+
has_route_index: blueprint.has_route_index,
|
|
21
|
+
fields: blueprint.fields,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
await client.blueprints.create(blueprintData);
|
|
26
|
+
console.log(`✓ Blueprint ${blueprint.slug} created`);
|
|
27
|
+
} catch (err: any) {
|
|
28
|
+
if (err?.response?.status === 409) {
|
|
29
|
+
const id = err.response.data;
|
|
30
|
+
console.log(`⚠ Blueprint ${blueprint.slug} already exists with id ${id}. Updating...`);
|
|
31
|
+
try {
|
|
32
|
+
await client.blueprints.update(id, blueprintData);
|
|
33
|
+
console.log(`✓ Blueprint ${blueprint.slug} updated`);
|
|
34
|
+
} catch (updateErr: any) {
|
|
35
|
+
console.error(`✗ Failed to update blueprint ${blueprint.slug}:`, updateErr?.message || updateErr);
|
|
36
|
+
}
|
|
37
|
+
} else {
|
|
38
|
+
console.error(`✗ Failed to create blueprint ${blueprint.slug}:`, err?.message || err);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
await Promise.all(syncPromises);
|
|
44
|
+
console.log(`\nSync complete: ${config.blueprints.length} blueprint(s) processed`);
|
|
45
|
+
}
|
package/src/cli/cli.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { resolve } from "path";
|
|
|
5
5
|
import { program } from "commander";
|
|
6
6
|
import { loadBackstageConfig } from "./load-config.js";
|
|
7
7
|
import { syncBlocks } from "./actions/sync-blocks.js";
|
|
8
|
+
import { syncBlueprints } from "./actions/sync-blueprints.js";
|
|
8
9
|
import { syncLayouts } from "./actions/sync-layouts.js";
|
|
9
10
|
|
|
10
11
|
config({ path: resolve(process.cwd(), ".env") });
|
|
@@ -16,7 +17,7 @@ program
|
|
|
16
17
|
|
|
17
18
|
program
|
|
18
19
|
.command("sync <type>")
|
|
19
|
-
.description("Sync blocks and layouts with the Backstage CMS")
|
|
20
|
+
.description("Sync blocks, blueprints, and layouts with the Backstage CMS")
|
|
20
21
|
.action(async (type) => {
|
|
21
22
|
const backstageConfig = await loadBackstageConfig();
|
|
22
23
|
|
|
@@ -30,6 +31,11 @@ program
|
|
|
30
31
|
return;
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
if (type === "blueprints") {
|
|
35
|
+
await syncBlueprints(backstageConfig);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
33
39
|
if (type === "layouts") {
|
|
34
40
|
await syncLayouts(backstageConfig);
|
|
35
41
|
return;
|
|
@@ -37,11 +43,12 @@ program
|
|
|
37
43
|
|
|
38
44
|
if (type === "all") {
|
|
39
45
|
await syncBlocks(backstageConfig);
|
|
46
|
+
await syncBlueprints(backstageConfig);
|
|
40
47
|
await syncLayouts(backstageConfig);
|
|
41
48
|
return;
|
|
42
49
|
}
|
|
43
50
|
|
|
44
|
-
console.error(`Unknown type: ${type}. Valid types are: blocks, layouts, all`);
|
|
51
|
+
console.error(`Unknown type: ${type}. Valid types are: blocks, blueprints, layouts, all`);
|
|
45
52
|
process.exit(1);
|
|
46
53
|
});
|
|
47
54
|
|
package/src/client.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { getGlobalConfig, BackstageUserConfig } from "./config.js";
|
|
|
2
2
|
import { AlertService } from "./endpoints/alerts.js";
|
|
3
3
|
import { AuthService } from "./endpoints/auth.js";
|
|
4
4
|
import { BlocksService } from "./endpoints/blocks.js";
|
|
5
|
+
import { BlueprintsService } from "./endpoints/blueprints.js";
|
|
5
6
|
import { EntryService } from "./endpoints/entries.js";
|
|
6
7
|
import { EventService } from "./endpoints/events.js";
|
|
7
8
|
import { FormService } from "./endpoints/forms.js";
|
|
@@ -27,6 +28,7 @@ export class BackstageClient {
|
|
|
27
28
|
public readonly alerts: AlertService;
|
|
28
29
|
public readonly auth: AuthService;
|
|
29
30
|
public readonly blocks: BlocksService;
|
|
31
|
+
public readonly blueprints: BlueprintsService;
|
|
30
32
|
public readonly entries: EntryService;
|
|
31
33
|
public readonly events: EventService;
|
|
32
34
|
public readonly forms: FormService;
|
|
@@ -69,6 +71,7 @@ export class BackstageClient {
|
|
|
69
71
|
this.alerts = new AlertService(this);
|
|
70
72
|
this.auth = new AuthService(this);
|
|
71
73
|
this.blocks = new BlocksService(this);
|
|
74
|
+
this.blueprints = new BlueprintsService(this);
|
|
72
75
|
this.entries = new EntryService(this);
|
|
73
76
|
this.events = new EventService(this);
|
|
74
77
|
this.forms = new FormService(this);
|
package/src/config.ts
CHANGED
|
@@ -2,11 +2,35 @@ import type { BlockDefinition } from "./studio/types/index.js";
|
|
|
2
2
|
|
|
3
3
|
const DEFAULT_BASE_URL = "https://bckstg.app/api";
|
|
4
4
|
|
|
5
|
+
export interface BlueprintDefinition {
|
|
6
|
+
name: string;
|
|
7
|
+
slug: string;
|
|
8
|
+
slug_single?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
is_routable?: boolean;
|
|
11
|
+
has_location?: boolean;
|
|
12
|
+
has_route_index?: boolean;
|
|
13
|
+
fields: Array<{
|
|
14
|
+
name: string;
|
|
15
|
+
slug: string;
|
|
16
|
+
type: string;
|
|
17
|
+
type_id?: string | null;
|
|
18
|
+
is_primary?: boolean;
|
|
19
|
+
is_multiple?: boolean;
|
|
20
|
+
show_in_list?: boolean;
|
|
21
|
+
order: number;
|
|
22
|
+
allowed_references?: string[];
|
|
23
|
+
options?: Array<{ label: string; value: any }>;
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
|
|
5
28
|
export interface BackstageUserConfig {
|
|
6
29
|
accountId?: string | undefined;
|
|
7
30
|
token?: string | undefined;
|
|
8
31
|
baseURL?: string;
|
|
9
32
|
blocks?: BlockDefinition<any>[] | undefined;
|
|
33
|
+
blueprints?: BlueprintDefinition[] | undefined;
|
|
10
34
|
layouts?: any[] | undefined;
|
|
11
35
|
onError?: (error: Error) => void;
|
|
12
36
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ApiCollectionResponse, ApiSingleResponse } from "../types/index";
|
|
2
|
+
import type { Blueprint } from "../types/blueprint";
|
|
3
|
+
import { BaseService } from "./base.js";
|
|
4
|
+
|
|
5
|
+
export interface CreateBlueprintParams {
|
|
6
|
+
name: string;
|
|
7
|
+
slug: string;
|
|
8
|
+
slug_single?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
is_routable?: boolean;
|
|
11
|
+
has_location?: boolean;
|
|
12
|
+
has_route_index?: boolean;
|
|
13
|
+
fields: Array<{
|
|
14
|
+
name: string;
|
|
15
|
+
slug: string;
|
|
16
|
+
type: string;
|
|
17
|
+
type_id?: string | null;
|
|
18
|
+
is_primary?: boolean;
|
|
19
|
+
is_multiple?: boolean;
|
|
20
|
+
show_in_list?: boolean;
|
|
21
|
+
order: number;
|
|
22
|
+
allowed_references?: string[];
|
|
23
|
+
options?: Array<{ label: string; value: any }>;
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface UpdateBlueprintParams extends Partial<CreateBlueprintParams> {}
|
|
29
|
+
|
|
30
|
+
export class BlueprintsService extends BaseService {
|
|
31
|
+
async list(options?: RequestInit): Promise<Blueprint[]> {
|
|
32
|
+
const { data } = await this.client.get<ApiCollectionResponse<Blueprint>>("/blueprints", options);
|
|
33
|
+
return data;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async get(id: string, options?: RequestInit): Promise<Blueprint | null> {
|
|
37
|
+
try {
|
|
38
|
+
const { data } = await this.client.get<ApiSingleResponse<Blueprint>>(`/blueprints/${id}`, options);
|
|
39
|
+
return data;
|
|
40
|
+
} catch (error) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async create(params: CreateBlueprintParams, options?: RequestInit): Promise<Blueprint> {
|
|
46
|
+
const { data } = await this.client.post<ApiSingleResponse<Blueprint>>("/blueprints", params, options);
|
|
47
|
+
return data;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async update(id: string, params: UpdateBlueprintParams, options?: RequestInit): Promise<Blueprint> {
|
|
51
|
+
const { data } = await this.client.put<ApiSingleResponse<Blueprint>>(`/blueprints/${id}`, params, options);
|
|
52
|
+
return data;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async delete(id: string, options?: RequestInit): Promise<void> {
|
|
56
|
+
await this.client.delete(`/blueprints/${id}`, options);
|
|
57
|
+
}
|
|
58
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ export { BackstageClient } from "./client.js";
|
|
|
8
8
|
export * from "./endpoints/alerts.js";
|
|
9
9
|
export * from "./endpoints/auth.js";
|
|
10
10
|
export * from "./endpoints/blocks.js";
|
|
11
|
+
export * from "./endpoints/blueprints.js";
|
|
11
12
|
export * from "./endpoints/entries.js";
|
|
12
13
|
export * from "./endpoints/events.js";
|
|
13
14
|
export * from "./endpoints/forms.js";
|
package/src/studio/index.ts
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { Field, FieldType, FieldTypeToValue } from "./field";
|
|
2
|
+
import { Entry } from "../../types/entry";
|
|
3
|
+
|
|
4
|
+
type Nullable<T> = T | null;
|
|
2
5
|
|
|
3
6
|
// Type for field values from array-based fields
|
|
4
7
|
type FieldValues<T extends readonly Field[]> = {
|
|
5
|
-
[K in T[number]["slug"]]: Extract<T[number], { slug: K }> extends
|
|
6
|
-
?
|
|
7
|
-
?
|
|
8
|
-
:
|
|
8
|
+
[K in T[number]["slug"]]: Extract<T[number], { slug: K }> extends infer FieldDef
|
|
9
|
+
? FieldDef extends { type: 'reference'; is_multiple: true }
|
|
10
|
+
? Nullable<Entry[]>
|
|
11
|
+
: FieldDef extends { type: 'reference' }
|
|
12
|
+
? Nullable<Entry>
|
|
13
|
+
: FieldDef extends { type: infer Type }
|
|
14
|
+
? Type extends FieldType
|
|
15
|
+
? FieldTypeToValue[Type]
|
|
16
|
+
: never
|
|
17
|
+
: never
|
|
9
18
|
: never;
|
|
10
19
|
};
|
|
11
20
|
|
|
@@ -1,24 +1,36 @@
|
|
|
1
1
|
import { MediaItem } from "../../types";
|
|
2
|
+
import { Entry } from "../../types/entry";
|
|
2
3
|
|
|
3
4
|
type Nullable<T> = T | null;
|
|
4
5
|
|
|
5
6
|
export type FieldTypeToValue = {
|
|
6
7
|
boolean: Nullable<boolean>;
|
|
8
|
+
date: Nullable<string>;
|
|
9
|
+
datetime: Nullable<string>;
|
|
10
|
+
email: Nullable<string>;
|
|
7
11
|
event_select: Nullable<string>;
|
|
12
|
+
fieldset: never;
|
|
8
13
|
form_select: Nullable<string>;
|
|
9
14
|
image: Nullable<MediaItem>;
|
|
10
15
|
image_list: Nullable<MediaItem[]>;
|
|
16
|
+
json: Nullable<any>;
|
|
11
17
|
list_array: Nullable<string[]>;
|
|
18
|
+
location: Nullable<string>;
|
|
19
|
+
markdown: Nullable<string>;
|
|
12
20
|
media: Nullable<MediaItem>;
|
|
13
21
|
menu_select: Nullable<string>;
|
|
14
22
|
number: Nullable<number>;
|
|
15
23
|
press_select: Nullable<string>;
|
|
24
|
+
reference: Nullable<Entry | Entry[]>;
|
|
16
25
|
repeater: Nullable<any[]>;
|
|
17
26
|
rich_text: Nullable<string>;
|
|
27
|
+
select: Nullable<string>;
|
|
18
28
|
separator: never;
|
|
29
|
+
slug: Nullable<string>;
|
|
19
30
|
spacer: never;
|
|
20
31
|
text: Nullable<string>;
|
|
21
32
|
textarea: Nullable<string>;
|
|
33
|
+
time: Nullable<string>;
|
|
22
34
|
url: Nullable<string>;
|
|
23
35
|
navigation_select: Nullable<string>;
|
|
24
36
|
page_select: Nullable<string>;
|
|
@@ -32,14 +44,26 @@ export type BaseField = {
|
|
|
32
44
|
placeholder?: string;
|
|
33
45
|
required?: boolean;
|
|
34
46
|
options?: Array<{ label: string; value: any }>;
|
|
47
|
+
allowed_references?: string[];
|
|
48
|
+
is_multiple?: boolean;
|
|
49
|
+
is_primary?: boolean;
|
|
50
|
+
show_in_list?: boolean;
|
|
51
|
+
order?: number;
|
|
52
|
+
type_id?: string | null;
|
|
35
53
|
fields?: Field[];
|
|
36
54
|
};
|
|
37
55
|
|
|
38
56
|
export type Field = {
|
|
39
|
-
[K in FieldType]:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
57
|
+
[K in FieldType]: K extends 'reference'
|
|
58
|
+
? BaseField & {
|
|
59
|
+
type: K;
|
|
60
|
+
value?: FieldTypeToValue[K];
|
|
61
|
+
is_multiple?: boolean;
|
|
62
|
+
}
|
|
63
|
+
: BaseField & {
|
|
64
|
+
type: K;
|
|
65
|
+
value?: FieldTypeToValue[K];
|
|
66
|
+
};
|
|
43
67
|
}[FieldType];
|
|
44
68
|
|
|
45
69
|
// export interface Field<T extends FieldType = FieldType> {
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { Field, FieldType, FieldTypeToValue } from "./field";
|
|
2
|
+
import { Entry } from "../../types/entry";
|
|
3
|
+
|
|
4
|
+
type Nullable<T> = T | null;
|
|
2
5
|
|
|
3
6
|
// Type for field values from array-based fields
|
|
4
7
|
type FieldValues<T extends readonly Field[]> = {
|
|
5
|
-
[K in T[number]["slug"]]: Extract<T[number], { slug: K }> extends
|
|
6
|
-
?
|
|
7
|
-
?
|
|
8
|
-
:
|
|
8
|
+
[K in T[number]["slug"]]: Extract<T[number], { slug: K }> extends infer FieldDef
|
|
9
|
+
? FieldDef extends { type: 'reference'; is_multiple: true }
|
|
10
|
+
? Nullable<Entry[]>
|
|
11
|
+
: FieldDef extends { type: 'reference' }
|
|
12
|
+
? Nullable<Entry>
|
|
13
|
+
: FieldDef extends { type: infer Type }
|
|
14
|
+
? Type extends FieldType
|
|
15
|
+
? FieldTypeToValue[Type]
|
|
16
|
+
: never
|
|
17
|
+
: never
|
|
9
18
|
: never;
|
|
10
19
|
};
|
|
11
20
|
|
package/src/types/blueprint.ts
CHANGED
|
@@ -1,10 +1,32 @@
|
|
|
1
|
+
export interface BlueprintField {
|
|
2
|
+
id: string;
|
|
3
|
+
blueprint_id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
slug: string;
|
|
6
|
+
type: string;
|
|
7
|
+
type_id: string | null;
|
|
8
|
+
is_primary: boolean;
|
|
9
|
+
is_multiple: boolean;
|
|
10
|
+
show_in_list: boolean;
|
|
11
|
+
order: number;
|
|
12
|
+
allowed_references: string[] | null;
|
|
13
|
+
options: Array<{ label: string; value: any }> | null;
|
|
14
|
+
placeholder: string | null;
|
|
15
|
+
created_at: string;
|
|
16
|
+
updated_at: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
1
19
|
export interface Blueprint {
|
|
2
20
|
id: string;
|
|
3
21
|
account_id: string;
|
|
4
22
|
name: string;
|
|
5
23
|
slug: string;
|
|
24
|
+
slug_single: string;
|
|
6
25
|
description: string | null;
|
|
7
|
-
|
|
26
|
+
is_routable: boolean;
|
|
27
|
+
has_location: boolean;
|
|
28
|
+
has_route_index: boolean;
|
|
29
|
+
fields: BlueprintField[];
|
|
8
30
|
created_at: string;
|
|
9
31
|
updated_at: string;
|
|
10
32
|
}
|