@marianmeres/collection-types 1.15.0 → 1.17.0

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/example.d.ts CHANGED
@@ -31,11 +31,13 @@ export interface ExampleDataBar extends ExampleDataDefault {
31
31
  }
32
32
  /** Union of all example data types */
33
33
  export type ExampleData = ExampleDataDefault | ExampleDataFoo | ExampleDataBar;
34
- /** Comment model data for testing strong relations */
34
+ /** Comment model data for testing strong and linked relations */
35
35
  export interface CommentData {
36
36
  body: string;
37
37
  author_name?: string;
38
38
  created_at?: string;
39
+ /** Links to examples with matching slug (for linked relation testing) */
40
+ example_slug?: string;
39
41
  /** Index signature for Model<T> compatibility */
40
42
  [key: string]: unknown;
41
43
  }
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Linked Configuration Types
3
+ *
4
+ * Types for the linked models feature - a configuration-driven system
5
+ * for displaying models that are implicitly linked via metadata matching
6
+ * rather than explicit relation records.
7
+ *
8
+ * Used by:
9
+ * - Joy admin (frontend configuration consumption)
10
+ * - Backend (configuration storage and bootstrap)
11
+ *
12
+ * @module linked
13
+ */
14
+ import type { MaybeLocalized } from "./utils.js";
15
+ /**
16
+ * Comparison operators supported for matching conditions.
17
+ * Maps to @marianmeres/condition-builder OPERATOR enum.
18
+ */
19
+ export type LinkedOperator = "eq" | "neq" | "lt" | "lte" | "gt" | "gte" | "like" | "ilike" | "in" | "nin" | "?" | "descendant";
20
+ /**
21
+ * Value source: where to get the value for matching.
22
+ * - "literal": use the value as-is
23
+ * - "model_field": extract from current model's data using dot-path
24
+ */
25
+ export type LinkedValueSource = "literal" | "model_field";
26
+ /**
27
+ * A single matching condition for linked models.
28
+ *
29
+ * @example
30
+ * // Match models where data.custom.sku equals source model's sku field
31
+ * {
32
+ * target_field: "data.custom.sku",
33
+ * operator: "eq",
34
+ * value_source: "model_field",
35
+ * value: "sku"
36
+ * }
37
+ */
38
+ export interface LinkedCondition {
39
+ /**
40
+ * The field path on the target model to match against.
41
+ * Examples: "type", "data.custom.sku", "folder", "tags"
42
+ */
43
+ target_field: string;
44
+ /** Comparison operator */
45
+ operator: LinkedOperator;
46
+ /** How to interpret the value */
47
+ value_source: LinkedValueSource;
48
+ /**
49
+ * The value to match:
50
+ * - If value_source is "literal": the actual value to compare
51
+ * - If value_source is "model_field": dot-path to source model field
52
+ */
53
+ value: string | number | boolean;
54
+ }
55
+ /**
56
+ * Upload configuration for linked models.
57
+ * When present, enables file upload capability.
58
+ */
59
+ export interface LinkedUploadConfig {
60
+ /**
61
+ * Auto-populate custom fields from parent model during upload.
62
+ * Key: target field path (e.g., "custom.sku")
63
+ * Value: source model field path (e.g., "sku")
64
+ */
65
+ auto_fill_custom: Record<string, string>;
66
+ /**
67
+ * Target type to use for uploads.
68
+ * @default target_query.type
69
+ */
70
+ type?: string;
71
+ /**
72
+ * Accepted file types (MIME patterns).
73
+ * @default "image/*"
74
+ */
75
+ accept?: string;
76
+ /**
77
+ * Maximum number of files (-1 for unlimited).
78
+ * @default -1
79
+ */
80
+ cardinality?: number;
81
+ }
82
+ /**
83
+ * Unlink configuration for linked models.
84
+ * Defines how to remove the link between target and source model.
85
+ */
86
+ export interface LinkedUnlinkConfig {
87
+ /**
88
+ * Which custom field to clear when unlinking.
89
+ * Should match a key from upload.auto_fill_custom.
90
+ */
91
+ field: string;
92
+ /**
93
+ * Require confirmation before unlinking.
94
+ * @default true
95
+ */
96
+ confirm?: boolean;
97
+ }
98
+ /**
99
+ * Target query configuration within a rule.
100
+ */
101
+ export interface LinkedQueryConfig {
102
+ /**
103
+ * Target domain to query.
104
+ * @default "asset"
105
+ */
106
+ domain?: string;
107
+ /**
108
+ * Target entity/collection to query.
109
+ * @default "asset"
110
+ */
111
+ entity?: string;
112
+ /**
113
+ * Target type filter (e.g., "product-image").
114
+ * If specified, adds `type:eq:<value>` to conditions.
115
+ */
116
+ type?: string;
117
+ /**
118
+ * Conditions to build the target query.
119
+ * Combined with AND logic.
120
+ */
121
+ conditions: LinkedCondition[];
122
+ /**
123
+ * Always include these base conditions.
124
+ * @default [{ target_field: "is_enabled", operator: "eq", value_source: "literal", value: true }]
125
+ */
126
+ base_conditions?: LinkedCondition[];
127
+ }
128
+ /**
129
+ * Match context configuration.
130
+ * Defines when a rule should be applied.
131
+ */
132
+ export interface LinkedMatchConfig {
133
+ /** Domain to match (e.g., "product") */
134
+ domain?: string;
135
+ /** Entity/collection to match (e.g., "product", "category") */
136
+ entity?: string;
137
+ /** Type to match (e.g., "default", "variant") */
138
+ type?: string;
139
+ }
140
+ /**
141
+ * Display options for rendering linked items.
142
+ * Used both as global defaults and per-rule overrides.
143
+ */
144
+ export interface LinkedDisplayOptions {
145
+ /** Maximum number of items to show (default: 20) */
146
+ limit?: number;
147
+ /** Grid column count (default: 4) */
148
+ columns?: number;
149
+ /** Whether to show filenames below items (default: true) */
150
+ show_filename?: boolean;
151
+ /** Thumbnail variant size (default: "sm") */
152
+ thumbnail_variant?: "xs" | "sm" | "lg";
153
+ }
154
+ /**
155
+ * Configuration for the "Referenced By" feature.
156
+ * Shows which other models reference the current model via reverse lookup.
157
+ */
158
+ export interface ReverseLinkedConfig {
159
+ /** Collections that display reverse linked lookups UI */
160
+ enabled_collections: Array<{
161
+ domain: string;
162
+ entity: string;
163
+ type?: string;
164
+ }>;
165
+ }
166
+ /**
167
+ * A single linked rule configuration.
168
+ * Defines when and how to show/manage linked models for a specific model context.
169
+ */
170
+ export interface LinkedRule {
171
+ /** Unique identifier for this rule */
172
+ id: string;
173
+ /** Human-readable label (supports localization) */
174
+ label: MaybeLocalized<string>;
175
+ /** Optional description */
176
+ description?: MaybeLocalized<string>;
177
+ /** When to apply this rule (AND logic, omitted = any) */
178
+ match: LinkedMatchConfig;
179
+ /** Target query configuration */
180
+ target_query: LinkedQueryConfig;
181
+ /** Upload configuration - enables CRUD mode when present */
182
+ upload?: LinkedUploadConfig;
183
+ /** Unlink configuration - defines how to remove links */
184
+ unlink?: LinkedUnlinkConfig;
185
+ /**
186
+ * Whether this rule is enabled.
187
+ * @default true
188
+ */
189
+ enabled?: boolean;
190
+ /**
191
+ * Sort order when multiple rules match (lower = earlier).
192
+ * @default 0
193
+ */
194
+ order?: number;
195
+ /** Display options for rendering (optional, falls back to config defaults) */
196
+ display?: LinkedDisplayOptions;
197
+ }
198
+ /**
199
+ * The complete linked configuration structure.
200
+ * Stored as the value of the `__joy_linked__` config record.
201
+ */
202
+ export interface LinkedConfig {
203
+ /**
204
+ * Schema version for future migrations.
205
+ */
206
+ version: number;
207
+ /**
208
+ * Array of linked rules.
209
+ */
210
+ rules: LinkedRule[];
211
+ /** Global default display options (individual rules can override) */
212
+ defaults?: LinkedDisplayOptions;
213
+ /** Configuration for reverse lookups ("referenced by" feature) */
214
+ reverse?: ReverseLinkedConfig;
215
+ }
@@ -1,14 +1,14 @@
1
1
  /**
2
- * Linked Assets Configuration Types
2
+ * Linked Configuration Types
3
3
  *
4
- * Types for the linked assets feature - a configuration-driven system
5
- * for displaying assets that are implicitly linked via metadata matching
4
+ * Types for the linked models feature - a configuration-driven system
5
+ * for displaying models that are implicitly linked via metadata matching
6
6
  * rather than explicit relation records.
7
7
  *
8
8
  * Used by:
9
9
  * - Joy admin (frontend configuration consumption)
10
10
  * - Backend (configuration storage and bootstrap)
11
11
  *
12
- * @module linked-assets
12
+ * @module linked
13
13
  */
