@pikku/inspector 0.12.55 → 0.12.56
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/CHANGELOG.md +38 -0
- package/dist/error-codes.d.ts +1 -0
- package/dist/error-codes.js +1 -0
- package/dist/inspector.js +7 -2
- package/dist/utils/post-process.d.ts +15 -0
- package/dist/utils/post-process.js +52 -0
- package/dist/utils/workflow/graph/serialize-workflow-graph.js +2 -10
- package/package.json +3 -3
- package/src/error-codes.ts +1 -0
- package/src/inspector.ts +8 -1
- package/src/utils/post-process.ts +57 -0
- package/src/utils/workflow/graph/serialize-workflow-graph.ts +2 -15
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,41 @@
|
|
|
1
|
+
## 0.12.56
|
|
2
|
+
|
|
3
|
+
### Patch Changes
|
|
4
|
+
|
|
5
|
+
- 7e60867: Delete exports nothing references
|
|
6
|
+
|
|
7
|
+
A sweep of the `@pikku/core` surface for exports with no consumer anywhere in the repo — no package, template, verifier or e2e project imports them: `ExtractFunctionOutput`, `CLICommandDefinition`, `RequestHeaders`, `HTTPFunctionsMeta`, `HTTPWiringMiddleware`, `JsonRpcError`, `TriggerSourceInfo`, `getMCPResources`, `getMCPPrompts`, `onGraphNodeComplete` and `InputRef`.
|
|
8
|
+
|
|
9
|
+
Every one was a compatibility promise with nothing on the other end of it. Removing them narrows what 0.13 has to keep stable.
|
|
10
|
+
|
|
11
|
+
`isRef` looked like the twelfth, and isn't. It is the type guard that reads what `createRef` writes — the `__isRef` brand marking a graph node input as "substitute another node's output here". Nothing imported it because neither it nor `RefValue` was reachable from any entry point, so the one consumer that needed it, the inspector's graph serializer, had reimplemented the same four conditions privately as `isRefValue` along with its own structural copy of `RefValue`. Deleting `isRef` would have made that duplicate permanent, with the brand's shape asserted in two places free to drift apart.
|
|
12
|
+
|
|
13
|
+
So `isRef` and `RefValue` are exported from `@pikku/core/workflow` instead, and the inspector imports them rather than keeping its own copy.
|
|
14
|
+
|
|
15
|
+
- a879ab3: **Codegen reports a schema it named but never generated (PKU463).** A named
|
|
16
|
+
contract type that is declared but not exported is imported by the virtual
|
|
17
|
+
source file the schema generator compiles, resolves to nothing, and yields no
|
|
18
|
+
schema — while the function meta still carries the name. `pikku all` exited 0
|
|
19
|
+
and the first call to that function failed in a deployment with
|
|
20
|
+
`MissingSchemaError`. The reference is now checked once addon schemas are
|
|
21
|
+
merged, since an addon supplies its own and checking earlier would report every
|
|
22
|
+
one of them as unresolved.
|
|
23
|
+
- Updated dependencies [41c1a95]
|
|
24
|
+
- Updated dependencies [ce96383]
|
|
25
|
+
- Updated dependencies [7e60867]
|
|
26
|
+
- Updated dependencies [f8f1244]
|
|
27
|
+
- Updated dependencies [dcf20cb]
|
|
28
|
+
- Updated dependencies [6512384]
|
|
29
|
+
- Updated dependencies [e3b4c14]
|
|
30
|
+
- Updated dependencies [efd0ed1]
|
|
31
|
+
- Updated dependencies [cba98fb]
|
|
32
|
+
- Updated dependencies [ce96383]
|
|
33
|
+
- Updated dependencies [f8f1244]
|
|
34
|
+
- Updated dependencies [f8f1244]
|
|
35
|
+
- Updated dependencies [6e93a35]
|
|
36
|
+
- Updated dependencies [6dada45]
|
|
37
|
+
- @pikku/core@0.12.80
|
|
38
|
+
|
|
1
39
|
## 0.12.55
|
|
2
40
|
|
|
3
41
|
### Patch Changes
|
package/dist/error-codes.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ export declare enum ErrorCode {
|
|
|
37
37
|
DB_FORM_ON_NON_STRING = "PKU484",
|
|
38
38
|
DB_DEFAULT_SCHEMA_NAME_COLLISION = "PKU485",
|
|
39
39
|
SCHEMA_GENERATION_ERROR = "PKU456",
|
|
40
|
+
SCHEMA_REFERENCE_UNRESOLVED = "PKU463",
|
|
40
41
|
INLINE_SCHEMA = "PKU489",
|
|
41
42
|
FUNCTION_METADATA_NOT_FOUND = "PKU559",
|
|
42
43
|
DUPLICATE_AUTH_DEFINITION = "PKU581",
|
package/dist/error-codes.js
CHANGED
|
@@ -42,6 +42,7 @@ export var ErrorCode;
|
|
|
42
42
|
ErrorCode["DB_DEFAULT_SCHEMA_NAME_COLLISION"] = "PKU485";
|
|
43
43
|
// Configuration errors
|
|
44
44
|
ErrorCode["SCHEMA_GENERATION_ERROR"] = "PKU456";
|
|
45
|
+
ErrorCode["SCHEMA_REFERENCE_UNRESOLVED"] = "PKU463";
|
|
45
46
|
ErrorCode["INLINE_SCHEMA"] = "PKU489";
|
|
46
47
|
// Function errors
|
|
47
48
|
ErrorCode["FUNCTION_METADATA_NOT_FOUND"] = "PKU559";
|
package/dist/inspector.js
CHANGED
|
@@ -6,12 +6,12 @@ import { TypesMap } from './types-map.js';
|
|
|
6
6
|
import { getFilesAndMethods } from './utils/get-files-and-methods.js';
|
|
7
7
|
import { findCommonAncestor } from './utils/find-root-dir.js';
|
|
8
8
|
import { createNestedProjectFilter } from './utils/nested-project-filter.js';
|
|
9
|
-
import { aggregateRequiredServices, stampAuthHandlerServices, validateAgentModels, validateAgentToolReferences, validateSecretOverrides, validateVariableOverrides, validateCredentialOverrides, validateRemoteAddonDependencies, validateRemoteAddonAuth, validateScopeReferences, validateSystemRoleScopes, validatePersonaRoles, computeResolvedIOTypes, computeMiddlewareGroupsMeta, computePermissionsGroupsMeta, computeRequiredSchemas, computeSecretBrokers, validateNoSecretAliasServices, validateSecretUsage, computeDiagnostics, validateSchemaWiringSeparation, validateScenarioServices, validateScenarioSteps, validateWorkflowGraphAddons, } from './utils/post-process.js';
|
|
9
|
+
import { aggregateRequiredServices, stampAuthHandlerServices, validateAgentModels, validateAgentToolReferences, validateSecretOverrides, validateVariableOverrides, validateCredentialOverrides, validateRemoteAddonDependencies, validateRemoteAddonAuth, validateScopeReferences, validateSystemRoleScopes, validatePersonaRoles, computeResolvedIOTypes, computeMiddlewareGroupsMeta, computePermissionsGroupsMeta, computeRequiredSchemas, computeSecretBrokers, validateNoSecretAliasServices, validateSecretUsage, computeDiagnostics, validateSchemaReferences, validateSchemaWiringSeparation, validateScenarioServices, validateScenarioSteps, validateWorkflowGraphAddons, } from './utils/post-process.js';
|
|
10
10
|
import { validateExposedFunctionsGated } from './utils/validate-exposed-functions-gated.js';
|
|
11
11
|
import { validateTagsResolveToMiddleware } from './utils/validate-tags-resolve-to-middleware.js';
|
|
12
12
|
import { annotateHttpRouteAuth } from './utils/annotate-http-route-auth.js';
|
|
13
13
|
import { generateOpenAPISpec } from './utils/serialize-openapi-json.js';
|
|
14
|
-
import { pikkuState } from '@pikku/core/
|
|
14
|
+
import { pikkuState } from '@pikku/core/ecosystem';
|
|
15
15
|
import { resolveLatestVersions } from './utils/resolve-versions.js';
|
|
16
16
|
import { finalizeWorkflows } from './utils/workflow/graph/finalize-workflows.js';
|
|
17
17
|
import { finalizeWorkflowHelperTypes, finalizeWorkflowWires, } from './utils/workflow/graph/finalize-workflow-wires.js';
|
|
@@ -336,6 +336,11 @@ export const inspect = async (logger, routeFiles, options = {}) => {
|
|
|
336
336
|
}
|
|
337
337
|
// Re-load addon schemas (generateAllSchemas replaces state.schemas)
|
|
338
338
|
await loadAddonSchemas(logger, state);
|
|
339
|
+
// After the addon merge, not before: an addon supplies its own schemas here,
|
|
340
|
+
// and checking earlier would report every one of them as unresolved.
|
|
341
|
+
if (options.schemaConfig) {
|
|
342
|
+
validateSchemaReferences(logger, state);
|
|
343
|
+
}
|
|
339
344
|
state.manifest.initial = options.manifest ?? null;
|
|
340
345
|
const contracts = extractContractsFromMeta(state.functions.meta);
|
|
341
346
|
const baseManifest = state.manifest.initial ?? createEmptyManifest();
|
|
@@ -50,6 +50,21 @@ export declare function computeResolvedIOTypes(state: InspectorState): void;
|
|
|
50
50
|
export declare function computeMiddlewareGroupsMeta(state: InspectorState): void;
|
|
51
51
|
export declare function computePermissionsGroupsMeta(state: InspectorState): void;
|
|
52
52
|
export declare function computeRequiredSchemas(state: InspectorState, options: InspectorOptions): void;
|
|
53
|
+
/**
|
|
54
|
+
* Every schema a function's contract names has to exist once codegen is done.
|
|
55
|
+
*
|
|
56
|
+
* The way it stops existing is quiet. `generateCustomTypes` hands the schema
|
|
57
|
+
* generator a virtual source file that *imports* each named contract type, so a
|
|
58
|
+
* type that is declared but never exported resolves to nothing and yields no
|
|
59
|
+
* schema — while the function's meta still carries the name. Nothing downstream
|
|
60
|
+
* reads that name until the first call, which fails with a runtime
|
|
61
|
+
* `MissingSchemaError` in a deployment rather than in the build that caused it.
|
|
62
|
+
*
|
|
63
|
+
* Reported rather than critical: the reference is only *guaranteed* to break
|
|
64
|
+
* the functions that are actually invoked, so this blocks CI through
|
|
65
|
+
* `--fail-on-error` without failing a dev server over a function nobody calls.
|
|
66
|
+
*/
|
|
67
|
+
export declare function validateSchemaReferences(logger: InspectorLogger, state: InspectorState): void;
|
|
53
68
|
export declare function validateAgentModels(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
54
69
|
/**
|
|
55
70
|
* Scenarios are pure stories of remote RPCs (same rule as client-side CLI
|
|
@@ -554,6 +554,58 @@ export function computeRequiredSchemas(state, options) {
|
|
|
554
554
|
...Array.from(schemaLookup.keys()),
|
|
555
555
|
]);
|
|
556
556
|
}
|
|
557
|
+
/**
|
|
558
|
+
* Every schema a function's contract names has to exist once codegen is done.
|
|
559
|
+
*
|
|
560
|
+
* The way it stops existing is quiet. `generateCustomTypes` hands the schema
|
|
561
|
+
* generator a virtual source file that *imports* each named contract type, so a
|
|
562
|
+
* type that is declared but never exported resolves to nothing and yields no
|
|
563
|
+
* schema — while the function's meta still carries the name. Nothing downstream
|
|
564
|
+
* reads that name until the first call, which fails with a runtime
|
|
565
|
+
* `MissingSchemaError` in a deployment rather than in the build that caused it.
|
|
566
|
+
*
|
|
567
|
+
* Reported rather than critical: the reference is only *guaranteed* to break
|
|
568
|
+
* the functions that are actually invoked, so this blocks CI through
|
|
569
|
+
* `--fail-on-error` without failing a dev server over a function nobody calls.
|
|
570
|
+
*/
|
|
571
|
+
export function validateSchemaReferences(logger, state) {
|
|
572
|
+
const { functions, schemas } = state;
|
|
573
|
+
const available = new Set(Object.keys(schemas ?? {}));
|
|
574
|
+
const unresolved = [];
|
|
575
|
+
const resolve = (typeName) => {
|
|
576
|
+
try {
|
|
577
|
+
return functions.typesMap.getUniqueName(typeName);
|
|
578
|
+
}
|
|
579
|
+
catch {
|
|
580
|
+
return typeName;
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
for (const [funcName, meta] of Object.entries(functions.meta)) {
|
|
584
|
+
for (const [role, declared] of [
|
|
585
|
+
['input', meta.inputs?.[0]],
|
|
586
|
+
['output', meta.outputs?.[0]],
|
|
587
|
+
]) {
|
|
588
|
+
if (!declared || PRIMITIVE_TYPES.has(declared))
|
|
589
|
+
continue;
|
|
590
|
+
const resolved = resolve(declared);
|
|
591
|
+
if (PRIMITIVE_TYPES.has(resolved) || available.has(resolved))
|
|
592
|
+
continue;
|
|
593
|
+
unresolved.push(`${funcName}.${role} → '${resolved}'`);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
if (unresolved.length === 0)
|
|
597
|
+
return;
|
|
598
|
+
logger.diagnostic({
|
|
599
|
+
severity: 'error',
|
|
600
|
+
code: ErrorCode.SCHEMA_REFERENCE_UNRESOLVED,
|
|
601
|
+
message: `${unresolved.length} function contract${unresolved.length === 1 ? '' : 's'} ` +
|
|
602
|
+
`name${unresolved.length === 1 ? 's' : ''} a schema that was never generated, so ` +
|
|
603
|
+
`calling ${unresolved.length === 1 ? 'it' : 'them'} fails at runtime with ` +
|
|
604
|
+
`MissingSchemaError: ${unresolved.join(', ')}. ` +
|
|
605
|
+
`The usual cause is a named type used as the function's input/output that ` +
|
|
606
|
+
`is declared but not exported — export it, or inline the type at the call site.`,
|
|
607
|
+
});
|
|
608
|
+
}
|
|
557
609
|
export function validateAgentModels(logger, state) {
|
|
558
610
|
for (const [, meta] of Object.entries(state.agents.agentsMeta)) {
|
|
559
611
|
const model = meta.model;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isRef } from '@pikku/core/workflow';
|
|
1
2
|
/**
|
|
2
3
|
* Convert a RefValue (from runtime) to DataRef (serialized)
|
|
3
4
|
*/
|
|
@@ -7,22 +8,13 @@ function convertRef(ref) {
|
|
|
7
8
|
path: ref.path,
|
|
8
9
|
};
|
|
9
10
|
}
|
|
10
|
-
/**
|
|
11
|
-
* Check if a value is a runtime RefValue
|
|
12
|
-
*/
|
|
13
|
-
function isRefValue(value) {
|
|
14
|
-
return (typeof value === 'object' &&
|
|
15
|
-
value !== null &&
|
|
16
|
-
'__isRef' in value &&
|
|
17
|
-
value.__isRef === true);
|
|
18
|
-
}
|
|
19
11
|
/**
|
|
20
12
|
* Convert input mapping from runtime format to serialized format
|
|
21
13
|
*/
|
|
22
14
|
function serializeInputMapping(input) {
|
|
23
15
|
const result = {};
|
|
24
16
|
for (const [key, value] of Object.entries(input)) {
|
|
25
|
-
if (
|
|
17
|
+
if (isRef(value)) {
|
|
26
18
|
result[key] = convertRef(value);
|
|
27
19
|
}
|
|
28
20
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikku/inspector",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.56",
|
|
4
4
|
"description": "TypeScript inspector for Pikku — discovers functions and wirings to drive code generation",
|
|
5
5
|
"author": "yasser.fadl@gmail.com",
|
|
6
6
|
"license": "BUSL-1.1",
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
"zod-to-ts": "^2.1.0"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"@pikku/core": "^0.12.
|
|
48
|
+
"@pikku/core": "^0.12.80"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@pikku/core": "^0.12.
|
|
51
|
+
"@pikku/core": "^0.12.80",
|
|
52
52
|
"@types/node": "^24.11.0"
|
|
53
53
|
},
|
|
54
54
|
"engines": {
|
package/src/error-codes.ts
CHANGED
package/src/inspector.ts
CHANGED
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
validateNoSecretAliasServices,
|
|
33
33
|
validateSecretUsage,
|
|
34
34
|
computeDiagnostics,
|
|
35
|
+
validateSchemaReferences,
|
|
35
36
|
validateSchemaWiringSeparation,
|
|
36
37
|
validateScenarioServices,
|
|
37
38
|
validateScenarioSteps,
|
|
@@ -41,7 +42,7 @@ import { validateExposedFunctionsGated } from './utils/validate-exposed-function
|
|
|
41
42
|
import { validateTagsResolveToMiddleware } from './utils/validate-tags-resolve-to-middleware.js'
|
|
42
43
|
import { annotateHttpRouteAuth } from './utils/annotate-http-route-auth.js'
|
|
43
44
|
import { generateOpenAPISpec } from './utils/serialize-openapi-json.js'
|
|
44
|
-
import { pikkuState } from '@pikku/core/
|
|
45
|
+
import { pikkuState } from '@pikku/core/ecosystem'
|
|
45
46
|
import { resolveLatestVersions } from './utils/resolve-versions.js'
|
|
46
47
|
import { finalizeWorkflows } from './utils/workflow/graph/finalize-workflows.js'
|
|
47
48
|
import {
|
|
@@ -444,6 +445,12 @@ export const inspect = async (
|
|
|
444
445
|
// Re-load addon schemas (generateAllSchemas replaces state.schemas)
|
|
445
446
|
await loadAddonSchemas(logger, state)
|
|
446
447
|
|
|
448
|
+
// After the addon merge, not before: an addon supplies its own schemas here,
|
|
449
|
+
// and checking earlier would report every one of them as unresolved.
|
|
450
|
+
if (options.schemaConfig) {
|
|
451
|
+
validateSchemaReferences(logger, state)
|
|
452
|
+
}
|
|
453
|
+
|
|
447
454
|
state.manifest.initial = options.manifest ?? null
|
|
448
455
|
const contracts = extractContractsFromMeta(state.functions.meta)
|
|
449
456
|
const baseManifest = state.manifest.initial ?? createEmptyManifest()
|
|
@@ -689,6 +689,63 @@ export function computeRequiredSchemas(
|
|
|
689
689
|
])
|
|
690
690
|
}
|
|
691
691
|
|
|
692
|
+
/**
|
|
693
|
+
* Every schema a function's contract names has to exist once codegen is done.
|
|
694
|
+
*
|
|
695
|
+
* The way it stops existing is quiet. `generateCustomTypes` hands the schema
|
|
696
|
+
* generator a virtual source file that *imports* each named contract type, so a
|
|
697
|
+
* type that is declared but never exported resolves to nothing and yields no
|
|
698
|
+
* schema — while the function's meta still carries the name. Nothing downstream
|
|
699
|
+
* reads that name until the first call, which fails with a runtime
|
|
700
|
+
* `MissingSchemaError` in a deployment rather than in the build that caused it.
|
|
701
|
+
*
|
|
702
|
+
* Reported rather than critical: the reference is only *guaranteed* to break
|
|
703
|
+
* the functions that are actually invoked, so this blocks CI through
|
|
704
|
+
* `--fail-on-error` without failing a dev server over a function nobody calls.
|
|
705
|
+
*/
|
|
706
|
+
export function validateSchemaReferences(
|
|
707
|
+
logger: InspectorLogger,
|
|
708
|
+
state: InspectorState
|
|
709
|
+
): void {
|
|
710
|
+
const { functions, schemas } = state
|
|
711
|
+
const available = new Set(Object.keys(schemas ?? {}))
|
|
712
|
+
const unresolved: string[] = []
|
|
713
|
+
|
|
714
|
+
const resolve = (typeName: string): string => {
|
|
715
|
+
try {
|
|
716
|
+
return functions.typesMap.getUniqueName(typeName)
|
|
717
|
+
} catch {
|
|
718
|
+
return typeName
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
for (const [funcName, meta] of Object.entries(functions.meta)) {
|
|
723
|
+
for (const [role, declared] of [
|
|
724
|
+
['input', meta.inputs?.[0]],
|
|
725
|
+
['output', meta.outputs?.[0]],
|
|
726
|
+
] as const) {
|
|
727
|
+
if (!declared || PRIMITIVE_TYPES.has(declared)) continue
|
|
728
|
+
const resolved = resolve(declared)
|
|
729
|
+
if (PRIMITIVE_TYPES.has(resolved) || available.has(resolved)) continue
|
|
730
|
+
unresolved.push(`${funcName}.${role} → '${resolved}'`)
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
if (unresolved.length === 0) return
|
|
735
|
+
|
|
736
|
+
logger.diagnostic({
|
|
737
|
+
severity: 'error',
|
|
738
|
+
code: ErrorCode.SCHEMA_REFERENCE_UNRESOLVED,
|
|
739
|
+
message:
|
|
740
|
+
`${unresolved.length} function contract${unresolved.length === 1 ? '' : 's'} ` +
|
|
741
|
+
`name${unresolved.length === 1 ? 's' : ''} a schema that was never generated, so ` +
|
|
742
|
+
`calling ${unresolved.length === 1 ? 'it' : 'them'} fails at runtime with ` +
|
|
743
|
+
`MissingSchemaError: ${unresolved.join(', ')}. ` +
|
|
744
|
+
`The usual cause is a named type used as the function's input/output that ` +
|
|
745
|
+
`is declared but not exported — export it, or inline the type at the call site.`,
|
|
746
|
+
})
|
|
747
|
+
}
|
|
748
|
+
|
|
692
749
|
export function validateAgentModels(
|
|
693
750
|
logger: InspectorLogger,
|
|
694
751
|
state: InspectorState | Omit<InspectorState, 'typesLookup'>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isRef } from '@pikku/core/workflow'
|
|
1
2
|
import type {
|
|
2
3
|
SerializedWorkflowGraph,
|
|
3
4
|
SerializedGraphNode,
|
|
@@ -16,20 +17,6 @@ function convertRef(ref: { nodeId: string; path?: string }): DataRef {
|
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
/**
|
|
20
|
-
* Check if a value is a runtime RefValue
|
|
21
|
-
*/
|
|
22
|
-
function isRefValue(
|
|
23
|
-
value: unknown
|
|
24
|
-
): value is { __isRef: true; nodeId: string; path?: string } {
|
|
25
|
-
return (
|
|
26
|
-
typeof value === 'object' &&
|
|
27
|
-
value !== null &&
|
|
28
|
-
'__isRef' in value &&
|
|
29
|
-
(value as any).__isRef === true
|
|
30
|
-
)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
20
|
/**
|
|
34
21
|
* Convert input mapping from runtime format to serialized format
|
|
35
22
|
*/
|
|
@@ -39,7 +26,7 @@ function serializeInputMapping(
|
|
|
39
26
|
const result: Record<string, unknown | DataRef> = {}
|
|
40
27
|
|
|
41
28
|
for (const [key, value] of Object.entries(input)) {
|
|
42
|
-
if (
|
|
29
|
+
if (isRef(value)) {
|
|
43
30
|
result[key] = convertRef(value)
|
|
44
31
|
} else {
|
|
45
32
|
result[key] = value
|