@eide/foir-cli 0.1.24 → 0.1.26

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
File without changes
@@ -1 +1 @@
1
- {"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../src/commands/extensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAatD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,aAAa,GAC9B,IAAI,CAoGN"}
1
+ {"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../src/commands/extensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AActD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,aAAa,GAC9B,IAAI,CAkKN"}
@@ -2,7 +2,7 @@ import { withErrorHandler } from '../lib/errors.js';
2
2
  import { createClient } from '../lib/client.js';
3
3
  import { formatOutput, formatList, success } from '../lib/output.js';
4
4
  import { parseInputData, isUUID } from '../lib/input.js';
5
- import { ListExtensionsDocument, GetExtensionDocument, GetExtensionByKeyDocument, RegisterExtensionDocument, TriggerExtensionSyncDocument, } from '../graphql/generated.js';
5
+ import { ListExtensionsDocument, GetExtensionDocument, GetExtensionByKeyDocument, RegisterExtensionDocument, TriggerExtensionSyncDocument, InstallExtensionDocument, } from '../graphql/generated.js';
6
6
  export function registerExtensionsCommands(program, globalOpts) {
7
7
  const extensions = program
8
8
  .command('extensions')
@@ -73,6 +73,58 @@ export function registerExtensionsCommands(program, globalOpts) {
73
73
  if (!(opts.json || opts.jsonl || opts.quiet))
74
74
  success(`Registered extension ${data.registerExtension.key}`);
75
75
  }));
76
+ // install
77
+ extensions
78
+ .command('install')
79
+ .description('Install (or update) an extension with full provisioning')
80
+ .option('-d, --data <json>', 'Extension manifest as JSON')
81
+ .option('-f, --file <path>', 'Read manifest from file (.ts, .js, or .json)')
82
+ .option('-k, --key <key>', 'Extension key (overrides manifest)')
83
+ .addHelpText('after', `
84
+ Examples:
85
+ $ foir extensions install -f install.config.ts
86
+ $ foir extensions install -f install.json
87
+ $ foir extensions install -d '{"key":"my-ext","name":"My Extension",...}'
88
+ `)
89
+ .action(withErrorHandler(globalOpts, async (cmdOpts) => {
90
+ const opts = globalOpts();
91
+ const client = await createClient(opts);
92
+ const input = await parseInputData(cmdOpts);
93
+ // Allow --key to override the manifest key
94
+ if (cmdOpts.key) {
95
+ input.key = cmdOpts.key;
96
+ }
97
+ const data = await client.request(InstallExtensionDocument, { input });
98
+ const result = data.installExtension;
99
+ if (opts.json || opts.jsonl || opts.quiet) {
100
+ formatOutput(result, opts);
101
+ return;
102
+ }
103
+ if (result.isUpdate) {
104
+ success(`Updated extension "${result.extensionKey}"`);
105
+ console.log('');
106
+ console.log(` Models: ${result.modelsCreated} created, ${result.modelsUpdated} updated`);
107
+ console.log(` Operations: ${result.operationsCreated} created, ${result.operationsUpdated} updated`);
108
+ console.log(` Extension: ${result.extensionId}`);
109
+ }
110
+ else {
111
+ success(`Installed extension "${result.extensionKey}"`);
112
+ console.log('');
113
+ console.log(` Models: ${result.modelsCreated} created`);
114
+ console.log(` Operations: ${result.operationsCreated} created`);
115
+ console.log(` Extension: ${result.extensionId}`);
116
+ if (result.credentials) {
117
+ console.log('');
118
+ console.log(' ┌─────────────────────────────────────────────────┐');
119
+ console.log(' │ CREDENTIALS (save these — shown only once!) │');
120
+ console.log(' ├─────────────────────────────────────────────────┤');
121
+ console.log(` │ API Key: ${result.credentials.platformApiKey}`);
122
+ console.log(` │ Editor Key: ${result.credentials.platformEditorKey}`);
123
+ console.log(` │ Webhook: ${result.credentials.webhookSecret}`);
124
+ console.log(' └─────────────────────────────────────────────────┘');
125
+ }
126
+ }
127
+ }));
76
128
  // sync
77
129
  extensions
78
130
  .command('sync <id>')
