@codenotch/codenotch.react 1.0.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +145 -0
  2. package/dist/components/Auml.d.ts +46 -0
  3. package/dist/components/Auml.d.ts.map +1 -0
  4. package/dist/components/Auml.js +208 -0
  5. package/dist/components/CodeEditor.d.ts +39 -0
  6. package/dist/components/CodeEditor.d.ts.map +1 -0
  7. package/dist/components/CodeEditor.js +174 -0
  8. package/dist/core/ProcessUtils.d.ts +10 -0
  9. package/dist/core/ProcessUtils.d.ts.map +1 -0
  10. package/dist/core/ProcessUtils.js +65 -0
  11. package/dist/core/SignalR.d.ts +30 -0
  12. package/dist/core/SignalR.d.ts.map +1 -0
  13. package/dist/core/SignalR.js +245 -0
  14. package/dist/index.d.ts +60 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +370 -0
  17. package/dist/models/AppManifestModels.d.ts +46 -0
  18. package/dist/models/AppManifestModels.d.ts.map +1 -0
  19. package/dist/models/AppManifestModels.js +2 -0
  20. package/dist/models/Codenotch.d.ts +256 -0
  21. package/dist/models/Codenotch.d.ts.map +1 -0
  22. package/dist/models/Codenotch.js +2 -0
  23. package/dist/models/Misc.d.ts +28 -0
  24. package/dist/models/Misc.d.ts.map +1 -0
  25. package/dist/models/Misc.js +2 -0
  26. package/dist/models/ProjectManifestModels.d.ts +126 -0
  27. package/dist/models/ProjectManifestModels.d.ts.map +1 -0
  28. package/dist/models/ProjectManifestModels.js +158 -0
  29. package/dist/utils/I18nUtils.d.ts +7 -0
  30. package/dist/utils/I18nUtils.d.ts.map +1 -0
  31. package/dist/utils/I18nUtils.js +37 -0
  32. package/package.json +44 -0
  33. package/src/components/CodeEditor.tsx +203 -0
  34. package/src/core/ProcessUtils.ts +86 -0
  35. package/src/core/SignalR.ts +375 -0
  36. package/src/index.ts +387 -0
  37. package/src/models/AppManifestModels.ts +54 -0
  38. package/src/models/Codenotch.ts +285 -0
  39. package/src/models/Misc.ts +32 -0
