@nocobase/plugin-flow-engine 3.0.0-alpha.1 → 3.0.0-alpha.11

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 (53) hide show
  1. package/dist/externalVersion.js +9 -9
  2. package/dist/node_modules/@ant-design/icons-svg/package.json +1 -1
  3. package/dist/node_modules/acorn/package.json +1 -1
  4. package/dist/node_modules/acorn-jsx/package.json +1 -1
  5. package/dist/node_modules/acorn-walk/package.json +1 -1
  6. package/dist/node_modules/ses/package.json +1 -1
  7. package/dist/node_modules/zod/package.json +1 -1
  8. package/dist/server/flow-surfaces/builder.js +5 -0
  9. package/dist/server/flow-surfaces/catalog.js +27 -8
  10. package/dist/server/flow-surfaces/configure-options.js +17 -1
  11. package/dist/server/flow-surfaces/field-binding-registry.js +9 -8
  12. package/dist/server/flow-surfaces/navigation-targets.js +21 -40
  13. package/dist/server/flow-surfaces/service-utils.d.ts +1 -0
  14. package/dist/server/flow-surfaces/service-utils.js +17 -0
  15. package/dist/server/flow-surfaces/service.js +9 -0
  16. package/dist/server/index.d.ts +2 -0
  17. package/dist/server/index.js +7 -0
  18. package/dist/server/plugin.d.ts +13 -0
  19. package/dist/server/plugin.js +90 -3
  20. package/dist/server/repository.d.ts +12 -0
  21. package/dist/server/repository.js +39 -2
  22. package/dist/server/template/context-keys.d.ts +14 -0
  23. package/dist/server/template/context-keys.js +86 -0
  24. package/dist/server/template/contexts.d.ts +5 -8
  25. package/dist/server/template/contexts.js +43 -51
  26. package/dist/server/template/resolver.d.ts +5 -13
  27. package/dist/server/template/resolver.js +188 -257
  28. package/dist/server/template/variable-expression.d.ts +72 -0
  29. package/dist/server/template/variable-expression.js +597 -0
  30. package/dist/server/variables/allow-list.d.ts +49 -0
  31. package/dist/server/variables/allow-list.js +492 -0
  32. package/dist/server/variables/form-item-record-slot-resolvers.d.ts +10 -0
  33. package/dist/server/variables/form-item-record-slot-resolvers.js +280 -0
  34. package/dist/server/variables/record-bindings.d.ts +42 -0
  35. package/dist/server/variables/record-bindings.js +196 -0
  36. package/dist/server/variables/record-projection.d.ts +10 -0
  37. package/dist/server/variables/record-projection.js +140 -0
  38. package/dist/server/variables/record-slot-policy.d.ts +23 -0
  39. package/dist/server/variables/record-slot-policy.js +100 -0
  40. package/dist/server/variables/record-slot-resolvers.d.ts +46 -0
  41. package/dist/server/variables/record-slot-resolvers.js +115 -0
  42. package/dist/server/variables/records.d.ts +49 -2
  43. package/dist/server/variables/records.js +309 -18
  44. package/dist/server/variables/registry.d.ts +33 -10
  45. package/dist/server/variables/registry.js +197 -362
  46. package/dist/server/variables/resolve.d.ts +20 -2
  47. package/dist/server/variables/resolve.js +85 -13
  48. package/dist/server/variables/runjs-variable-dependencies.d.ts +23 -0
  49. package/dist/server/variables/runjs-variable-dependencies.js +407 -0
  50. package/dist/server/variables/selects.js +6 -3
  51. package/dist/server/variables/utils.d.ts +3 -6
  52. package/dist/server/variables/utils.js +50 -111
  53. package/package.json +2 -2