@@ -1832,6 +1832,86 @@ export type HookFilterInput = {
1832
1832
  export type ImageFit = 'CONTAIN' | 'COVER' | 'FILL';
1833
1833
  /** Image format options for CDN transforms */
1834
1834
  export type ImageFormat = 'AVIF' | 'JPEG' | 'PNG' | 'WEBP';
1835
+ export type InstallExtensionAuthProviderInput = {
1836
+ captureMetadata?: InputMaybe<Scalars['Boolean']['input']>;
1837
+ config: Scalars['JSON']['input'];
1838
+ enabled?: InputMaybe<Scalars['Boolean']['input']>;
1839
+ isDefault?: InputMaybe<Scalars['Boolean']['input']>;
1840
+ key: Scalars['String']['input'];
1841
+ name: Scalars['String']['input'];
1842
+ priority?: InputMaybe<Scalars['Int']['input']>;
1843
+ type: Scalars['String']['input'];
1844
+ verifyExternalCustomer?: InputMaybe<Scalars['Boolean']['input']>;
1845
+ };
1846
+ export type InstallExtensionCredentials = {
1847
+ platformApiKey: Scalars['String']['output'];
1848
+ platformEditorKey: Scalars['String']['output'];
1849
+ webhookSecret: Scalars['String']['output'];
1850
+ };
1851
+ export type InstallExtensionCustomerProfileSchemaInput = {
1852
+ fields: Scalars['JSON']['input'];
1853
+ publicFields?: InputMaybe<Array<Scalars['String']['input']>>;
1854
+ };
1855
+ /** Full extension provisioning input — one manifest, full setup. */
1856
+ export type InstallExtensionInput = {
1857
+ authProviders?: InputMaybe<Array<InstallExtensionAuthProviderInput>>;
1858
+ config?: InputMaybe<Scalars['JSON']['input']>;
1859
+ connectionDomain?: InputMaybe<Scalars['String']['input']>;
1860
+ credentials?: InputMaybe<Scalars['JSON']['input']>;
1861
+ customerProfileSchema?: InputMaybe<InstallExtensionCustomerProfileSchemaInput>;
1862
+ description?: InputMaybe<Scalars['String']['input']>;
1863
+ direction?: InputMaybe<Scalars['String']['input']>;
1864
+ extensionType?: InputMaybe<Scalars['String']['input']>;
1865
+ key: Scalars['String']['input'];
1866
+ models?: InputMaybe<Array<InstallExtensionModelInput>>;
1867
+ name: Scalars['String']['input'];
1868
+ /** Base URL prepended to relative operation endpoints */
1869
+ operationBaseUrl?: InputMaybe<Scalars['String']['input']>;
1870
+ operations?: InputMaybe<Array<InstallExtensionOperationInput>>;
1871
+ placements?: InputMaybe<Array<InstallExtensionPlacementInput>>;
1872
+ };
1873
+ export type InstallExtensionModelInput = {
1874
+ category?: InputMaybe<Scalars['String']['input']>;
1875
+ config?: InputMaybe<Scalars['JSON']['input']>;
1876
+ description?: InputMaybe<Scalars['String']['input']>;
1877
+ fields?: InputMaybe<Scalars['JSON']['input']>;
1878
+ hooks?: InputMaybe<Scalars['JSON']['input']>;
1879
+ icon?: InputMaybe<Scalars['String']['input']>;
1880
+ key: Scalars['String']['input'];
1881
+ name: Scalars['String']['input'];
1882
+ pluralName?: InputMaybe<Scalars['String']['input']>;
1883
+ };
1884
+ export type InstallExtensionOperationInput = {
1885
+ category?: InputMaybe<Scalars['String']['input']>;
1886
+ description?: InputMaybe<Scalars['String']['input']>;
1887
+ endpoint: Scalars['String']['input'];
1888
+ key: Scalars['String']['input'];
1889
+ name: Scalars['String']['input'];
1890
+ retryPolicy?: InputMaybe<Scalars['JSON']['input']>;
1891
+ timeoutMs?: InputMaybe<Scalars['Int']['input']>;
1892
+ touchPoints?: InputMaybe<Array<Scalars['String']['input']>>;
1893
+ };
1894
+ export type InstallExtensionPlacementInput = {
1895
+ allowedOrigin?: InputMaybe<Scalars['String']['input']>;
1896
+ height?: InputMaybe<Scalars['String']['input']>;
1897
+ hideContentTab?: InputMaybe<Scalars['Boolean']['input']>;
1898
+ modelKeys?: InputMaybe<Array<Scalars['String']['input']>>;
1899
+ tabName?: InputMaybe<Scalars['String']['input']>;
1900
+ type: Scalars['String']['input'];
1901
+ url: Scalars['String']['input'];
1902
+ };
1903
+ /** Result of installExtension mutation */
1904
+ export type InstallExtensionResult = {
1905
+ /** Credentials returned on first install only. Null on updates. */
1906
+ credentials?: Maybe<InstallExtensionCredentials>;
1907
+ extensionId: Scalars['ID']['output'];
1908
+ extensionKey: Scalars['String']['output'];
1909
+ isUpdate: Scalars['Boolean']['output'];
1910
+ modelsCreated: Scalars['Int']['output'];
1911
+ modelsUpdated: Scalars['Int']['output'];
1912
+ operationsCreated: Scalars['Int']['output'];
1913
+ operationsUpdated: Scalars['Int']['output'];
1914
+ };
1835
1915
  /** An invitation to join a tenant or project */
1836
1916
  export type Invitation = {
1837
1917
  /** When the invitation was accepted (if accepted) */
@@ -2218,6 +2298,13 @@ export type Mutation = {
2218
2298
  generateAvatarUploadUrl: AvatarUploadUrl;
2219
2299
  /** Grant access to a tenant/project for an admin user */
2220
2300
  grantAdminAccess: AdminUserAccess;
2301
+ /**
2302
+ * Install (or update) an extension with full provisioning:
2303
+ * models, operations, API keys, webhook secret, auth providers, customer profile schema.
2304
+ * First call creates the extension and returns credentials.
2305
+ * Subsequent calls update models/operations without regenerating credentials.
2306
+ */
2307
+ installExtension: InstallExtensionResult;
2221
2308
  login: LoginResponse;
2222
2309
  loginOTP: LoginResponse;
2223
2310
  logout: SuccessResponse;
@@ -2782,6 +2869,9 @@ export type MutationGrantAdminAccessArgs = {
2782
2869
  adminUserId: Scalars['ID']['input'];
2783
2870
  input: GrantAccessInput;
2784
2871
  };
2872
+ export type MutationInstallExtensionArgs = {
2873
+ input: InstallExtensionInput;
2874
+ };
2785
2875
  export type MutationLoginArgs = {
2786
2876
  email: Scalars['String']['input'];
2787
2877
  password: Scalars['String']['input'];
@@ -6548,6 +6638,25 @@ export type TriggerExtensionSyncMutation = {
6548
6638
  results?: unknown | null;
6549
6639
  };
6550
6640
  };
6641
+ export type InstallExtensionMutationVariables = Exact<{
6642
+ input: InstallExtensionInput;
6643
+ }>;
6644
+ export type InstallExtensionMutation = {
6645
+ installExtension: {
6646
+ extensionId: string;
6647
+ extensionKey: string;
6648
+ modelsCreated: number;
6649
+ modelsUpdated: number;
6650
+ operationsCreated: number;
6651
+ operationsUpdated: number;
6652
+ isUpdate: boolean;
6653
+ credentials?: {
6654
+ platformApiKey: string;
6655
+ platformEditorKey: string;
6656
+ webhookSecret: string;
6657
+ } | null;
6658
+ };
6659
+ };
6551
6660
  export type ListFilesQueryVariables = Exact<{
6552
6661
  folder?: InputMaybe<Scalars['String']['input']>;
6553
6662
  mimeType?: InputMaybe<Scalars['String']['input']>;
@@ -8041,6 +8150,7 @@ export declare const GetExtensionDocument: DocumentNode<GetExtensionQuery, GetEx
8041
8150
  export declare const GetExtensionByKeyDocument: DocumentNode<GetExtensionByKeyQuery, GetExtensionByKeyQueryVariables>;
8042
8151
  export declare const RegisterExtensionDocument: DocumentNode<RegisterExtensionMutation, RegisterExtensionMutationVariables>;
8043
8152
  export declare const TriggerExtensionSyncDocument: DocumentNode<TriggerExtensionSyncMutation, TriggerExtensionSyncMutationVariables>;
8153
+ export declare const InstallExtensionDocument: DocumentNode<InstallExtensionMutation, InstallExtensionMutationVariables>;
8044
8154
  export declare const ListFilesDocument: DocumentNode<ListFilesQuery, ListFilesQueryVariables>;
8045
8155
  export declare const GetFileDocument: DocumentNode<GetFileQuery, GetFileQueryVariables>;
8046
8156
  export declare const FileStorageUsageDocument: DocumentNode<FileStorageUsageQuery, FileStorageUsageQueryVariables>;