@eide/foir-cli 0.39.0 → 0.40.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/cli.js CHANGED
@@ -2785,8 +2785,14 @@ import {
2785
2785
  ListDeadLetterEntriesRequestSchema,
2786
2786
  RetryDeadLetterEntryRequestSchema,
2787
2787
  DismissDeadLetterEntryRequestSchema,
2788
- PublishOperationRequestSchema
2788
+ PublishOperationRequestSchema,
2789
+ OperationKind
2789
2790
  } from "@eide/foir-proto-ts/operations/v1/operations_pb";
2791
+ function toOperationKind(kind) {
2792
+ if (kind === "query") return OperationKind.QUERY;
2793
+ if (kind === "field") return OperationKind.FIELD;
2794
+ return OperationKind.MUTATION;
2795
+ }
2790
2796
  function createOperationsMethods(client) {
2791
2797
  return {
2792
2798
  // ── CRUD ──────────────────────────────────────────────────
@@ -2828,7 +2834,15 @@ function createOperationsMethods(client) {
2828
2834
  configId: params.configId,
2829
2835
  supportsAsync: params.supportsAsync,
2830
2836
  callbackTtlSeconds: params.callbackTtlSeconds,
2831
- capabilities: params.capabilities ?? []
2837
+ capabilities: params.capabilities ?? [],
2838
+ kind: toOperationKind(params.kind),
2839
+ attachedToModel: params.attachedToModel,
2840
+ parentFields: params.parentFields ?? [],
2841
+ cacheControl: params.cacheControl,
2842
+ secretBindings: params.secretBindings ?? [],
2843
+ requestTemplate: params.requestTemplate,
2844
+ responseTransform: params.responseTransform,
2845
+ allowInternalEndpoint: params.allowInternalEndpoint
2832
2846
  })
2833
2847
  );
2834
2848
  return resp.operation ?? null;
@@ -2850,7 +2864,15 @@ function createOperationsMethods(client) {
2850
2864
  isActive: params.isActive,
2851
2865
  supportsAsync: params.supportsAsync,
2852
2866
  callbackTtlSeconds: params.callbackTtlSeconds,
2853
- capabilities: params.capabilities
2867
+ capabilities: params.capabilities,
2868
+ kind: params.kind ? toOperationKind(params.kind) : void 0,
2869
+ attachedToModel: params.attachedToModel,
2870
+ parentFields: params.parentFields ?? [],
2871
+ cacheControl: params.cacheControl,
2872
+ secretBindings: params.secretBindings ?? [],
2873
+ requestTemplate: params.requestTemplate,
2874
+ responseTransform: params.responseTransform,
2875
+ allowInternalEndpoint: params.allowInternalEndpoint
2854
2876
  })
2855
2877
  );
2856
2878
  return resp.operation ?? null;
@@ -5339,7 +5361,16 @@ async function reconcileOperations(client, configId, operations, operationBaseUr
5339
5361
  isActive: op.isActive,
5340
5362
  supportsAsync,
5341
5363
  callbackTtlSeconds: op.callbackTtlSeconds,
5342
- capabilities
5364
+ capabilities,
5365
+ // Resolver (kind=query/field) fields — partial update on the platform.
5366
+ kind: op.kind,
5367
+ attachedToModel: op.attachedToModel,
5368
+ parentFields: op.parentFields,
5369
+ cacheControl: op.cacheControl,
5370
+ secretBindings: op.secretBindings,
5371
+ requestTemplate: op.requestTemplate,
5372
+ responseTransform: op.responseTransform,
5373
+ allowInternalEndpoint: op.allowInternalEndpoint
5343
5374
  });
5344
5375
  summary.operations.updated++;
5345
5376
  summary.updatedOperationIds.push(ex.id);
@@ -5362,7 +5393,16 @@ async function reconcileOperations(client, configId, operations, operationBaseUr
5362
5393
  configId,
5363
5394
  supportsAsync,
5364
5395
  callbackTtlSeconds: op.callbackTtlSeconds,
5365
- capabilities
5396
+ capabilities,
5397
+ // Resolver (kind=query/field) fields.
5398
+ kind: op.kind,
5399
+ attachedToModel: op.attachedToModel,
5400
+ parentFields: op.parentFields,
5401
+ cacheControl: op.cacheControl,
5402
+ secretBindings: op.secretBindings,
5403
+ requestTemplate: op.requestTemplate,
5404
+ responseTransform: op.responseTransform,
5405
+ allowInternalEndpoint: op.allowInternalEndpoint
5366
5406
  });