package/dist/index.js ADDED
@@ -0,0 +1,370 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.CodeEditor = exports.env = void 0;
21
+ exports.useCodenotch = useCodenotch;
22
+ exports.init = init;
23
+ const react_dom_1 = __importDefault(require("react-dom"));
24
+ const SignalR_1 = require("./core/SignalR");
25
+ const ProcessUtils_1 = __importDefault(require("./core/ProcessUtils"));
26
+ const uuid_1 = require("uuid");
27
+ const CodeEditor_1 = __importDefault(require("./components/CodeEditor"));
28
+ exports.CodeEditor = CodeEditor_1.default;
29
+ var signalR = undefined;
30
+ /**
31
+ * The Codenotch runtime environment, populated by {@link init}.
32
+ * Prefer reading it through `useCodenotch().env`.
33
+ */
34
+ const env = {};
35
+ exports.env = env;
36
+ const MISSING_CLUSTER_URL_ERROR = "Codenotch cluster URL is not defined. Please set it in the Codenotch configuration.";
37
+ const MISSING_SERVICE_NAME_ERROR = "Codenotch service name is not defined. Please set it in the Codenotch configuration.";
38
+ const MISSING_TENANT_NAME_ERROR = "Codenotch tenant name is not defined. Please set it in the Codenotch configuration.";
39
+ /**
40
+ * Initialize the Codenotch environment from the given key-value pairs.
41
+ *
42
+ * This is normally called once, by the page hosting the application, with the
43
+ * environment variables injected by the Codenotch runtime (URL parameters or
44
+ * any other source). It must be called before `useCodenotch()` is used.
45
+ *
46
+ * Recognized key formats:
47
+ * - `i18n.<key>.<language>` — a translation, stored in `env.i18n[language][key]`.
48
+ * The first language found becomes the current language if none is set.
49
+ * - `GLOBAL.<name>` — JSON value assigned to `window[name]` (or `globalThis`).
50
+ * - `appManifest` / `projectManifest` — parsed as JSON into the environment.
51
+ * - anything else — copied as-is onto {@link env}.
52
+ *
53
+ * The UI theme is resolved from the `_theme` URL parameter, or from
54
+ * `prefers-color-scheme` as a fallback.
55
+ *
56
+ * @param envVariables An object containing the Codenotch environment variables as key-value pairs.
57
+ * @example
58
+ * import { init } from 'codenotch-react';
59
+ * init({
60
+ * clusterUrl: 'https://cluster.example.com',
61
+ * serviceName: 'myproject',
62
+ * tenantName: 'acme',
63
+ * 'i18n.welcome.en': 'Welcome',
64
+ * 'i18n.welcome.fr': 'Bienvenue'
65
+ * });
66
+ */
67
+ function init(envVariables) {
68
+ // Ensure envVariables is an object
69
+ if (typeof envVariables === 'object' && envVariables !== null) {
70
+ let i18nLanguages = new Set();
71
+ Object.keys(envVariables).forEach((key) => {
72
+ try {
73
+ if (key.startsWith('GLOBAL.')) {
74
+ // Global variable, we set it directly on the window object
75
+ let globalKey = key.substring('GLOBAL.'.length);
76
+ let globalObject = typeof window !== 'undefined' ? window : globalThis;
77
+ globalObject[globalKey] = JSON.parse(envVariables[key]);
78
+ console.log(`Codenotch global variable ${globalKey} set!`);
79
+ return;
80
+ }
81
+ else if (key.startsWith("i18n.")) {
82
+ // Special case
83
+ let parts = key.split("."); // i18n.someKey.fr
84
+ let language = parts[parts.length - 1]; // fr
85
+ let keyName = parts.slice(1, parts.length - 1).join("."); // someKey
86
+ i18nLanguages.add(language);
87
+ let value = `${envVariables[key]}`.trim();
88
+ if (value.startsWith('"') && value.endsWith('"')) {
89
+ // Parse like json
90
+ value = JSON.parse(value);
91
+ }
92
+ env.i18n = env.i18n ?? {};
93
+ env.i18n[language] = env.i18n[language] ?? {};
94
+ env.i18n[language][keyName] = value;
95
+ }
96
+ else {
97
+ env[key] = envVariables[key];
98
+ if (['appManifest', 'projectManifest'].includes(key)) {
99
+ // Must be Json
100
+ try {
101
+ env[key] = JSON.parse(envVariables[key]);
102
+ }
103
+ catch (error) {
104
+ console.warn(`Codenotch environment variable ${key} is not a valid JSON string. Using raw value.`);
105
+ }
106
+ }
107
+ console.log(`Codenotch environment variable ${key} set to ${env[key]}`);
108
+ }
109
+ }
110
+ catch (error) {
111
+ console.error(`Error processing Codenotch environment variable ${key}:`, error);
112
+ }
113
+ });
114
+ if (env.language === undefined) {
115
+ // If current language is not defined, we set it to the first language found in i18n
116
+ if (i18nLanguages.size > 0) {
117
+ env.language = Array.from(i18nLanguages)[0];
118
+ console.log(`Codenotch current language set to ${env.language}`);
119
+ }
120
+ }
121
+ }
122
+ // Instantiate SignalR for further use in the API
123
+ if (env.clusterUrl && env.serviceName) {
124
+ signalR = new SignalR_1.SignalR(env.clusterUrl, env.serviceName, false, env.accessToken);
125
+ }
126
+ // Get theme like AEC does
127
+ try {
128
+ let urlParams = Object.fromEntries(new URLSearchParams(window.location.search).entries());
129
+ if (urlParams["_theme"]) {
130
+ let theme = urlParams["_theme"].toLowerCase();
131
+ if (theme === "light" || theme === "dark") {
132
+ env.theme = theme;
133
+ }
134
+ }
135
+ else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
136
+ env.theme = 'dark';
137
+ }
138
+ else {
139
+ env.theme = 'light';
140
+ }
141
+ }
142
+ catch {
143
+ }
144
+ }
145
+ /**
146
+ * Return the Codenotch client API bound to the current environment.
147
+ *
148
+ * Despite its name this is NOT a React hook — it is a plain function with no
149
+ * hook rules attached: it can be called anywhere (components, handlers, plain
150
+ * modules). `init()` must have been called first, which the Codenotch runtime
151
+ * does automatically when serving the application.
152
+ *
153
+ * @returns The Codenotch API: BPMN processes, SioQL queries, i18n, signals, theme…
154
+ * @example
155
+ * import { useCodenotch } from 'codenotch-react';
156
+ *
157
+ * const MyApp: React.FC = () => {
158
+ * const cn = useCodenotch();
159
+ * return <h1>{cn.i18n('welcome')}</h1>;
160
+ * };
161
+ */
162
+ function useCodenotch() {
163
+ return {
164
+ env: env,
165
+ uuid: () => (0, uuid_1.v4)(),
166
+ getProjectFileUrl: (relativePath) => {
167
+ if (env.clusterUrl === undefined)
168
+ throw new Error(MISSING_CLUSTER_URL_ERROR);
169
+ if (env.serviceName === undefined)
170
+ throw new Error(MISSING_SERVICE_NAME_ERROR);
171
+ relativePath = relativePath.replace(/\\/g, "/");
172
+ if (relativePath.startsWith("/"))
173
+ relativePath = relativePath.substring(1);
174
+ let url = `${env.clusterUrl}/${env.serviceName}/project/file?name=""&path=${encodeURIComponent(relativePath)}`;
175
+ return url;
176
+ },
177
+ getProjectFile: async (relativePath) => {
178
+ let url = useCodenotch().getProjectFileUrl(relativePath);
179
+ let resp = await fetch(url);
180
+ if (resp.status.toString().startsWith('2') === false) {
181
+ throw new Error(`Failed to fetch file content: ${resp.status} ${resp.statusText}`);
182
+ }
183
+ let content = await resp.text();
184
+ return content;
185
+ },
186
+ requestSioql: async (sioql, verbose) => {
187
+ if (env.clusterUrl === undefined)
188
+ throw new Error(MISSING_CLUSTER_URL_ERROR);
189
+ if (env.serviceName === undefined)
190
+ throw new Error(MISSING_SERVICE_NAME_ERROR);
191
+ const request = {
192
+ method: 'POST',
193
+ mode: 'cors',
194
+ credentials: 'same-origin',
195
+ headers: { 'Content-Type': 'application/json' },
196
+ body: `"${sioql.replace(/\"/g, '\\\"')}"`
197
+ };
198
+ if (`${env.accessToken ?? ''}`.trim() !== "") {
199
+ if (env.tenantName === undefined)
200
+ throw new Error(MISSING_TENANT_NAME_ERROR);
201
+ request.headers = {
202
+ ...request.headers, [`${env.tenantName}AccessToken`]: env.accessToken
203
+ };
204
+ }
205
+ const response = await fetch(`${env.clusterUrl}/${env.serviceName}/sioql${verbose ? "?v=true" : ""}`, request);
206
+ if (!response.ok) {
207
+ const error = await response.text();
208
+ throw new Error(error);
209
+ }
210
+ return await response.json();
211
+ },
212
+ i18n: (key, ...args) => {
213
+ try {
214
+ if (env.i18n === undefined || Object.keys(env.i18n).length === 0) {
215
+ console.warn("Codenotch i18n is not defined. Please set it in the Codenotch configuration.");
216
+ return key;
217
+ }
218
+ let language = env.language ?? "en";
219
+ let isLanguageExists = env.i18n[language] !== undefined;
220
+ if (isLanguageExists === false) {
221
+ let fallbackLanguage = Object.keys(env.i18n)[0];
222
+ console.warn(`Codenotch i18n language ${language} is not defined. Falling back to ${fallbackLanguage}. Please set the correct language in the Codenotch configuration.`);
223
+ language = fallbackLanguage;
224
+ }
225
+ let dico = env.i18n[language];
226
+ let value = dico[key];
227
+ if (typeof value !== "string") {
228
+ console.warn(`Codenotch i18n key ${key} is not defined for language ${language}. Please set it in the Codenotch configuration.`);
229
+ return key;
230
+ }
231
+ args = args ?? [];
232
+ let result = value.replace(/{([\d ]*)}/g, (match, p1) => {
233
+ let argValue = args[p1.trim()];
234
+ // Instead of returning 'undefined', returns an empty string
235
+ return argValue !== undefined ? argValue : "";
236
+ });
237
+ return result;
238
+ }
239
+ catch (error) {
240
+ console.error("Error in i18n function:", error);
241
+ return key;
242
+ }
243
+ },
244
+ startProcess: async (processName, startNodeId, inputs) => {
245
+ if (env.clusterUrl === undefined)
246
+ throw new Error(MISSING_CLUSTER_URL_ERROR);
247
+ if (env.serviceName === undefined)
248
+ throw new Error(MISSING_SERVICE_NAME_ERROR);
249
+ if (env.tenantName === undefined)
250
+ throw new Error(MISSING_TENANT_NAME_ERROR);
251
+ if (signalR === undefined)
252
+ throw new Error("SignalR not available. Cannot start process.");
253
+ return ProcessUtils_1.default.startProcess((processInstanceId, callbacks) => signalR.subscribeToProcessInstance(processInstanceId, callbacks), env.clusterUrl, env.tenantName, env.serviceName, processName, inputs, undefined, startNodeId ?? 'start', env.accessToken);
254
+ },
255
+ getUrlParams: () => {
256
+ let result = {};
257
+ if (typeof window !== 'undefined') {
258
+ const params = new URL(window.location.href).searchParams;
259
+ params.forEach((value, key) => {
260
+ if (result[key] === undefined) {
261
+ result[key] = value;
262
+ }
263
+ });
264
+ }
265
+ return result;
266
+ },
267
+ showDialog: (node) => {
268
+ let dialogId = "codenotch-dialog-" + Math.random().toString(36).substring(2, 9);
269
+ let result = {
270
+ id: dialogId,
271
+ close: () => {
272
+ let dialogElement = document.getElementById(dialogId);
273
+ if (dialogElement) {
274
+ dialogElement.remove();
275
+ }
276
+ }
277
+ };
278
+ // Find "cn-dialog-container" element in the page
279
+ let container = document.getElementById("cn-dialog-container");
280
+ if (container === null) {
281
+ container = document.createElement("div");
282
+ container.id = "cn-dialog-container";
283
+ container.style.zIndex = "9999";
284
+ container.style.position = "fixed";
285
+ container.style.top = "0";
286
+ container.style.left = "0";
287
+ container.style.minWidth = "100vw";
288
+ container.style.minHeight = "100vh";
289
+ container.style.maxWidth = "100vw";
290
+ container.style.maxHeight = "100vh";
291
+ container.style.display = "flex";
292
+ container.style.alignItems = "center";
293
+ container.style.justifyContent = "center";
294
+ container.style.pointerEvents = 'none';
295
+ document.body.appendChild(container);
296
+ }
297
+ let dialogElement = document.createElement('dialog');
298
+ dialogElement.id = dialogId;
299
+ dialogElement.style.zIndex = "9999";
300
+ dialogElement.style.position = "fixed";
301
+ dialogElement.style.top = "0";
302
+ dialogElement.style.left = "0";
303
+ dialogElement.style.minWidth = "100vw";
304
+ dialogElement.style.minHeight = "100vh";
305
+ dialogElement.style.maxWidth = "100vw";
306
+ dialogElement.style.maxHeight = "100vh";
307
+ dialogElement.style.display = "flex";
308
+ dialogElement.style.alignItems = "center";
309
+ dialogElement.style.justifyContent = "center";
310
+ dialogElement.style.pointerEvents = 'all';
311
+ dialogElement.style.background = '#78787822';
312
+ dialogElement.style.backdropFilter = 'blur(2px)';
313
+ container.appendChild(dialogElement);
314
+ react_dom_1.default.render(node, dialogElement, () => {
315
+ dialogElement.showModal();
316
+ });
317
+ return result;
318
+ },
319
+ listenSignal: async (signalId, callback) => {
320
+ if (!signalR) {
321
+ throw new Error("SignalR not available. Cannot listen to signal.");
322
+ }
323
+ let unsubscribeFunc = await signalR.subscribeToSignal(signalId, callback);
324
+ return {
325
+ dispose: () => {
326
+ unsubscribeFunc();
327
+ }
328
+ };
329
+ },
330
+ setTheme: (theme) => {
331
+ if (env.theme === theme)
332
+ return;
333
+ if (env.theme)
334
+ document.documentElement.classList.remove(env.theme);
335
+ env.theme = theme;
336
+ document.documentElement.classList.add(theme);
337
+ },
338
+ setLanguage: (lang) => {
339
+ if (env.language === lang)
340
+ return;
341
+ env.language = lang;
342
+ },
343
+ getLanguages: () => {
344
+ return env.projectManifest?.languages ?? [];
345
+ },
346
+ getLanguage: () => {
347
+ return env.language;
348
+ },
349
+ getTheme: () => {
350
+ return env.theme;
351
+ },
352
+ getProjectManifest: () => {
353
+ if (env.projectManifest === undefined) {
354
+ throw new Error("Project manifest is not defined in Codenotch environment. Please set it in the Codenotch configuration.");
355
+ }
356
+ return env.projectManifest;
357
+ },
358
+ getAppManifest: () => {
359
+ return env.appManifest;
360
+ }
361
+ };
362
+ }
363
+ // Public models. Re-exported from the package root so that the typings
364
+ // generated by the Codenotch IDE (typings/i18n.d.ts and typings/process.d.ts,
365
+ // which augment the 'codenotch-react' module) merge with the real
366
+ // TranslationRegistry / ProcessRegistry declarations.
367
+ __exportStar(require("./models/Codenotch"), exports);
368
+ __exportStar(require("./models/Misc"), exports);
369
+ __exportStar(require("./models/AppManifestModels"), exports);
370
+ __exportStar(require("@codenotch/codenotch.core"), exports);
@@ -0,0 +1,46 @@
1
+ export interface ApplicationManifest {
2
+ pwa?: PWAManifest;
3
+ html?: HTMLManifest;
4
+ auml?: AUMLManifest;
5
+ }
6
+ export interface HTMLManifest {
7
+ title?: string;
8
+ description?: string;
9
+ author?: string;
10
+ keywords?: string;
11
+ charset?: string;
12
+ }
13
+ export interface PWAManifest {
14
+ background_color?: string;
15
+ description?: string;
16
+ dir?: string;
17
+ display?: string;
18
+ icons?: PWAManifestIcon[];
19
+ lang?: string;
20
+ name?: string;
21
+ orientation?: string;
22
+ prefer_related_applications?: boolean;
23
+ related_applications?: PWAManifestRelatedApplications[];
24
+ scope?: string;
25
+ short_name?: string;
26
+ start_url?: string;
27
+ theme_color?: string;
28
+ shortcuts?: string;
29
+ display_override?: string[];
30
+ }
31
+ export interface PWAManifestIcon {
32
+ src?: string;
33
+ sizes?: string;
34
+ type?: string;
35
+ }
36
+ export interface PWAManifestRelatedApplications {
37
+ platform?: string;
38
+ url?: string;
39
+ id?: string;
40
+ }
41
+ export interface AUMLManifest {
42
+ name?: string;
43
+ description?: string;
44
+ logoURL?: string;
45
+ }
46
+ //# sourceMappingURL=AppManifestModels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppManifestModels.d.ts","sourceRoot":"","sources":["../../src/models/AppManifestModels.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,mBAAmB;IAChC,GAAG,CAAC,EAAE,WAAW,CAAC;IAElB,IAAI,CAAC,EAAE,YAAY,CAAC;IAEpB,IAAI,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,eAAe,EAAE,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,oBAAoB,CAAC,EAAE,8BAA8B,EAAE,CAAC;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,8BAA8B;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,256 @@
1
+ import { ProjectManifest } from "@codenotch/codenotch.core";
2
+ import { ICodenotchSignal, IDisposable } from "./Misc";
3
+ import { ApplicationManifest } from "./AppManifestModels";
4
+ /**
5
+ * Runtime environment of a Codenotch application.
6
+ *
7
+ * Populated by `init()` from the environment variables injected by the Codenotch
8
+ * runtime into the hosting page, and exposed read-only through {@link ICodenotchApi.env}.
9
+ */
10
+ export interface ICodenotchEnv {
11
+ /** Name of the current application. */
12
+ appName?: string;
13
+ /** Base URL of the Codenotch cluster hosting the project, e.g. `https://cluster.example.com`. */
14
+ clusterUrl?: string;
15
+ /** Service name of the project (`serviceName` in the project's `manifest.json`). Used to build every server URL. */
16
+ serviceName?: string;
17
+ /** Name of the tenant hosting the project. Required when authenticating with an access token. */
18
+ tenantName?: string;
19
+ /** Access token used to authenticate server calls, sent as the `<tenantName>AccessToken` HTTP header. */
20
+ accessToken?: string;
21
+ /** Base URL of the current application. */
22
+ baseUrl?: string;
23
+ /** Translation dictionaries, keyed by language then by translation key: `i18n[language][key] = text`. */
24
+ i18n?: {
25
+ [language: string]: {
26
+ [key: string]: string;
27
+ };
28
+ };
29
+ /** Current language code (e.g. `"en"`). Defaults to the first language found in {@link i18n}. */
30
+ language?: string;
31
+ /** Current UI theme. Resolved from the `_theme` URL parameter, or `prefers-color-scheme` as a fallback. */
32
+ theme?: 'light' | 'dark';
33
+ /** Manifest of the current application (the `<AppName>.manifest.json` file next to the app). */
34
+ appManifest?: ApplicationManifest;
35
+ /** Manifest of the Codenotch project (the project's `manifest.json` file). */
36
+ projectManifest?: ProjectManifest;
37
+ /** Any additional environment variable passed to `init()`. */
38
+ [key: string]: any;
39
+ }
40
+ /**
41
+ * Registry of the project's BPMN processes, used to type {@link ICodenotchApi.startProcess}.
42
+ *
43
+ * Empty by default: the Codenotch IDE fills it through declaration merging in the
44
+ * auto-generated `typings/process.d.ts` file of each project, with one entry per
45
+ * BPMN process. Each entry maps the process name to its start events (`nodes`,
46
+ * keyed by start node id, valued with the start event's input parameters) and to
47
+ * the `output` of its end event.
48
+ *
49
+ * When the registry has not been augmented (project built without the IDE
50
+ * typings), `startProcess` falls back to plain string names and untyped inputs,
51
+ * so the code still compiles.
52
+ *
53
+ * @example
54
+ * // typings/process.d.ts (auto-generated by the Codenotch IDE)
55
+ * import 'codenotch-react';
56
+ * declare module 'codenotch-react' {
57
+ * interface ProcessRegistry {
58
+ * 'getTodos': {
59
+ * nodes: { 'start': { UserId: string } };
60
+ * output: { todos: any[] };
61
+ * };
62
+ * }
63
+ * }
64
+ */
65
+ export interface ProcessRegistry {
66
+ }
67
+ /**
68
+ * Registry of the project's translation keys, used to type {@link ICodenotchApi.i18n}.
69
+ *
70
+ * Empty by default: the Codenotch IDE fills it through declaration merging in the
71
+ * auto-generated `typings/i18n.d.ts` file of each project, from the project's
72
+ * `.i18n.csv` files. Each entry maps a translation key to the tuple of arguments
73
+ * expected by its `{0}`, `{1}`, … placeholders.
74
+ *
75
+ * When the registry has not been augmented (project built without the IDE
76
+ * typings), `i18n` falls back to plain string keys and untyped arguments,
77
+ * so the code still compiles.
78
+ *
79
+ * @example
80
+ * // typings/i18n.d.ts (auto-generated by the Codenotch IDE)
81
+ * import 'codenotch-react';
82
+ * declare module 'codenotch-react' {
83
+ * interface TranslationRegistry {
84
+ * 'welcome': [];
85
+ * 'greeting': [arg1: any, arg2: any];
86
+ * }
87
+ * }
88
+ */
89
+ export interface TranslationRegistry {
90
+ }
91
+ /** A BPMN process name: a key of {@link ProcessRegistry}, or any string when the registry is empty. */
92
+ export type ProcessName = keyof ProcessRegistry extends never ? string : keyof ProcessRegistry;
93
+ /** The start nodes of process `P`: its `nodes` map from {@link ProcessRegistry}, or an open map when unknown. */
94
+ export type ProcessNodes<P> = P extends keyof ProcessRegistry ? ProcessRegistry[P] extends {
95
+ nodes: infer N;
96
+ } ? N : {
97
+ [nodeId: string]: any;
98
+ } : {
99
+ [nodeId: string]: any;
100
+ };
101
+ /** The end-event output of process `P` from {@link ProcessRegistry}, or `any` when unknown. */
102
+ export type ProcessOutput<P> = P extends keyof ProcessRegistry ? ProcessRegistry[P] extends {
103
+ output: infer O;
104
+ } ? O : any : any;
105
+ /** A translation key: a key of {@link TranslationRegistry}, or any string when the registry is empty. */
106
+ export type TranslationKey = keyof TranslationRegistry extends never ? string : keyof TranslationRegistry;
107
+ /** The placeholder arguments of translation key `K` from {@link TranslationRegistry}, or `any[]` when unknown. */
108
+ export type TranslationArgs<K> = K extends keyof TranslationRegistry ? TranslationRegistry[K] extends any[] ? TranslationRegistry[K] : any[] : any[];
109
+ /**
110
+ * Result of a BPMN process execution started with {@link ICodenotchApi.startProcess}.
111
+ */
112
+ export interface IProcessResult<T = any> {
113
+ /** Unique id of this execution of the process. */
114
+ processInstanceId: string;
115
+ /** Output parameters of the end event reached by the process. */
116
+ output: T;
117
+ /** `true` if the process ended in error; check it before reading {@link output}. */
118
+ isError: boolean;
119
+ /** Error details when {@link isError} is `true`. */
120
+ errorMessage: string;
121
+ }
122
+ /**
123
+ * The Codenotch client API, obtained by calling `useCodenotch()`.
124
+ *
125
+ * It is the bridge between a React app and the Codenotch runtime: it starts
126
+ * server-side BPMN processes, runs SioQL queries, translates i18n keys,
127
+ * listens to real-time signals and manages theme/language.
128
+ *
129
+ * @example
130
+ * import { useCodenotch } from 'codenotch-react';
131
+ *
132
+ * const cn = useCodenotch();
133
+ * const title = cn.i18n('welcome');
134
+ * const result = await cn.startProcess('getTodos', 'start', { UserId: '42' });
135
+ */
136
+ export interface ICodenotchApi {
137
+ /**
138
+ * Start a server-side BPMN process and wait for its completion.
139
+ *
140
+ * @param processName Name of the process — the `.bpmn` file name without extension (e.g. `processes/getTodos.bpmn` → `'getTodos'`).
141
+ * @param startNodeId Id of the start event to trigger (conventionally `'start'`).
142
+ * @param inputs Input parameters declared by that start event.
143
+ * @returns The process result; check `isError` before using `output` (the parameters of the end event reached).
144
+ * @example
145
+ * const result = await cn.startProcess('getTodos', 'start', { UserId: userId });
146
+ * if (!result.isError) {
147
+ * setTodos(result.output.todos);
148
+ * }
149
+ */
150
+ startProcess<P extends ProcessName, N extends keyof ProcessNodes<P>>(processName: P, startNodeId: N, inputs: ProcessNodes<P>[N]): Promise<IProcessResult<ProcessOutput<P>>>;
151
+ /**
152
+ * Translate a key for the current language ({@link ICodenotchEnv.language}).
153
+ *
154
+ * Placeholders `{0}`, `{1}`, … in the translated text are replaced by `args`.
155
+ * Never throws: if the key or the language is missing, a warning is logged
156
+ * and the key itself is returned.
157
+ *
158
+ * @param key Translation key, as defined in the project's `.i18n.csv` files.
159
+ * @param args Values for the `{0}`, `{1}`, … placeholders of the translation.
160
+ * @example
161
+ * cn.i18n('welcome'); // "Bienvenue"
162
+ * cn.i18n('greeting', 'Fabian', 3); // "Bonjour Fabian, 3 messages" (from "Bonjour {0}, {1} messages")
163
+ */
164
+ i18n<K extends TranslationKey>(key: K, ...args: TranslationArgs<K>): string;
165
+ /** Runtime environment (cluster, service, language, theme, i18n dictionaries, manifests…). Populated by `init()`. */
166
+ readonly env: ICodenotchEnv;
167
+ /**
168
+ * Execute a SioQL query (XML, SELECT-only) against the project's SQL tables and return the parsed JSON result.
169
+ *
170
+ * The root element's `xmlns` must be the project's `serviceName`. Results are
171
+ * keyed by the `Ref` attribute of each queried table.
172
+ *
173
+ * @param sioql The SioQL XML query.
174
+ * @param verbose When `true`, asks the server for a verbose response (debugging).
175
+ * @example
176
+ * const data = await cn.requestSioql(`
177
+ * <SioQL xmlns="myproject" PageSize="10" PageIndex="0">
178
+ * <Users Ref="results">
179
+ * <Id />
180
+ * <Email />
181
+ * </Users>
182
+ * </SioQL>`);
183
+ * console.log(data.results); // [{ Id: ..., Email: ... }, ...]
184
+ */
185
+ readonly requestSioql: (sioql: string, verbose?: boolean) => Promise<any>;
186
+ /**
187
+ * Render the given React element in a fullscreen modal `<dialog>` overlay.
188
+ *
189
+ * The dialog is not closed automatically: keep the returned handle and call
190
+ * its `close()` method (typically from a button inside the dialog content).
191
+ *
192
+ * @example
193
+ * const dialog = cn.showDialog(
194
+ * <div className="bg-white p-4 rounded">
195
+ * <p>Are you sure?</p>
196
+ * <button onClick={() => dialog.close()}>Close</button>
197
+ * </div>
198
+ * );
199
+ */
200
+ readonly showDialog: (node: JSX.Element) => ICodenotchDialog;
201
+ /**
202
+ * Fetch the text content of a file of the deployed Codenotch project.
203
+ * @param relativePath Path of the file relative to the project root (e.g. `'readme.md'`).
204
+ */
205
+ readonly getProjectFile: (relativePath: string) => Promise<string | undefined>;
206
+ /**
207
+ * Build the URL serving a file of the deployed Codenotch project
208
+ * (useful as `src` for images or links).
209
+ * @param relativePath Path of the file relative to the project root.
210
+ */
211
+ readonly getProjectFileUrl: (relativePath: string) => string;
212
+ /**
213
+ * Subscribe to a real-time signal emitted by the project's BPMN processes (via SignalR).
214
+ *
215
+ * @param signalId Id of the signal, as declared in the BPMN process.
216
+ * @param callback Called each time the signal is received, with `{ signalId, data }`.
217
+ * @returns A disposable — call `dispose()` to unsubscribe (e.g. in a `useEffect` cleanup).
218
+ * @example
219
+ * useEffect(() => {
220
+ * let sub: IDisposable | undefined;
221
+ * cn.listenSignal('todosChanged', () => refresh()).then(s => sub = s);
222
+ * return () => sub?.dispose();
223
+ * }, []);
224
+ */
225
+ readonly listenSignal: (signalId: string, callback: (data: ICodenotchSignal) => void) => Promise<IDisposable>;
226
+ /** Set the UI theme. Also toggles the `light`/`dark` class on `<html>` (Tailwind `dark:` variants). */
227
+ readonly setTheme: (theme: 'light' | 'dark') => void;
228
+ /** Current UI theme, if resolved. */
229
+ readonly getTheme: () => 'light' | 'dark' | undefined;
230
+ /** Set the current language used by {@link i18n}. Must be one of the project's languages. */
231
+ readonly setLanguage: (lang: string) => void;
232
+ /** Current language code, if any. */
233
+ readonly getLanguage: () => string | undefined;
234
+ /** Languages declared in the project's `manifest.json`. */
235
+ readonly getLanguages: () => string[];
236
+ /** Query-string parameters of the current URL, as a plain object (first value wins for duplicated keys). */
237
+ readonly getUrlParams: () => {
238
+ [key: string]: string;
239
+ };
240
+ /** Generate a random UUID v4. */
241
+ readonly uuid: () => string;
242
+ /** Manifest of the Codenotch project. Throws if not available in the environment. */
243
+ readonly getProjectManifest: () => ProjectManifest;
244
+ /** Manifest of the current application, if any. */
245
+ readonly getAppManifest: () => ApplicationManifest | undefined;
246
+ }
247
+ /**
248
+ * Handle on a dialog opened with {@link ICodenotchApi.showDialog}.
249
+ */
250
+ export interface ICodenotchDialog {
251
+ /** DOM id of the underlying `<dialog>` element. */
252
+ id: string;
253
+ /** Close the dialog and remove it from the DOM. */
254
+ close: () => void;
255
+ }
256
+ //# sourceMappingURL=Codenotch.d.ts.map