@contrail/extensions-sdk 1.0.34 → 1.0.35
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.
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { User } from '@contrail/entity-types';
|
|
2
|
+
import { DocumentGenerationIntent } from './document-generation';
|
|
2
3
|
interface Document {
|
|
3
4
|
id: string;
|
|
4
5
|
name: string;
|
|
@@ -122,6 +123,11 @@ export interface BoardContext {
|
|
|
122
123
|
rootWorkspaceId?: string;
|
|
123
124
|
typeId?: string;
|
|
124
125
|
workspaceId?: string;
|
|
126
|
+
/**
|
|
127
|
+
* Why the host opened this extension, when it opened it against generated
|
|
128
|
+
* content. Absent on an ordinary launch from a menu.
|
|
129
|
+
*/
|
|
130
|
+
documentGenerationIntent?: DocumentGenerationIntent;
|
|
125
131
|
}
|
|
126
132
|
export interface ShowcaseContext {
|
|
127
133
|
id: string;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The contract for an extension that generates board content.
|
|
3
|
+
*
|
|
4
|
+
* Any extension that stamps `documentGenerationConfigId` onto elements is
|
|
5
|
+
* claiming a block of someone's board, and the board offers Refresh, Configure,
|
|
6
|
+
* Select all and Details against that claim. Those only work if the extension
|
|
7
|
+
* holds up its end, which is this file.
|
|
8
|
+
*
|
|
9
|
+
* 1. Write a `document-generation-config` shaped like {@link DocumentGenerationConfigRecord}
|
|
10
|
+
* - `kind: 'app'` at minimum, or the board treats it as the built-in
|
|
11
|
+
* generator's and that editor will fail on the missing fields.
|
|
12
|
+
* 2. Stamp that config's id onto EVERY element you create, and scope every read
|
|
13
|
+
* and delete to elements carrying it. Elements without the stamp are someone
|
|
14
|
+
* else's.
|
|
15
|
+
* 3. Read {@link DocumentGenerationApp.getIntent} on launch and honour the mode.
|
|
16
|
+
* `regenerate` means: same spec, latest data, no questions asked.
|
|
17
|
+
* 4. When `headless` is true, render nothing and wait for nobody. Finish with
|
|
18
|
+
* {@link DocumentGenerationApp.complete} or {@link DocumentGenerationApp.fail} -
|
|
19
|
+
* the host has no other way to tell success from an extension that gave up.
|
|
20
|
+
* 5. Declare `supportsDocumentGeneration` in app.yml, and
|
|
21
|
+
* `supportsHeadlessRegenerate` if you honour rule 4.
|
|
22
|
+
*/
|
|
23
|
+
export declare const GENERATION_COMMAND: {
|
|
24
|
+
readonly progress: "generation:progress";
|
|
25
|
+
readonly complete: "generation:complete";
|
|
26
|
+
readonly failed: "generation:failed";
|
|
27
|
+
};
|
|
28
|
+
export declare type DocumentGenerationMode = 'create' | 'edit' | 'regenerate';
|
|
29
|
+
export interface DocumentGenerationIntent {
|
|
30
|
+
mode: DocumentGenerationMode;
|
|
31
|
+
/** Absent for `create`. */
|
|
32
|
+
documentGenerationConfigId?: string;
|
|
33
|
+
/** True when no UI will be seen and no user is waiting. */
|
|
34
|
+
headless?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/** One row of the board's details panel. The host renders these verbatim. */
|
|
37
|
+
export interface GenerationSummaryRow {
|
|
38
|
+
label: string;
|
|
39
|
+
value: string;
|
|
40
|
+
}
|
|
41
|
+
export interface GenerationSource {
|
|
42
|
+
/** An entity name the platform can read, e.g. `assortment`. */
|
|
43
|
+
kind: string;
|
|
44
|
+
id: string;
|
|
45
|
+
label?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface GenerationReference {
|
|
48
|
+
appIdentifier: string;
|
|
49
|
+
extensionIdentifier: string;
|
|
50
|
+
/**
|
|
51
|
+
* Which of the app's generators made this, when it has more than one.
|
|
52
|
+
* Names the generator, never its output - the same extension may produce
|
|
53
|
+
* frames of cards, a chart or a table.
|
|
54
|
+
*/
|
|
55
|
+
generatorId?: string;
|
|
56
|
+
generatorVersion?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The fields the board reads off a `document-generation-config`. Anything else -
|
|
60
|
+
* `spec` in particular - is the extension's own and the host never interprets it.
|
|
61
|
+
*/
|
|
62
|
+
export interface DocumentGenerationConfigRecord {
|
|
63
|
+
id?: string;
|
|
64
|
+
/** `app` for anything an installed app generated; `native` is the built-in generator. */
|
|
65
|
+
kind: 'app';
|
|
66
|
+
name: string;
|
|
67
|
+
documentId: string;
|
|
68
|
+
generatorRef: GenerationReference;
|
|
69
|
+
/** Drives the source links and the staleness check. */
|
|
70
|
+
sources: GenerationSource[];
|
|
71
|
+
/** Opaque to the host: whatever the layout needs to run again. */
|
|
72
|
+
spec: unknown;
|
|
73
|
+
specVersion: number;
|
|
74
|
+
/** What the details panel shows. Written by the extension; nothing else can. */
|
|
75
|
+
summary?: GenerationSummaryRow[];
|
|
76
|
+
/** What the board may offer against this content. `headlessRefresh` enables Refresh. */
|
|
77
|
+
capabilities?: {
|
|
78
|
+
headlessRefresh?: boolean;
|
|
79
|
+
};
|
|
80
|
+
lastGeneratedOn?: string;
|
|
81
|
+
anchor?: {
|
|
82
|
+
x: number;
|
|
83
|
+
y: number;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export interface GenerationResult {
|
|
87
|
+
created: number;
|
|
88
|
+
updated: number;
|
|
89
|
+
deleted: number;
|
|
90
|
+
unchanged: number;
|
|
91
|
+
/**
|
|
92
|
+
* False when the run replaced its elements wholesale rather than diffing, so
|
|
93
|
+
* the counts describe a rewrite. Defaults to true.
|
|
94
|
+
*/
|
|
95
|
+
isDiff?: boolean;
|
|
96
|
+
}
|
|
97
|
+
export declare class DocumentGenerationApp {
|
|
98
|
+
/** Why the host opened this extension. Absent when it was opened from a menu. */
|
|
99
|
+
static getIntent(): DocumentGenerationIntent | undefined;
|
|
100
|
+
static isHeadless(): boolean;
|
|
101
|
+
/** Optional. Gives the host something to show while a long run proceeds. */
|
|
102
|
+
static progress(message: string): void;
|
|
103
|
+
/** Required to end a headless run that succeeded. */
|
|
104
|
+
static complete(result: GenerationResult): void;
|
|
105
|
+
/** Required to end a headless run that failed. The message reaches the board. */
|
|
106
|
+
static fail(message: string): void;
|
|
107
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DocumentGenerationApp = exports.GENERATION_COMMAND = void 0;
|
|
4
|
+
const actions_1 = require("../actions/actions");
|
|
5
|
+
const app_context_1 = require("./app-context");
|
|
6
|
+
/**
|
|
7
|
+
* The contract for an extension that generates board content.
|
|
8
|
+
*
|
|
9
|
+
* Any extension that stamps `documentGenerationConfigId` onto elements is
|
|
10
|
+
* claiming a block of someone's board, and the board offers Refresh, Configure,
|
|
11
|
+
* Select all and Details against that claim. Those only work if the extension
|
|
12
|
+
* holds up its end, which is this file.
|
|
13
|
+
*
|
|
14
|
+
* 1. Write a `document-generation-config` shaped like {@link DocumentGenerationConfigRecord}
|
|
15
|
+
* - `kind: 'app'` at minimum, or the board treats it as the built-in
|
|
16
|
+
* generator's and that editor will fail on the missing fields.
|
|
17
|
+
* 2. Stamp that config's id onto EVERY element you create, and scope every read
|
|
18
|
+
* and delete to elements carrying it. Elements without the stamp are someone
|
|
19
|
+
* else's.
|
|
20
|
+
* 3. Read {@link DocumentGenerationApp.getIntent} on launch and honour the mode.
|
|
21
|
+
* `regenerate` means: same spec, latest data, no questions asked.
|
|
22
|
+
* 4. When `headless` is true, render nothing and wait for nobody. Finish with
|
|
23
|
+
* {@link DocumentGenerationApp.complete} or {@link DocumentGenerationApp.fail} -
|
|
24
|
+
* the host has no other way to tell success from an extension that gave up.
|
|
25
|
+
* 5. Declare `supportsDocumentGeneration` in app.yml, and
|
|
26
|
+
* `supportsHeadlessRegenerate` if you honour rule 4.
|
|
27
|
+
*/
|
|
28
|
+
exports.GENERATION_COMMAND = {
|
|
29
|
+
progress: 'generation:progress',
|
|
30
|
+
complete: 'generation:complete',
|
|
31
|
+
failed: 'generation:failed',
|
|
32
|
+
};
|
|
33
|
+
class DocumentGenerationApp {
|
|
34
|
+
/** Why the host opened this extension. Absent when it was opened from a menu. */
|
|
35
|
+
static getIntent() {
|
|
36
|
+
var _a, _b, _c;
|
|
37
|
+
return (_c = (_b = (_a = (0, app_context_1.getAppContext)()) === null || _a === void 0 ? void 0 : _a.appContext) === null || _b === void 0 ? void 0 : _b.board) === null || _c === void 0 ? void 0 : _c.documentGenerationIntent;
|
|
38
|
+
}
|
|
39
|
+
static isHeadless() {
|
|
40
|
+
var _a;
|
|
41
|
+
return ((_a = DocumentGenerationApp.getIntent()) === null || _a === void 0 ? void 0 : _a.headless) === true;
|
|
42
|
+
}
|
|
43
|
+
/** Optional. Gives the host something to show while a long run proceeds. */
|
|
44
|
+
static progress(message) {
|
|
45
|
+
(0, actions_1.getExtensionActions)().sendMessageToHost({ command: exports.GENERATION_COMMAND.progress, data: { message } });
|
|
46
|
+
}
|
|
47
|
+
/** Required to end a headless run that succeeded. */
|
|
48
|
+
static complete(result) {
|
|
49
|
+
(0, actions_1.getExtensionActions)().sendMessageToHost({ command: exports.GENERATION_COMMAND.complete, data: result });
|
|
50
|
+
}
|
|
51
|
+
/** Required to end a headless run that failed. The message reaches the board. */
|
|
52
|
+
static fail(message) {
|
|
53
|
+
(0, actions_1.getExtensionActions)().sendMessageToHost({ command: exports.GENERATION_COMMAND.failed, data: { message } });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.DocumentGenerationApp = DocumentGenerationApp;
|
package/lib/apps/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { getAppContext, AppContext, BoardContext, PlanContext, PlanFilterCriterion, PlanSortCriterion, PlanViewState, ShowcaseContext, VibeIQAppType, } from './app-context';
|
|
2
|
+
export * from './document-generation';
|
|
2
3
|
export * from './boards';
|
|
3
4
|
export * from './plan';
|
|
4
5
|
export * from './showcase';
|
package/lib/apps/index.js
CHANGED
|
@@ -18,6 +18,7 @@ exports.VibeIQAppType = exports.getAppContext = void 0;
|
|
|
18
18
|
var app_context_1 = require("./app-context");
|
|
19
19
|
Object.defineProperty(exports, "getAppContext", { enumerable: true, get: function () { return app_context_1.getAppContext; } });
|
|
20
20
|
Object.defineProperty(exports, "VibeIQAppType", { enumerable: true, get: function () { return app_context_1.VibeIQAppType; } });
|
|
21
|
+
__exportStar(require("./document-generation"), exports);
|
|
21
22
|
__exportStar(require("./boards"), exports);
|
|
22
23
|
__exportStar(require("./plan"), exports);
|
|
23
24
|
__exportStar(require("./showcase"), exports);
|
package/package.json
CHANGED