@antglobal/copilot-cards-core 0.0.20260806095059-dev.1 → 0.0.20260811080429-dev.5
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/index.cjs +92 -20
- package/dist/index.d.ts +5 -2
- package/dist/index.js +92 -20
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1937,6 +1937,7 @@ function validateSchema(input) {
|
|
|
1937
1937
|
}
|
|
1938
1938
|
const REPEAT_SLOT_LAYOUTS = new Set([
|
|
1939
1939
|
'default',
|
|
1940
|
+
'flex',
|
|
1940
1941
|
'list',
|
|
1941
1942
|
'grid',
|
|
1942
1943
|
'horizontalScroll',
|
|
@@ -2050,11 +2051,15 @@ function readRepeatBindingFields(value) {
|
|
|
2050
2051
|
const template = readOwnData(value, 'template');
|
|
2051
2052
|
const item = readOwnData(value, 'item');
|
|
2052
2053
|
const index = readOwnData(value, 'index');
|
|
2054
|
+
const emptyTemplate = readOwnData(value, 'emptyTemplate');
|
|
2053
2055
|
return {
|
|
2054
2056
|
source: source.kind === 'value' ? source.value : undefined,
|
|
2055
2057
|
template: template.kind === 'value' ? template.value : undefined,
|
|
2056
|
-
item
|
|
2058
|
+
...(item.kind === 'value' ? { item: item.value } : {}),
|
|
2057
2059
|
...(index.kind === 'value' ? { index: index.value } : {}),
|
|
2060
|
+
...(emptyTemplate.kind === 'value'
|
|
2061
|
+
? { emptyTemplate: emptyTemplate.value }
|
|
2062
|
+
: {}),
|
|
2058
2063
|
};
|
|
2059
2064
|
}
|
|
2060
2065
|
function slotStaticReferences(slot) {
|
|
@@ -2179,6 +2184,10 @@ function elementReferences(element) {
|
|
|
2179
2184
|
if (typeof binding?.template === 'string' && binding.template) {
|
|
2180
2185
|
references.push(binding.template);
|
|
2181
2186
|
}
|
|
2187
|
+
if (typeof binding?.emptyTemplate === 'string'
|
|
2188
|
+
&& binding.emptyTemplate) {
|
|
2189
|
+
references.push(binding.emptyTemplate);
|
|
2190
|
+
}
|
|
2182
2191
|
const a2ui = getA2UIChildBinding(slot);
|
|
2183
2192
|
if (typeof a2ui?.templateId === 'string' && a2ui.templateId) {
|
|
2184
2193
|
references.push(a2ui.templateId);
|
|
@@ -2257,13 +2266,27 @@ function validateRepeatBindings(schema, errors) {
|
|
|
2257
2266
|
else if (!getOwnElement(schema, binding.template)) {
|
|
2258
2267
|
errors.push(`Element "${id}" slot "${slotName}" repeat references unknown template "${binding.template}"`);
|
|
2259
2268
|
}
|
|
2260
|
-
|
|
2269
|
+
if (binding.item !== undefined) {
|
|
2270
|
+
validateAlias(id, slotName, 'item', binding.item, errors);
|
|
2271
|
+
}
|
|
2261
2272
|
if (binding.index !== undefined) {
|
|
2262
2273
|
validateAlias(id, slotName, 'index', binding.index, errors);
|
|
2263
2274
|
}
|
|
2264
|
-
if (binding.index !== undefined
|
|
2275
|
+
if (binding.index !== undefined
|
|
2276
|
+
&& (binding.item ?? '$item') === binding.index) {
|
|
2265
2277
|
errors.push(`Element "${id}" slot "${slotName}" repeat item and index aliases must be different`);
|
|
2266
2278
|
}
|
|
2279
|
+
if (binding.emptyTemplate !== undefined) {
|
|
2280
|
+
if (typeof binding.emptyTemplate !== 'string') {
|
|
2281
|
+
errors.push(`Element "${id}" slot "${slotName}" repeat emptyTemplate must be a string`);
|
|
2282
|
+
}
|
|
2283
|
+
else if (!binding.emptyTemplate) {
|
|
2284
|
+
errors.push(`Element "${id}" slot "${slotName}" repeat emptyTemplate must be a non-empty string`);
|
|
2285
|
+
}
|
|
2286
|
+
else if (!getOwnElement(schema, binding.emptyTemplate)) {
|
|
2287
|
+
errors.push(`Element "${id}" slot "${slotName}" repeat references unknown empty template "${binding.emptyTemplate}"`);
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2267
2290
|
}
|
|
2268
2291
|
}
|
|
2269
2292
|
validateRepeatNesting(schema, dynamicBindings, errors);
|
|
@@ -2283,6 +2306,17 @@ function validateAlias(owner, slotName, kind, alias, errors) {
|
|
|
2283
2306
|
function validateRepeatNesting(schema, bindings, errors) {
|
|
2284
2307
|
const reportedCycles = new Set();
|
|
2285
2308
|
const reportedCollisions = new Set();
|
|
2309
|
+
function effectiveAliases(binding) {
|
|
2310
|
+
if (!binding)
|
|
2311
|
+
return [];
|
|
2312
|
+
if (binding.item !== undefined) {
|
|
2313
|
+
return [binding.item, binding.index].filter((alias) => typeof alias === 'string');
|
|
2314
|
+
}
|
|
2315
|
+
return [
|
|
2316
|
+
'$item',
|
|
2317
|
+
binding.index === undefined ? '$index' : binding.index,
|
|
2318
|
+
].filter((alias) => typeof alias === 'string');
|
|
2319
|
+
}
|
|
2286
2320
|
function visitElement(id, activeAliases, repeatPath, visitedStatic) {
|
|
2287
2321
|
const element = getOwnElement(schema, id);
|
|
2288
2322
|
if (!element || visitedStatic.has(id))
|
|
@@ -2297,8 +2331,10 @@ function validateRepeatNesting(schema, bindings, errors) {
|
|
|
2297
2331
|
? readRepeatBindingFields(repeat.value)
|
|
2298
2332
|
: undefined;
|
|
2299
2333
|
const a2uiBinding = getA2UIChildBinding(slot);
|
|
2300
|
-
const
|
|
2301
|
-
|
|
2334
|
+
const itemTemplate = nativeBinding?.template ?? a2uiBinding?.templateId;
|
|
2335
|
+
const visitDynamicTemplate = (template, aliases) => {
|
|
2336
|
+
if (!template)
|
|
2337
|
+
return;
|
|
2302
2338
|
const cycleAt = repeatPath.indexOf(template);
|
|
2303
2339
|
if (cycleAt >= 0) {
|
|
2304
2340
|
const cycle = [...repeatPath.slice(cycleAt), template].join(' -> ');
|
|
@@ -2308,9 +2344,8 @@ function validateRepeatNesting(schema, bindings, errors) {
|
|
|
2308
2344
|
? `Element "${id}" slot "${slotName}" has repeat template cycle: ${cycle}`
|
|
2309
2345
|
: `Element "${id}" slot "${slotName}" has dynamic template cycle: ${cycle}`);
|
|
2310
2346
|
}
|
|
2311
|
-
|
|
2347
|
+
return;
|
|
2312
2348
|
}
|
|
2313
|
-
const aliases = [nativeBinding?.item, nativeBinding?.index].filter((alias) => typeof alias === 'string');
|
|
2314
2349
|
for (const alias of aliases) {
|
|
2315
2350
|
if (activeAliases.has(alias)) {
|
|
2316
2351
|
const key = `${id}:${slotName}:${alias}`;
|
|
@@ -2324,7 +2359,9 @@ function validateRepeatNesting(schema, bindings, errors) {
|
|
|
2324
2359
|
for (const alias of aliases)
|
|
2325
2360
|
nestedAliases.add(alias);
|
|
2326
2361
|
visitElement(template, nestedAliases, [...repeatPath, template], new Set());
|
|
2327
|
-
}
|
|
2362
|
+
};
|
|
2363
|
+
visitDynamicTemplate(itemTemplate, effectiveAliases(nativeBinding));
|
|
2364
|
+
visitDynamicTemplate(nativeBinding?.emptyTemplate, []);
|
|
2328
2365
|
for (const child of slotStaticReferences(slot)) {
|
|
2329
2366
|
visitElement(child, activeAliases, repeatPath, nextVisitedStatic);
|
|
2330
2367
|
}
|
|
@@ -2332,10 +2369,14 @@ function validateRepeatNesting(schema, bindings, errors) {
|
|
|
2332
2369
|
}
|
|
2333
2370
|
for (const dynamic of bindings) {
|
|
2334
2371
|
const { owner, binding, template } = dynamic;
|
|
2335
|
-
const aliases = new Set(
|
|
2372
|
+
const aliases = new Set(effectiveAliases(binding));
|
|
2336
2373
|
if (typeof template === 'string' && template) {
|
|
2337
2374
|
visitElement(template, aliases, [owner, template], new Set());
|
|
2338
2375
|
}
|
|
2376
|
+
if (typeof binding?.emptyTemplate === 'string'
|
|
2377
|
+
&& binding.emptyTemplate) {
|
|
2378
|
+
visitElement(binding.emptyTemplate, new Set(), [owner, binding.emptyTemplate], new Set());
|
|
2379
|
+
}
|
|
2339
2380
|
}
|
|
2340
2381
|
}
|
|
2341
2382
|
function validateDynamicClosures(schema, repeats, errors) {
|
|
@@ -2882,6 +2923,7 @@ function materializeCard(input, variables, options = {}) {
|
|
|
2882
2923
|
template: native.template,
|
|
2883
2924
|
item: native.item,
|
|
2884
2925
|
index: native.index,
|
|
2926
|
+
emptyTemplate: native.emptyTemplate,
|
|
2885
2927
|
};
|
|
2886
2928
|
}
|
|
2887
2929
|
else {
|
|
@@ -2909,6 +2951,9 @@ function materializeCard(input, variables, options = {}) {
|
|
|
2909
2951
|
sourceOwnerId: sourceId,
|
|
2910
2952
|
slot: slotName,
|
|
2911
2953
|
templateId: binding.template,
|
|
2954
|
+
...(binding.emptyTemplate
|
|
2955
|
+
? { emptyTemplateId: binding.emptyTemplate }
|
|
2956
|
+
: {}),
|
|
2912
2957
|
...(sourcePath === undefined ? {} : { sourcePath }),
|
|
2913
2958
|
dataPath: activeScope.dataPath,
|
|
2914
2959
|
instancePath,
|
|
@@ -2920,6 +2965,9 @@ function materializeCard(input, variables, options = {}) {
|
|
|
2920
2965
|
repeatOwners.set(ownerKey, owner);
|
|
2921
2966
|
slotOwners.set(slotName, { owner, binding, sourcePath, depth });
|
|
2922
2967
|
addDependency('component', binding.template, ownerKey);
|
|
2968
|
+
if (binding.emptyTemplate) {
|
|
2969
|
+
addDependency('component', binding.emptyTemplate, ownerKey);
|
|
2970
|
+
}
|
|
2923
2971
|
const runtimeKeys = runtimeOwnerKeys.get(id) ?? [];
|
|
2924
2972
|
if (runtimeKeys.length > 0) {
|
|
2925
2973
|
for (const key of runtimeKeys)
|
|
@@ -3000,15 +3048,30 @@ function materializeCard(input, variables, options = {}) {
|
|
|
3000
3048
|
Reflect.deleteProperty(slot, 'repeat');
|
|
3001
3049
|
Reflect.deleteProperty(slot, A2UI_CHILD_BINDING);
|
|
3002
3050
|
slot.children = [];
|
|
3051
|
+
if (items.length === 0
|
|
3052
|
+
&& binding.dialect === 'native'
|
|
3053
|
+
&& binding.emptyTemplate) {
|
|
3054
|
+
const emptyPath = appendOccurrence(structuralPath, 'item', sourceId, slotName, `${binding.emptyTemplate}:empty`);
|
|
3055
|
+
const empty = buildNode(binding.emptyTemplate, activeScope, emptyPath, emptyPath, true, id, depth, owner.key, nextActiveDefinitions);
|
|
3056
|
+
slot.children.push(empty.id);
|
|
3057
|
+
node.children.push(empty);
|
|
3058
|
+
}
|
|
3003
3059
|
items.forEach((item, index) => {
|
|
3004
3060
|
const dataPath = sourcePath === undefined
|
|
3005
3061
|
? activeScope.dataPath
|
|
3006
3062
|
: joinPointer(sourcePath, [String(index)]);
|
|
3007
|
-
const locals = binding.dialect === 'native'
|
|
3008
|
-
?
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3063
|
+
const locals = binding.dialect === 'native'
|
|
3064
|
+
? binding.item !== undefined
|
|
3065
|
+
? {
|
|
3066
|
+
[binding.item]: item,
|
|
3067
|
+
...(binding.index === undefined
|
|
3068
|
+
? {}
|
|
3069
|
+
: { [binding.index]: index }),
|
|
3070
|
+
}
|
|
3071
|
+
: {
|
|
3072
|
+
$item: item,
|
|
3073
|
+
[binding.index ?? '$index']: index,
|
|
3074
|
+
}
|
|
3012
3075
|
: {};
|
|
3013
3076
|
const childScope = {
|
|
3014
3077
|
root: rootVariables,
|
|
@@ -3018,14 +3081,23 @@ function materializeCard(input, variables, options = {}) {
|
|
|
3018
3081
|
bindingDialect: binding.dialect,
|
|
3019
3082
|
};
|
|
3020
3083
|
const aliases = new Map();
|
|
3021
|
-
if (binding.dialect === 'native'
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3084
|
+
if (binding.dialect === 'native') {
|
|
3085
|
+
const itemAlias = binding.item ?? '$item';
|
|
3086
|
+
const indexAlias = binding.item === undefined
|
|
3087
|
+
? binding.index ?? '$index'
|
|
3088
|
+
: binding.index;
|
|
3089
|
+
aliases.set(itemAlias, sourcePath === undefined ? undefined : dataPath);
|
|
3090
|
+
if (indexAlias !== undefined) {
|
|
3091
|
+
aliases.set(indexAlias, sourcePath);
|
|
3092
|
+
}
|
|
3025
3093
|
}
|
|
3026
3094
|
scopeAliasPaths.set(childScope, aliases);
|
|
3027
|
-
scopeIndexAliases.set(childScope, new Set(binding.dialect === 'native'
|
|
3028
|
-
?
|
|
3095
|
+
scopeIndexAliases.set(childScope, new Set(binding.dialect === 'native'
|
|
3096
|
+
? binding.item === undefined
|
|
3097
|
+
? [binding.index ?? '$index']
|
|
3098
|
+
: binding.index === undefined
|
|
3099
|
+
? []
|
|
3100
|
+
: [binding.index]
|
|
3029
3101
|
: []));
|
|
3030
3102
|
const itemPath = appendOccurrence(structuralPath, 'item', sourceId, slotName, `${binding.template}:${index}`);
|
|
3031
3103
|
const child = buildNode(binding.template, childScope, itemPath, itemPath, true, id, depth, owner.key, nextActiveDefinitions);
|
package/dist/index.d.ts
CHANGED
|
@@ -151,6 +151,7 @@ interface ExpressionValue {
|
|
|
151
151
|
/**
|
|
152
152
|
* Slot layout mode — the key name in `props.slots` determines the layout:
|
|
153
153
|
* - default: no special layout, children appended directly
|
|
154
|
+
* - flex: one-dimensional Flexbox layout applied to the host container
|
|
154
155
|
* - columns: multi-column layout using groups (each group = one column)
|
|
155
156
|
* - grid: CSS grid with configurable column count and gap
|
|
156
157
|
* - horizontalScroll: horizontal scrollable container with drag and snap
|
|
@@ -158,13 +159,14 @@ interface ExpressionValue {
|
|
|
158
159
|
* - list: vertical list with optional ordered/unordered markers
|
|
159
160
|
* - float: relative container with absolutely positioned overlays
|
|
160
161
|
*/
|
|
161
|
-
type SlotLayout = 'default' | 'columns' | 'grid' | 'horizontalScroll' | 'carousel' | 'list' | 'float' | 'keyValue' | 'table' | 'chart';
|
|
162
|
+
type SlotLayout = 'default' | 'flex' | 'columns' | 'grid' | 'horizontalScroll' | 'carousel' | 'list' | 'float' | 'keyValue' | 'table' | 'chart';
|
|
162
163
|
/** Binds a slot to a template that is instantiated once per source item. */
|
|
163
164
|
interface RepeatBinding {
|
|
164
165
|
source: string;
|
|
165
166
|
template: string;
|
|
166
|
-
item
|
|
167
|
+
item?: string;
|
|
167
168
|
index?: string;
|
|
169
|
+
emptyTemplate?: string;
|
|
168
170
|
}
|
|
169
171
|
/**
|
|
170
172
|
* Content of a named slot.
|
|
@@ -468,6 +470,7 @@ interface RepeatOwner {
|
|
|
468
470
|
sourceOwnerId: string;
|
|
469
471
|
slot: SlotLayout;
|
|
470
472
|
templateId: string;
|
|
473
|
+
emptyTemplateId?: string;
|
|
471
474
|
sourcePath?: string;
|
|
472
475
|
dataPath: string;
|
|
473
476
|
instancePath: string;
|
package/dist/index.js
CHANGED
|
@@ -1935,6 +1935,7 @@ function validateSchema(input) {
|
|
|
1935
1935
|
}
|
|
1936
1936
|
const REPEAT_SLOT_LAYOUTS = new Set([
|
|
1937
1937
|
'default',
|
|
1938
|
+
'flex',
|
|
1938
1939
|
'list',
|
|
1939
1940
|
'grid',
|
|
1940
1941
|
'horizontalScroll',
|
|
@@ -2048,11 +2049,15 @@ function readRepeatBindingFields(value) {
|
|
|
2048
2049
|
const template = readOwnData(value, 'template');
|
|
2049
2050
|
const item = readOwnData(value, 'item');
|
|
2050
2051
|
const index = readOwnData(value, 'index');
|
|
2052
|
+
const emptyTemplate = readOwnData(value, 'emptyTemplate');
|
|
2051
2053
|
return {
|
|
2052
2054
|
source: source.kind === 'value' ? source.value : undefined,
|
|
2053
2055
|
template: template.kind === 'value' ? template.value : undefined,
|
|
2054
|
-
item
|
|
2056
|
+
...(item.kind === 'value' ? { item: item.value } : {}),
|
|
2055
2057
|
...(index.kind === 'value' ? { index: index.value } : {}),
|
|
2058
|
+
...(emptyTemplate.kind === 'value'
|
|
2059
|
+
? { emptyTemplate: emptyTemplate.value }
|
|
2060
|
+
: {}),
|
|
2056
2061
|
};
|
|
2057
2062
|
}
|
|
2058
2063
|
function slotStaticReferences(slot) {
|
|
@@ -2177,6 +2182,10 @@ function elementReferences(element) {
|
|
|
2177
2182
|
if (typeof binding?.template === 'string' && binding.template) {
|
|
2178
2183
|
references.push(binding.template);
|
|
2179
2184
|
}
|
|
2185
|
+
if (typeof binding?.emptyTemplate === 'string'
|
|
2186
|
+
&& binding.emptyTemplate) {
|
|
2187
|
+
references.push(binding.emptyTemplate);
|
|
2188
|
+
}
|
|
2180
2189
|
const a2ui = getA2UIChildBinding(slot);
|
|
2181
2190
|
if (typeof a2ui?.templateId === 'string' && a2ui.templateId) {
|
|
2182
2191
|
references.push(a2ui.templateId);
|
|
@@ -2255,13 +2264,27 @@ function validateRepeatBindings(schema, errors) {
|
|
|
2255
2264
|
else if (!getOwnElement(schema, binding.template)) {
|
|
2256
2265
|
errors.push(`Element "${id}" slot "${slotName}" repeat references unknown template "${binding.template}"`);
|
|
2257
2266
|
}
|
|
2258
|
-
|
|
2267
|
+
if (binding.item !== undefined) {
|
|
2268
|
+
validateAlias(id, slotName, 'item', binding.item, errors);
|
|
2269
|
+
}
|
|
2259
2270
|
if (binding.index !== undefined) {
|
|
2260
2271
|
validateAlias(id, slotName, 'index', binding.index, errors);
|
|
2261
2272
|
}
|
|
2262
|
-
if (binding.index !== undefined
|
|
2273
|
+
if (binding.index !== undefined
|
|
2274
|
+
&& (binding.item ?? '$item') === binding.index) {
|
|
2263
2275
|
errors.push(`Element "${id}" slot "${slotName}" repeat item and index aliases must be different`);
|
|
2264
2276
|
}
|
|
2277
|
+
if (binding.emptyTemplate !== undefined) {
|
|
2278
|
+
if (typeof binding.emptyTemplate !== 'string') {
|
|
2279
|
+
errors.push(`Element "${id}" slot "${slotName}" repeat emptyTemplate must be a string`);
|
|
2280
|
+
}
|
|
2281
|
+
else if (!binding.emptyTemplate) {
|
|
2282
|
+
errors.push(`Element "${id}" slot "${slotName}" repeat emptyTemplate must be a non-empty string`);
|
|
2283
|
+
}
|
|
2284
|
+
else if (!getOwnElement(schema, binding.emptyTemplate)) {
|
|
2285
|
+
errors.push(`Element "${id}" slot "${slotName}" repeat references unknown empty template "${binding.emptyTemplate}"`);
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2265
2288
|
}
|
|
2266
2289
|
}
|
|
2267
2290
|
validateRepeatNesting(schema, dynamicBindings, errors);
|
|
@@ -2281,6 +2304,17 @@ function validateAlias(owner, slotName, kind, alias, errors) {
|
|
|
2281
2304
|
function validateRepeatNesting(schema, bindings, errors) {
|
|
2282
2305
|
const reportedCycles = new Set();
|
|
2283
2306
|
const reportedCollisions = new Set();
|
|
2307
|
+
function effectiveAliases(binding) {
|
|
2308
|
+
if (!binding)
|
|
2309
|
+
return [];
|
|
2310
|
+
if (binding.item !== undefined) {
|
|
2311
|
+
return [binding.item, binding.index].filter((alias) => typeof alias === 'string');
|
|
2312
|
+
}
|
|
2313
|
+
return [
|
|
2314
|
+
'$item',
|
|
2315
|
+
binding.index === undefined ? '$index' : binding.index,
|
|
2316
|
+
].filter((alias) => typeof alias === 'string');
|
|
2317
|
+
}
|
|
2284
2318
|
function visitElement(id, activeAliases, repeatPath, visitedStatic) {
|
|
2285
2319
|
const element = getOwnElement(schema, id);
|
|
2286
2320
|
if (!element || visitedStatic.has(id))
|
|
@@ -2295,8 +2329,10 @@ function validateRepeatNesting(schema, bindings, errors) {
|
|
|
2295
2329
|
? readRepeatBindingFields(repeat.value)
|
|
2296
2330
|
: undefined;
|
|
2297
2331
|
const a2uiBinding = getA2UIChildBinding(slot);
|
|
2298
|
-
const
|
|
2299
|
-
|
|
2332
|
+
const itemTemplate = nativeBinding?.template ?? a2uiBinding?.templateId;
|
|
2333
|
+
const visitDynamicTemplate = (template, aliases) => {
|
|
2334
|
+
if (!template)
|
|
2335
|
+
return;
|
|
2300
2336
|
const cycleAt = repeatPath.indexOf(template);
|
|
2301
2337
|
if (cycleAt >= 0) {
|
|
2302
2338
|
const cycle = [...repeatPath.slice(cycleAt), template].join(' -> ');
|
|
@@ -2306,9 +2342,8 @@ function validateRepeatNesting(schema, bindings, errors) {
|
|
|
2306
2342
|
? `Element "${id}" slot "${slotName}" has repeat template cycle: ${cycle}`
|
|
2307
2343
|
: `Element "${id}" slot "${slotName}" has dynamic template cycle: ${cycle}`);
|
|
2308
2344
|
}
|
|
2309
|
-
|
|
2345
|
+
return;
|
|
2310
2346
|
}
|
|
2311
|
-
const aliases = [nativeBinding?.item, nativeBinding?.index].filter((alias) => typeof alias === 'string');
|
|
2312
2347
|
for (const alias of aliases) {
|
|
2313
2348
|
if (activeAliases.has(alias)) {
|
|
2314
2349
|
const key = `${id}:${slotName}:${alias}`;
|
|
@@ -2322,7 +2357,9 @@ function validateRepeatNesting(schema, bindings, errors) {
|
|
|
2322
2357
|
for (const alias of aliases)
|
|
2323
2358
|
nestedAliases.add(alias);
|
|
2324
2359
|
visitElement(template, nestedAliases, [...repeatPath, template], new Set());
|
|
2325
|
-
}
|
|
2360
|
+
};
|
|
2361
|
+
visitDynamicTemplate(itemTemplate, effectiveAliases(nativeBinding));
|
|
2362
|
+
visitDynamicTemplate(nativeBinding?.emptyTemplate, []);
|
|
2326
2363
|
for (const child of slotStaticReferences(slot)) {
|
|
2327
2364
|
visitElement(child, activeAliases, repeatPath, nextVisitedStatic);
|
|
2328
2365
|
}
|
|
@@ -2330,10 +2367,14 @@ function validateRepeatNesting(schema, bindings, errors) {
|
|
|
2330
2367
|
}
|
|
2331
2368
|
for (const dynamic of bindings) {
|
|
2332
2369
|
const { owner, binding, template } = dynamic;
|
|
2333
|
-
const aliases = new Set(
|
|
2370
|
+
const aliases = new Set(effectiveAliases(binding));
|
|
2334
2371
|
if (typeof template === 'string' && template) {
|
|
2335
2372
|
visitElement(template, aliases, [owner, template], new Set());
|
|
2336
2373
|
}
|
|
2374
|
+
if (typeof binding?.emptyTemplate === 'string'
|
|
2375
|
+
&& binding.emptyTemplate) {
|
|
2376
|
+
visitElement(binding.emptyTemplate, new Set(), [owner, binding.emptyTemplate], new Set());
|
|
2377
|
+
}
|
|
2337
2378
|
}
|
|
2338
2379
|
}
|
|
2339
2380
|
function validateDynamicClosures(schema, repeats, errors) {
|
|
@@ -2880,6 +2921,7 @@ function materializeCard(input, variables, options = {}) {
|
|
|
2880
2921
|
template: native.template,
|
|
2881
2922
|
item: native.item,
|
|
2882
2923
|
index: native.index,
|
|
2924
|
+
emptyTemplate: native.emptyTemplate,
|
|
2883
2925
|
};
|
|
2884
2926
|
}
|
|
2885
2927
|
else {
|
|
@@ -2907,6 +2949,9 @@ function materializeCard(input, variables, options = {}) {
|
|
|
2907
2949
|
sourceOwnerId: sourceId,
|
|
2908
2950
|
slot: slotName,
|
|
2909
2951
|
templateId: binding.template,
|
|
2952
|
+
...(binding.emptyTemplate
|
|
2953
|
+
? { emptyTemplateId: binding.emptyTemplate }
|
|
2954
|
+
: {}),
|
|
2910
2955
|
...(sourcePath === undefined ? {} : { sourcePath }),
|
|
2911
2956
|
dataPath: activeScope.dataPath,
|
|
2912
2957
|
instancePath,
|
|
@@ -2918,6 +2963,9 @@ function materializeCard(input, variables, options = {}) {
|
|
|
2918
2963
|
repeatOwners.set(ownerKey, owner);
|
|
2919
2964
|
slotOwners.set(slotName, { owner, binding, sourcePath, depth });
|
|
2920
2965
|
addDependency('component', binding.template, ownerKey);
|
|
2966
|
+
if (binding.emptyTemplate) {
|
|
2967
|
+
addDependency('component', binding.emptyTemplate, ownerKey);
|
|
2968
|
+
}
|
|
2921
2969
|
const runtimeKeys = runtimeOwnerKeys.get(id) ?? [];
|
|
2922
2970
|
if (runtimeKeys.length > 0) {
|
|
2923
2971
|
for (const key of runtimeKeys)
|
|
@@ -2998,15 +3046,30 @@ function materializeCard(input, variables, options = {}) {
|
|
|
2998
3046
|
Reflect.deleteProperty(slot, 'repeat');
|
|
2999
3047
|
Reflect.deleteProperty(slot, A2UI_CHILD_BINDING);
|
|
3000
3048
|
slot.children = [];
|
|
3049
|
+
if (items.length === 0
|
|
3050
|
+
&& binding.dialect === 'native'
|
|
3051
|
+
&& binding.emptyTemplate) {
|
|
3052
|
+
const emptyPath = appendOccurrence(structuralPath, 'item', sourceId, slotName, `${binding.emptyTemplate}:empty`);
|
|
3053
|
+
const empty = buildNode(binding.emptyTemplate, activeScope, emptyPath, emptyPath, true, id, depth, owner.key, nextActiveDefinitions);
|
|
3054
|
+
slot.children.push(empty.id);
|
|
3055
|
+
node.children.push(empty);
|
|
3056
|
+
}
|
|
3001
3057
|
items.forEach((item, index) => {
|
|
3002
3058
|
const dataPath = sourcePath === undefined
|
|
3003
3059
|
? activeScope.dataPath
|
|
3004
3060
|
: joinPointer(sourcePath, [String(index)]);
|
|
3005
|
-
const locals = binding.dialect === 'native'
|
|
3006
|
-
?
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3061
|
+
const locals = binding.dialect === 'native'
|
|
3062
|
+
? binding.item !== undefined
|
|
3063
|
+
? {
|
|
3064
|
+
[binding.item]: item,
|
|
3065
|
+
...(binding.index === undefined
|
|
3066
|
+
? {}
|
|
3067
|
+
: { [binding.index]: index }),
|
|
3068
|
+
}
|
|
3069
|
+
: {
|
|
3070
|
+
$item: item,
|
|
3071
|
+
[binding.index ?? '$index']: index,
|
|
3072
|
+
}
|
|
3010
3073
|
: {};
|
|
3011
3074
|
const childScope = {
|
|
3012
3075
|
root: rootVariables,
|
|
@@ -3016,14 +3079,23 @@ function materializeCard(input, variables, options = {}) {
|
|
|
3016
3079
|
bindingDialect: binding.dialect,
|
|
3017
3080
|
};
|
|
3018
3081
|
const aliases = new Map();
|
|
3019
|
-
if (binding.dialect === 'native'
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3082
|
+
if (binding.dialect === 'native') {
|
|
3083
|
+
const itemAlias = binding.item ?? '$item';
|
|
3084
|
+
const indexAlias = binding.item === undefined
|
|
3085
|
+
? binding.index ?? '$index'
|
|
3086
|
+
: binding.index;
|
|
3087
|
+
aliases.set(itemAlias, sourcePath === undefined ? undefined : dataPath);
|
|
3088
|
+
if (indexAlias !== undefined) {
|
|
3089
|
+
aliases.set(indexAlias, sourcePath);
|
|
3090
|
+
}
|
|
3023
3091
|
}
|
|
3024
3092
|
scopeAliasPaths.set(childScope, aliases);
|
|
3025
|
-
scopeIndexAliases.set(childScope, new Set(binding.dialect === 'native'
|
|
3026
|
-
?
|
|
3093
|
+
scopeIndexAliases.set(childScope, new Set(binding.dialect === 'native'
|
|
3094
|
+
? binding.item === undefined
|
|
3095
|
+
? [binding.index ?? '$index']
|
|
3096
|
+
: binding.index === undefined
|
|
3097
|
+
? []
|
|
3098
|
+
: [binding.index]
|
|
3027
3099
|
: []));
|
|
3028
3100
|
const itemPath = appendOccurrence(structuralPath, 'item', sourceId, slotName, `${binding.template}:${index}`);
|
|
3029
3101
|
const child = buildNode(binding.template, childScope, itemPath, itemPath, true, id, depth, owner.key, nextActiveDefinitions);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antglobal/copilot-cards-core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20260811080429-dev.5",
|
|
4
4
|
"description": "Core logic engine for copilot bot card SDK — no UI, pure logic (Expression Engine, Action Runner, Schema Parser, Lifecycle Manager)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|