5367
5407
  summary.operations.created++;
5368
5408
  }
@@ -213,6 +213,67 @@ interface ApplyConfigOperationInput {
213
213
  * whose extension makes no back-channel calls.
214
214
  */
215
215
  capabilities?: string[];
216
+ /**
217
+ * How the operation surfaces in the public GraphQL schema and how it is
218
+ * dispatched. `mutation` (default) is the existing behaviour: an
219
+ * `executeXxx` root mutation dispatched via the worker queue. `query`
220
+ * registers a root Query field resolved synchronously in-process.
221
+ * `field` attaches a resolver field to `attachedToModel`, batched per
222
+ * request. QUERY/FIELD operations are the new "resolver" kind and use
223
+ * `requestTemplate` / `responseTransform` to call an upstream endpoint.
224
+ */
225
+ kind?: 'mutation' | 'query' | 'field';
226
+ /**
227
+ * Model key the resolver field attaches to. Required (and only meaningful)
228
+ * when `kind === 'field'`.
229
+ */
230
+ attachedToModel?: string;
231
+ /**
232
+ * Field path(s) under `attachedToModel` that this resolver populates.
233
+ * FIELD only.
234
+ */
235
+ parentFields?: string[];
236
+ /**
237
+ * Cache-control for QUERY / FIELD resolver results. `scope` selects the
238
+ * cache audience; `maxAge` is the freshness window in seconds.
239
+ */
240
+ cacheControl?: {
241
+ scope: 'PUBLIC' | 'PRIVATE' | 'NO_CACHE';
242
+ maxAge?: number;
243
+ };
244
+ /**
245
+ * Maps `{{secret.NAME}}` placeholders in the request template to
246
+ * PROJECT-owned secrets. The dispatcher resolves plaintext at call time;
247
+ * it is never stored on the operation row.
248
+ */
249
+ secretBindings?: Array<{
250
+ name: string;
251
+ secretRef: string;
252
+ }>;
253
+ /**
254
+ * Shapes the outbound HTTP request for QUERY / FIELD operations. Template
255
+ * variables `{{input.X}}`, `{{parent.X}}`, `{{secret.NAME}}`,
256
+ * `{{context.X}}` are interpolated at dispatch time. Set `batchCapable`
257
+ * to send one upstream request for the whole deduped input set.
258
+ */
259
+ requestTemplate?: {
260
+ method?: string;
261
+ pathTemplate?: string;
262
+ query?: Record<string, string>;
263
+ headers?: Record<string, string>;
264
+ bodyTemplate?: string;
265
+ batchCapable?: boolean;
266
+ };
267
+ /**
268
+ * jq-style transform applied to the upstream response before it is
269
+ * returned to the caller. QUERY / FIELD only.
270
+ */
271
+ responseTransform?: string;
272
+ /**
273
+ * Allow the resolver to call an internal (private-network) endpoint.
274
+ * Off by default; only meaningful for QUERY / FIELD operations.
275
+ */
276
+ allowInternalEndpoint?: boolean;
216
277
  }
217
278
  interface ApplyConfigSegmentInput {
218
279
  key: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eide/foir-cli",
3
- "version": "0.39.0",
3
+ "version": "0.40.0",
4
4
  "description": "Universal platform CLI for Foir platform",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -50,7 +50,7 @@
50
50
  "@bufbuild/protovalidate": "^1.1.1",
51
51
  "@connectrpc/connect": "^2.0.0",
52
52
  "@connectrpc/connect-node": "^2.0.0",
53
- "@eide/foir-proto-ts": "^0.90.0",
53
+ "@eide/foir-proto-ts": "^0.91.0",
54
54
  "chalk": "^5.3.0",
55
55
  "commander": "^12.1.0",
56
56
  "dotenv": "^16.4.5",