14
14
  export {};
package/dist/mod.d.ts CHANGED
@@ -33,7 +33,7 @@ export * from "./relation.js";
33
33
  export * from "./schema.js";
34
34
  export * from "./api.js";
35
35
  export * from "./asset.js";
36
- export * from "./linked-assets.js";
36
+ export * from "./linked.js";
37
37
  export * from "./adapter.js";
38
38
  export * from "./session.js";
39
39
  export * from "./customer.js";
package/dist/mod.js CHANGED
@@ -38,8 +38,8 @@ export * from "./schema.js";
38
38
  export * from "./api.js";
39
39
  // Assets
40
40
  export * from "./asset.js";
41
- // Linked Assets (metadata-based linking configuration)
42
- export * from "./linked-assets.js";
41
+ // Linked models (metadata-based linking configuration)
42
+ export * from "./linked.js";
43
43
  // Adapter (database layer)
44
44
  export * from "./adapter.js";
45
45
  // E-commerce domain types
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marianmeres/collection-types",
3
- "version": "1.15.0",
3
+ "version": "1.17.0",
4
4
  "type": "module",
5
5
  "main": "dist/mod.js",
6
6
  "types": "dist/mod.d.ts",
@@ -1,183 +0,0 @@
1
- /**
2
- * Linked Assets Configuration Types
3
- *
4
- * Types for the linked assets feature - a configuration-driven system
5
- * for displaying assets that are implicitly linked via metadata matching
6
- * rather than explicit relation records.
7
- *
8
- * Used by:
9
- * - Joy admin (frontend configuration consumption)
10
- * - Backend (configuration storage and bootstrap)
11
- *
12
- * @module linked-assets
13
- */
14
- import type { MaybeLocalized } from "./utils.js";
15
- /**
16
- * Comparison operators supported for matching conditions.
17
- * Maps to @marianmeres/condition-builder OPERATOR enum.
18
- */
19
- export type LinkedAssetOperator = "eq" | "neq" | "lt" | "lte" | "gt" | "gte" | "like" | "ilike" | "in" | "nin" | "?" | "descendant";
20
- /**
21
- * Value source: where to get the value for matching.
22
- * - "literal": use the value as-is
23
- * - "model_field": extract from current model's data using dot-path
24
- */
25
- export type LinkedAssetValueSource = "literal" | "model_field";
26
- /**
27
- * A single matching condition for linked assets.
28
- *
29
- * @example
30
- * // Match assets where data.custom.sku equals model's sku field
31
- * {
32
- * asset_field: "data.custom.sku",
33
- * operator: "eq",
34
- * value_source: "model_field",
35
- * value: "sku"
36
- * }
37
- */
38
- export interface LinkedAssetCondition {
39
- /**
40
- * The field path on the asset model to match against.
41
- * Examples: "type", "data.custom.sku", "folder", "tags"
42
- */
43
- asset_field: string;
44
- /** Comparison operator */
45
- operator: LinkedAssetOperator;
46
- /** How to interpret the value */
47
- value_source: LinkedAssetValueSource;
48
- /**
49
- * The value to match:
50
- * - If value_source is "literal": the actual value to compare
51
- * - If value_source is "model_field": dot-path to model field
52
- */
53
- value: string | number | boolean;
54
- }
55
- /**
56
- * Upload configuration for linked assets.
57
- * When present, enables file upload capability.
58
- */
59
- export interface LinkedAssetUploadConfig {
60
- /**
61
- * Auto-populate custom fields from parent model during upload.
62
- * Key: asset field path (e.g., "custom.sku")
63
- * Value: model field path (e.g., "sku")
64
- */
65
- auto_fill_custom: Record<string, string>;
66
- /**
67
- * Asset type to use for uploads.
68
- * @default asset_query.type
69
- */
70
- type?: string;
71
- /**
72
- * Accepted file types (MIME patterns).
73
- * @default "image/*"
74
- */
75
- accept?: string;
76
- /**
77
- * Maximum number of files (-1 for unlimited).
78
- * @default -1
79
- */
80
- cardinality?: number;
81
- }
82
- /**
83
- * Unlink configuration for linked assets.
84
- * Defines how to remove the link between asset and parent model.
85
- */
86
- export interface LinkedAssetUnlinkConfig {
87
- /**
88
- * Which custom field to clear when unlinking.
89
- * Should match a key from upload.auto_fill_custom.
90
- */
91
- field: string;
92
- /**
93
- * Require confirmation before unlinking.
94
- * @default true
95
- */
96
- confirm?: boolean;
97
- }
98
- /**
99
- * Asset query configuration within a rule.
100
- */
101
- export interface LinkedAssetQueryConfig {
102
- /**
103
- * Asset domain to query.
104
- * @default "asset"
105
- */
106
- domain?: string;
107
- /**
108
- * Asset entity/collection to query.
109
- * @default "asset"
110
- */
111
- entity?: string;
112
- /**
113
- * Asset type filter (e.g., "product-image").
114
- * If specified, adds `type:eq:<value>` to conditions.
115
- */
116
- type?: string;
117
- /**
118
- * Conditions to build the asset query.
119
- * Combined with AND logic.
120
- */
121
- conditions: LinkedAssetCondition[];
122
- /**
123
- * Always include these base conditions.
124
- * @default [{ asset_field: "is_enabled", operator: "eq", value_source: "literal", value: true }]
125
- */
126
- base_conditions?: LinkedAssetCondition[];
127
- }
128
- /**
129
- * Match context configuration.
130
- * Defines when a rule should be applied.
131
- */
132
- export interface LinkedAssetMatchConfig {
133
- /** Domain to match (e.g., "product") */
134
- domain?: string;
135
- /** Entity/collection to match (e.g., "product", "category") */
136
- entity?: string;
137
- /** Type to match (e.g., "default", "variant") */
138
- type?: string;
139
- }
140
- /**
141
- * A single linked assets rule configuration.
142
- * Defines when and how to show/manage linked assets for a specific model context.
143
- */
144
- export interface LinkedAssetRule {
145
- /** Unique identifier for this rule */
146
- id: string;
147
- /** Human-readable label (supports localization) */
148
- label: MaybeLocalized<string>;
149
- /** Optional description */
150
- description?: MaybeLocalized<string>;
151
- /** When to apply this rule (AND logic, omitted = any) */
152
- match: LinkedAssetMatchConfig;
153
- /** Asset query configuration */
154
- asset_query: LinkedAssetQueryConfig;
155
- /** Upload configuration - enables CRUD mode when present */
156
- upload?: LinkedAssetUploadConfig;
157
- /** Unlink configuration - defines how to remove links */
158
- unlink?: LinkedAssetUnlinkConfig;
159
- /**
160
- * Whether this rule is enabled.
161
- * @default true
162
- */
163
- enabled?: boolean;
164
- /**
165
- * Sort order when multiple rules match (lower = earlier).
166
- * @default 0
167
- */
168
- order?: number;
169
- }
170
- /**
171
- * The complete linked assets configuration structure.
172
- * Stored as the value of the `__joy_linked_assets__` config record.
173
- */
174
- export interface LinkedAssetsConfig {
175
- /**
176
- * Schema version for future migrations.
177
- */
178
- version: number;
179
- /**
180
- * Array of linked asset rules.
181
- */
182
- rules: LinkedAssetRule[];
183
- }