@@ -0,0 +1,23 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ import type { Application } from '@nocobase/server';
10
+ import type { AnalyzedTemplate } from '../template/variable-expression';
11
+ import { type RecordSlotResolved, type RecordSlotResolverInput, type RecordSlotResolverRegistration } from './record-slot-resolvers';
12
+ export type RecordSlotPolicy = RecordSlotResolved;
13
+ export type RecordSlotPolicies = ReadonlyMap<string, RecordSlotPolicy>;
14
+ export type FlowModelVariableContract = Readonly<{
15
+ allowedPaths: ReadonlySet<string>;
16
+ recordSlots: RecordSlotPolicies;
17
+ }>;
18
+ export type CompileRecordSlotPoliciesOptions = Omit<RecordSlotResolverInput, 'path'> & Readonly<{
19
+ app: Application;
20
+ }>;
21
+ export declare function createBuiltInRecordSlotResolvers(): readonly RecordSlotResolverRegistration[];
22
+ export declare function compileRecordSlotPolicies(analysis: Pick<AnalyzedTemplate, 'paths'>, options: CompileRecordSlotPoliciesOptions): Promise<RecordSlotPolicies>;
23
+ export declare function createFlowModelVariableContract(analysis: AnalyzedTemplate, options: CompileRecordSlotPoliciesOptions): Promise<FlowModelVariableContract>;
@@ -0,0 +1,100 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var record_slot_policy_exports = {};
28
+ __export(record_slot_policy_exports, {
29
+ compileRecordSlotPolicies: () => compileRecordSlotPolicies,
30
+ createBuiltInRecordSlotResolvers: () => createBuiltInRecordSlotResolvers,
31
+ createFlowModelVariableContract: () => createFlowModelVariableContract
32
+ });
33
+ module.exports = __toCommonJS(record_slot_policy_exports);
34
+ var import_record_slot_resolvers = require("./record-slot-resolvers");
35
+ function resolved(slot) {
36
+ return { status: "resolved", slot };
37
+ }
38
+ function createBuiltInRecordSlotResolvers() {
39
+ return [
40
+ ...["record", "responseRecord", "clickedRowRecord"].map(
41
+ (varName) => ({
42
+ owner: "@nocobase/plugin-flow-engine",
43
+ id: `direct:${varName}`,
44
+ match: (path) => path.varName === varName,
45
+ resolve: () => resolved([])
46
+ })
47
+ ),
48
+ {
49
+ owner: "@nocobase/plugin-flow-engine",
50
+ id: "view:record",
51
+ match: (path) => path.varName === "view" && path.runtimeSegments[0] === "record",
52
+ resolve: () => resolved(["record"])
53
+ },
54
+ {
55
+ owner: "@nocobase/plugin-flow-engine",
56
+ id: "popup:record",
57
+ match: (path) => {
58
+ if (path.varName !== "popup") return false;
59
+ let index = 0;
60
+ while (path.runtimeSegments[index] === "parent") index += 1;
61
+ return path.runtimeSegments[index] === "record" || path.runtimeSegments[index] === "sourceRecord";
62
+ },
63
+ resolve: ({ path }) => {
64
+ let index = 0;
65
+ while (path.runtimeSegments[index] === "parent") index += 1;
66
+ return resolved(path.runtimeSegments.slice(0, index + 1));
67
+ }
68
+ }
69
+ ];
70
+ }
71
+ function samePolicy(left, right) {
72
+ return left.slot.length === right.slot.length && left.slot.every((segment, index) => segment === right.slot[index]);
73
+ }
74
+ async function compileRecordSlotPolicies(analysis, options) {
75
+ const registry = (0, import_record_slot_resolvers.getRecordSlotResolverRegistry)(options.app);
76
+ const occurrences = /* @__PURE__ */ new Map();
77
+ for (const path of analysis.paths) {
78
+ const policies = occurrences.get(path.canonicalKey) || [];
79
+ policies.push(await registry.resolve({ ...options, path }));
80
+ occurrences.set(path.canonicalKey, policies);
81
+ }
82
+ const result = /* @__PURE__ */ new Map();
83
+ for (const [canonicalKey, policies] of occurrences) {
84
+ const first = policies[0];
85
+ if (first && policies.every((policy) => !!policy && samePolicy(policy, first))) result.set(canonicalKey, first);
86
+ }
87
+ return result;
88
+ }
89
+ async function createFlowModelVariableContract(analysis, options) {
90
+ return Object.freeze({
91
+ allowedPaths: new Set(analysis.paths.map((path) => path.canonicalKey)),
92
+ recordSlots: await compileRecordSlotPolicies(analysis, options)
93
+ });
94
+ }
95
+ // Annotate the CommonJS export names for ESM import in node:
96
+ 0 && (module.exports = {
97
+ compileRecordSlotPolicies,
98
+ createBuiltInRecordSlotResolvers,
99
+ createFlowModelVariableContract
100
+ });
@@ -0,0 +1,46 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ import type { ResourcerContext } from '@nocobase/resourcer';
10
+ import type { Application } from '@nocobase/server';
11
+ import type { PathSegment, VariablePathRef } from '../template/variable-expression';
12
+ type MaybePromise<T> = T | Promise<T>;
13
+ export type RecordSlotResolved = Readonly<{
14
+ status: 'resolved';
15
+ slot: readonly PathSegment[];
16
+ }>;
17
+ export type RecordSlotResolverResult = RecordSlotResolved | Readonly<{
18
+ status: 'deny' | 'abstain';
19
+ }>;
20
+ export type RecordSlotResolverInput = Readonly<{
21
+ path: VariablePathRef;
22
+ currentNode?: unknown;
23
+ loadAncestors?: () => Promise<readonly unknown[]>;
24
+ ctx?: ResourcerContext;
25
+ getCollection?: (dataSourceKey: string, collection: string) => unknown;
26
+ }>;
27
+ export type RecordSlotResolverRegistration = Readonly<{
28
+ owner: string;
29
+ id: string;
30
+ needsAncestors?: boolean;
31
+ match: (path: VariablePathRef) => boolean;
32
+ resolve: (input: RecordSlotResolverInput) => MaybePromise<RecordSlotResolverResult>;
33
+ }>;
34
+ export declare class RecordSlotResolverRegistry {
35
+ private readonly registrations;
36
+ has(owner: string, id: string): boolean;
37
+ register(registration: RecordSlotResolverRegistration): () => void;
38
+ resolve(input: RecordSlotResolverInput): Promise<RecordSlotResolved | undefined>;
39
+ }
40
+ export declare function getRecordSlotResolverRegistry(app: Application): RecordSlotResolverRegistry;
41
+ export declare function createNestedRecordSlotResolver(registration: Readonly<{
42
+ owner: string;
43
+ id: string;
44
+ varName: string;
45
+ }>): RecordSlotResolverRegistration;
46
+ export {};
@@ -0,0 +1,115 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var record_slot_resolvers_exports = {};
28
+ __export(record_slot_resolvers_exports, {
29
+ RecordSlotResolverRegistry: () => RecordSlotResolverRegistry,
30
+ createNestedRecordSlotResolver: () => createNestedRecordSlotResolver,
31
+ getRecordSlotResolverRegistry: () => getRecordSlotResolverRegistry
32
+ });
33
+ module.exports = __toCommonJS(record_slot_resolvers_exports);
34
+ function normalizeResolved(result) {
35
+ if (result.status !== "resolved" || !Array.isArray(result.slot)) return void 0;
36
+ if (result.slot.some(
37
+ (segment) => typeof segment !== "string" && typeof segment !== "number" || typeof segment === "string" && segment.includes("*") || typeof segment === "number" && (!Number.isSafeInteger(segment) || segment < 0)
38
+ )) {
39
+ return void 0;
40
+ }
41
+ return Object.freeze({ status: "resolved", slot: Object.freeze([...result.slot]) });
42
+ }
43
+ function sameResolved(left, right) {
44
+ return left.slot.length === right.slot.length && left.slot.every((segment, index) => segment === right.slot[index]);
45
+ }
46
+ class RecordSlotResolverRegistry {
47
+ registrations = /* @__PURE__ */ new Map();
48
+ has(owner, id) {
49
+ var _a;
50
+ return ((_a = this.registrations.get(owner.trim())) == null ? void 0 : _a.has(id.trim())) === true;
51
+ }
52
+ register(registration) {
53
+ const owner = registration.owner.trim();
54
+ const id = registration.id.trim();
55
+ if (!owner || !id) throw new TypeError("Record Slot resolver owner and id are required");
56
+ const entry = Object.freeze({ ...registration, owner, id });
57
+ let owned = this.registrations.get(owner);
58
+ if (!owned) {
59
+ owned = /* @__PURE__ */ new Map();
60
+ this.registrations.set(owner, owned);
61
+ }
62
+ owned.set(id, entry);
63
+ return () => {
64
+ const current = this.registrations.get(owner);
65
+ if ((current == null ? void 0 : current.get(id)) !== entry) return;
66
+ current.delete(id);
67
+ if (!current.size) this.registrations.delete(owner);
68
+ };
69
+ }
70
+ async resolve(input) {
71
+ const resolutions = [];
72
+ for (const owned of this.registrations.values()) {
73
+ for (const registration of owned.values()) {
74
+ try {
75
+ if (!registration.match(input.path)) continue;
76
+ const result = await registration.resolve(
77
+ registration.needsAncestors ? input : { ...input, loadAncestors: void 0 }
78
+ );
79
+ if (result.status === "deny") return void 0;
80
+ if (result.status === "abstain") continue;
81
+ const normalized = normalizeResolved(result);
82
+ if (!normalized) return void 0;
83
+ resolutions.push(normalized);
84
+ } catch (_) {
85
+ return void 0;
86
+ }
87
+ }
88
+ }
89
+ const first = resolutions[0];
90
+ return first && resolutions.every((resolution) => sameResolved(resolution, first)) ? first : void 0;
91
+ }
92
+ }
93
+ const registries = /* @__PURE__ */ new WeakMap();
94
+ function getRecordSlotResolverRegistry(app) {
95
+ let registry = registries.get(app);
96
+ if (!registry) {
97
+ registry = new RecordSlotResolverRegistry();
98
+ registries.set(app, registry);
99
+ }
100
+ return registry;
101
+ }
102
+ function createNestedRecordSlotResolver(registration) {
103
+ return Object.freeze({
104
+ owner: registration.owner,
105
+ id: registration.id,
106
+ match: (path) => path.varName === registration.varName && path.runtimeSegments[0] === "record",
107
+ resolve: () => ({ status: "resolved", slot: ["record"] })
108
+ });
109
+ }
110
+ // Annotate the CommonJS export names for ESM import in node:
111
+ 0 && (module.exports = {
112
+ RecordSlotResolverRegistry,
113
+ createNestedRecordSlotResolver,
114
+ getRecordSlotResolverRegistry
115
+ });
@@ -6,7 +6,54 @@
6
6
  * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
