@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;
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrail/extensions-sdk",
3
- "version": "1.0.34",
3
+ "version": "1.0.35",
4
4
  "description": "Client library for interfacing with VibeIQ's services and apps from an extension.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",