+ import type { Collection, RelationRepository, Repository } from '@nocobase/database';
10
+ import type { IRepository } from '@nocobase/data-source-manager';
11
+ import type { ResourcerContext } from '@nocobase/resourcer';
9
12
  type FilterTargetKey = string | string[] | undefined;
13
+ type RecordRepository = IRepository | Repository | RelationRepository;
14
+ export type RecordParams = {
15
+ associationName?: string;
16
+ collection: string;
17
+ dataSourceKey?: string;
18
+ filterByTk: unknown;
19
+ sourceId?: unknown;
20
+ fields?: string[];
21
+ appends?: string[];
22
+ };
23
+ export type RecordTarget = {
24
+ repository: RecordRepository;
25
+ dataSourceKey: string;
26
+ collection: Collection;
27
+ collectionName: string;
28
+ filterTargetKey: FilterTargetKey;
29
+ pkAttr?: string;
30
+ pkIsValid: boolean;
31
+ rawAttributes?: Record<string, unknown>;
32
+ cacheIdentity: Readonly<{
33
+ ds: string;
34
+ c: string;
35
+ assoc?: string;
36
+ sid?: unknown;
37
+ }>;
38
+ };
39
+ export type RecordQuery = RecordTarget & {
40
+ filterByTk: unknown;
41
+ fields?: string[];
42
+ appends?: string[];
43
+ preferFullRecord: boolean;
44
+ strictSelects: boolean;
45
+ cacheKey: string;
46
+ };
47
+ export declare function isRecordParams(value: unknown): value is RecordParams;
48
+ export declare function resolveRecordTarget(koaCtx: ResourcerContext, params: RecordParams): RecordTarget | undefined;
49
+ export declare function prepareRecordQuery(koaCtx: ResourcerContext, target: RecordTarget, filterByTk: unknown, fields?: string[], appends?: string[], strictSelects?: boolean, preferFullRecord?: boolean): RecordQuery;
50
+ export declare function getRecordRequestCache(koaCtx: ResourcerContext): Map<string, unknown>;
51
+ export declare function setRecordRequestCache(cache: Map<string, unknown>, query: RecordQuery, value: unknown): Map<string, unknown>;
52
+ export declare function findRecordRequestCacheValue(cache: Map<string, unknown>, query: RecordQuery): {
53
+ hit: boolean;
54
+ value: unknown;
55
+ };
56
+ export declare function fetchRecordWithRequestCache(koaCtx: ResourcerContext, params: RecordParams, fields?: string[], appends?: string[], strictSelects?: boolean, preferFullRecord?: boolean): Promise<unknown>;
10
57
  /**
11
58
  * 为了:
12
59
  * - 关联加载/缓存:fields 模式下确保包含主键
@@ -26,7 +73,7 @@ export declare function mergeFieldsWithExtras(fields?: string[], extras?: string
26
73
  * - 单值:返回 object | undefined
27
74
  * - 数组:返回 array(空数组时返回 [],不会退化为无条件查询)
28
75
  */
29
- export declare function fetchRecordOrRecordsJson(repo: any, params: {
76
+ export declare function fetchRecordOrRecordsJson(repo: RecordRepository, params: {
30
77
  filterByTk: unknown;
31
78
  preferFullRecord?: boolean;
32
79
  fields?: string[];
@@ -34,5 +81,5 @@ export declare function fetchRecordOrRecordsJson(repo: any, params: {
34
81
  filterTargetKey?: FilterTargetKey;
35
82
  pkAttr?: string;
36
83
  pkIsValid?: boolean;
37
- }): Promise<unknown>;
84
+ }, context: ResourcerContext): Promise<unknown>;
38
85
  export {};