@equinor/fusion-framework-cli-plugin-ai-index 2.0.1 → 3.0.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.
Files changed (78) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/dist/esm/bin/apply-metadata.js +15 -5
  3. package/dist/esm/bin/apply-metadata.js.map +1 -1
  4. package/dist/esm/bin/apply-schema.js +64 -0
  5. package/dist/esm/bin/apply-schema.js.map +1 -0
  6. package/dist/esm/bin/apply-schema.test.js +143 -0
  7. package/dist/esm/bin/apply-schema.test.js.map +1 -0
  8. package/dist/esm/bin/delete-removed-files.js +1 -1
  9. package/dist/esm/bin/delete-removed-files.js.map +1 -1
  10. package/dist/esm/bin/embed.js +265 -55
  11. package/dist/esm/bin/embed.js.map +1 -1
  12. package/dist/esm/bin/get-diff.js +5 -0
  13. package/dist/esm/bin/get-diff.js.map +1 -1
  14. package/dist/esm/create-command.js +186 -0
  15. package/dist/esm/create-command.js.map +1 -0
  16. package/dist/esm/delete-command.js +14 -2
  17. package/dist/esm/delete-command.js.map +1 -1
  18. package/dist/esm/delete-command.options.js +7 -31
  19. package/dist/esm/delete-command.options.js.map +1 -1
  20. package/dist/esm/delete-index-command.js +94 -0
  21. package/dist/esm/delete-index-command.js.map +1 -0
  22. package/dist/esm/embed-command.js +30 -0
  23. package/dist/esm/embed-command.js.map +1 -0
  24. package/dist/esm/embeddings-command.js +14 -17
  25. package/dist/esm/embeddings-command.js.map +1 -1
  26. package/dist/esm/embeddings-command.options.js +12 -43
  27. package/dist/esm/embeddings-command.options.js.map +1 -1
  28. package/dist/esm/index.js +12 -3
  29. package/dist/esm/index.js.map +1 -1
  30. package/dist/esm/schema.js +41 -0
  31. package/dist/esm/schema.js.map +1 -0
  32. package/dist/esm/search-command.js +17 -5
  33. package/dist/esm/search-command.js.map +1 -1
  34. package/dist/esm/utils/embedding-dimensions.js +37 -0
  35. package/dist/esm/utils/embedding-dimensions.js.map +1 -0
  36. package/dist/esm/utils/zod-to-azure-fields.js +120 -0
  37. package/dist/esm/utils/zod-to-azure-fields.js.map +1 -0
  38. package/dist/esm/utils/zod-to-azure-fields.test.js +112 -0
  39. package/dist/esm/utils/zod-to-azure-fields.test.js.map +1 -0
  40. package/dist/esm/version.js +1 -1
  41. package/dist/tsconfig.tsbuildinfo +1 -1
  42. package/dist/types/bin/apply-metadata.d.ts +2 -1
  43. package/dist/types/bin/apply-schema.d.ts +22 -0
  44. package/dist/types/bin/apply-schema.test.d.ts +1 -0
  45. package/dist/types/config.d.ts +14 -0
  46. package/dist/types/create-command.d.ts +6 -0
  47. package/dist/types/delete-command.options.d.ts +10 -23
  48. package/dist/types/delete-index-command.d.ts +6 -0
  49. package/dist/types/embed-command.d.ts +12 -0
  50. package/dist/types/embeddings-command.options.d.ts +10 -28
  51. package/dist/types/index.d.ts +1 -0
  52. package/dist/types/schema.d.ts +137 -0
  53. package/dist/types/utils/embedding-dimensions.d.ts +13 -0
  54. package/dist/types/utils/zod-to-azure-fields.d.ts +61 -0
  55. package/dist/types/utils/zod-to-azure-fields.test.d.ts +1 -0
  56. package/dist/types/version.d.ts +1 -1
  57. package/package.json +5 -5
  58. package/src/bin/apply-metadata.ts +20 -4
  59. package/src/bin/apply-schema.test.ts +170 -0
  60. package/src/bin/apply-schema.ts +86 -0
  61. package/src/bin/delete-removed-files.ts +1 -1
  62. package/src/bin/embed.ts +325 -77
  63. package/src/bin/get-diff.ts +5 -0
  64. package/src/config.ts +15 -0
  65. package/src/create-command.ts +218 -0
  66. package/src/delete-command.options.ts +7 -37
  67. package/src/delete-command.ts +19 -2
  68. package/src/delete-index-command.ts +121 -0
  69. package/src/embed-command.ts +44 -0
  70. package/src/embeddings-command.options.ts +12 -50
  71. package/src/embeddings-command.ts +18 -18
  72. package/src/index.ts +12 -3
  73. package/src/schema.ts +149 -0
  74. package/src/search-command.ts +22 -5
  75. package/src/utils/embedding-dimensions.ts +39 -0
  76. package/src/utils/zod-to-azure-fields.test.ts +136 -0
  77. package/src/utils/zod-to-azure-fields.ts +177 -0
  78. package/src/version.ts +1 -1
@@ -0,0 +1,186 @@
1
+ import { createCommand, createOption } from 'commander';
2
+ import { loadFusionAIConfig, setupFramework } from '@equinor/fusion-framework-cli-plugin-ai-base';
3
+ import { withOptions as withAiOptions, } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
4
+ import { zodToAzureFields } from './utils/zod-to-azure-fields.js';
5
+ import { resolveEmbeddingDimensions } from './utils/embedding-dimensions.js';
6
+ /**
7
+ * CLI command: `ai index create`
8
+ *
9
+ * Generate and preview the Azure AI Search index schema derived from the
10
+ * Zod-based schema definition in the fusion-ai config.
11
+ *
12
+ * Reads the `index.schema` configuration, converts the Zod shape into
13
+ * Azure AI Search field definitions, and combines them with the base
14
+ * fields (`id`, `content`, `content_vector`, `metadata`) to produce
15
+ * the full index schema.
16
+ *
17
+ * Usage:
18
+ * $ ffc ai index create [options]
19
+ *
20
+ * Options:
21
+ * --config <config> Path to a config file (default: fusion-ai.config)
22
+ * --dry-run Preview the schema without creating the index
23
+ *
24
+ * Examples:
25
+ * $ ffc ai index create --dry-run
26
+ * $ ffc ai index create --config fusion-ai.config.eds.ts --dry-run
27
+ */
28
+ const _command = createCommand('create')
29
+ .description('Create an Azure AI Search index from the config schema definition')
30
+ .addOption(createOption('--config <config>', 'Path to a config file').default('fusion-ai.config'))
31
+ .addOption(createOption('--dry-run', 'Preview the index schema without creating it').default(false))
32
+ .action(async function (commandOptions) {
33
+ const config = await loadFusionAIConfig(commandOptions.config, {
34
+ baseDir: process.cwd(),
35
+ });
36
+ const indexConfig = config.index;
37
+ if (!indexConfig?.schema) {
38
+ console.error('❌ No schema defined in config. Add a `schema` property to `index` using defineIndexSchema().');
39
+ process.exit(1);
40
+ }
41
+ // Resolve index name from config
42
+ const indexName = indexConfig.name;
43
+ if (!indexName) {
44
+ console.error('❌ Index name is required. Set `name` in the index config.');
45
+ process.exit(1);
46
+ }
47
+ // Convert Zod shape to Azure AI Search field definitions
48
+ const schemaFields = zodToAzureFields(indexConfig.schema.shape);
49
+ // Guard against schema fields that collide with reserved base-schema names
50
+ const reservedFieldNames = ['id', 'content', 'content_vector', 'metadata'];
51
+ const conflictingSchemaFields = schemaFields
52
+ .map((field) => field.name)
53
+ .filter((name) => reservedFieldNames.includes(name));
54
+ if (conflictingSchemaFields.length > 0) {
55
+ const conflicts = [...new Set(conflictingSchemaFields)].sort().join(', ');
56
+ console.error(`❌ Schema fields use reserved names: ${conflicts}. Reserved field names are: ${reservedFieldNames.join(', ')}. Rename these fields in \`index.schema\`.`);
57
+ process.exit(1);
58
+ }
59
+ // Resolve embedding vector dimensions from the model name or explicit config
60
+ const model = indexConfig.model ?? 'text-embedding-3-large';
61
+ let dimensions;
62
+ try {
63
+ dimensions = resolveEmbeddingDimensions(model, indexConfig.embedding?.dimensions);
64
+ }
65
+ catch (error) {
66
+ console.error(`❌ ${error instanceof Error ? error.message : String(error)}`);
67
+ process.exit(1);
68
+ }
69
+ // Base Azure AI Search fields that every index requires
70
+ const baseFields = [
71
+ {
72
+ name: 'id',
73
+ type: 'Edm.String',
74
+ key: true,
75
+ filterable: true,
76
+ sortable: false,
77
+ facetable: false,
78
+ searchable: false,
79
+ },
80
+ {
81
+ name: 'content',
82
+ type: 'Edm.String',
83
+ filterable: false,
84
+ sortable: false,
85
+ facetable: false,
86
+ searchable: true,
87
+ },
88
+ {
89
+ name: 'content_vector',
90
+ type: 'Collection(Edm.Single)',
91
+ filterable: false,
92
+ sortable: false,
93
+ facetable: false,
94
+ searchable: true,
95
+ dimensions,
96
+ vectorSearchProfile: 'default-vector-profile',
97
+ },
98
+ {
99
+ name: 'metadata',
100
+ type: 'Edm.ComplexType',
101
+ fields: [
102
+ {
103
+ name: 'source',
104
+ type: 'Edm.String',
105
+ filterable: true,
106
+ sortable: false,
107
+ facetable: false,
108
+ searchable: false,
109
+ },
110
+ {
111
+ name: 'attributes',
112
+ type: 'Collection(Edm.ComplexType)',
113
+ fields: [
114
+ {
115
+ name: 'key',
116
+ type: 'Edm.String',
117
+ filterable: true,
118
+ sortable: false,
119
+ facetable: false,
120
+ searchable: false,
121
+ },
122
+ {
123
+ name: 'value',
124
+ type: 'Edm.String',
125
+ filterable: true,
126
+ sortable: false,
127
+ facetable: true,
128
+ searchable: false,
129
+ },
130
+ ],
131
+ },
132
+ ],
133
+ },
134
+ ];
135
+ const fullSchema = {
136
+ name: indexName,
137
+ fields: [...baseFields, ...schemaFields],
138
+ vectorSearch: {
139
+ algorithms: [{ name: 'default-hnsw', kind: 'hnsw' }],
140
+ profiles: [
141
+ {
142
+ name: 'default-vector-profile',
143
+ algorithm: 'default-hnsw',
144
+ },
145
+ ],
146
+ },
147
+ };
148
+ if (commandOptions.dryRun) {
149
+ console.log('📋 Index schema preview (dry-run):');
150
+ console.log(JSON.stringify(fullSchema, null, 2));
151
+ console.log(`\n✅ Schema has ${baseFields.length} base fields + ${schemaFields.length} promoted fields`);
152
+ process.exit(0);
153
+ }
154
+ // Create or update the index via the Fusion AI proxy
155
+ const framework = await setupFramework(commandOptions);
156
+ const service = await framework.serviceDiscovery.resolveService('ai');
157
+ const baseUri = service.uri.replace(/\/+$/, '');
158
+ const scopes = service.scopes ?? service.defaultScopes ?? [];
159
+ const token = await framework.auth.acquireAccessToken({ request: { scopes } });
160
+ if (!token) {
161
+ console.error('❌ Failed to acquire access token for the AI service.');
162
+ process.exit(1);
163
+ }
164
+ const url = `${baseUri}/indexes/${encodeURIComponent(indexName)}?api-version=2024-07-01`;
165
+ const response = await fetch(url, {
166
+ method: 'PUT',
167
+ headers: {
168
+ 'Content-Type': 'application/json',
169
+ Authorization: `Bearer ${token}`,
170
+ },
171
+ body: JSON.stringify(fullSchema),
172
+ });
173
+ if (!response.ok) {
174
+ const body = await response.text();
175
+ console.error(`❌ Index creation failed (${response.status} ${response.statusText})`);
176
+ console.error(body);
177
+ process.exit(1);
178
+ }
179
+ console.log(`✅ Index "${indexName}" created/updated successfully.`);
180
+ });
181
+ /**
182
+ * The `ai index create` command with inherited AI base options for
183
+ * authentication and service discovery.
184
+ */
185
+ export const createIndexCommand = withAiOptions(_command);
186
+ //# sourceMappingURL=create-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-command.js","sourceRoot":"","sources":["../../src/create-command.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { createCommand, createOption } from 'commander';
2
- import { setupFramework } from '@equinor/fusion-framework-cli-plugin-ai-base';
2
+ import { loadFusionAIConfig, setupFramework } from '@equinor/fusion-framework-cli-plugin-ai-base';
3
3
  import { withOptions as withAiOptions } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
4
4
  import { DeleteOptionsSchema } from './delete-command.options.js';
5
5
  /**
@@ -55,9 +55,21 @@ function buildFilter(sources, rawFilter) {
55
55
  */
56
56
  const _command = createCommand('remove')
57
57
  .description('Remove documents from the search index by source path or OData filter')
58
+ .addOption(createOption('--config <config>', 'Path to a config file').default('fusion-ai.config'))
58
59
  .addOption(createOption('--dry-run', 'Preview matching documents without deleting them').default(false))
59
60
  .addOption(createOption('--filter <expression>', 'Raw OData filter expression for selecting documents to delete'))
60
61
  .argument('[source-paths...]', 'Relative file paths whose indexed chunks should be removed')
62
+ .hook('preAction', async (thisCommand) => {
63
+ const opts = thisCommand.opts();
64
+ const config = await loadFusionAIConfig(opts.config ?? 'fusion-ai.config', { baseDir: process.cwd() });
65
+ const indexConfig = config.index ?? {};
66
+ if (indexConfig.name && !opts.indexName?.trim()) {
67
+ thisCommand.setOptionValue('indexName', indexConfig.name);
68
+ }
69
+ if (indexConfig.model && !opts.embedModel?.trim()) {
70
+ thisCommand.setOptionValue('embedModel', indexConfig.model);
71
+ }
72
+ })
61
73
  .action(async (sources, commandOptions) => {
62
74
  const options = await DeleteOptionsSchema.parseAsync(commandOptions);
63
75
  const filterExpression = buildFilter(sources, options.filter);
@@ -79,7 +91,7 @@ const _command = createCommand('remove')
79
91
  return;
80
92
  }
81
93
  const framework = await setupFramework(options);
82
- const vectorStoreService = framework.ai.getService('search', options.azureSearchIndexName);
94
+ const vectorStoreService = framework.ai.useIndex(options.indexName);
83
95
  await vectorStoreService.deleteDocuments({
84
96
  filter: { filterExpression },
85
97
  });
@@ -1 +1 @@
1
- {"version":3,"file":"delete-command.js","sourceRoot":"","sources":["../../src/delete-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAExD,OAAO,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AAC9E,OAAO,EAAE,WAAW,IAAI,aAAa,EAAE,MAAM,8DAA8D,CAAC;AAE5G,OAAO,EAAE,mBAAmB,EAAsB,MAAM,6BAA6B,CAAC;AAEtF;;;;;;;;;;;GAWG;AACH,SAAS,WAAW,CAAC,OAAiB,EAAE,SAAkB;IACxD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;KACrC,WAAW,CAAC,uEAAuE,CAAC;KACpF,SAAS,CACR,YAAY,CAAC,WAAW,EAAE,kDAAkD,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAC7F;KACA,SAAS,CACR,YAAY,CACV,uBAAuB,EACvB,+DAA+D,CAChE,CACF;KACA,QAAQ,CAAC,mBAAmB,EAAE,4DAA4D,CAAC;KAC3F,MAAM,CAAC,KAAK,EAAE,OAAiB,EAAE,cAA6B,EAAE,EAAE;IACjE,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IACrE,MAAM,gBAAgB,GAAG,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAE9D,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,0FAA0F,CAC3F,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,eAAe,OAAO,CAAC,MAAM,oBAAoB,CAAC,CAAC;QAC/D,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,aAAa,gBAAgB,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,yBAAyB,gBAAgB,EAAE,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,kBAAkB,GAAG,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC3F,MAAM,kBAAkB,CAAC,eAAe,CAAC;QACvC,MAAM,EAAE,EAAE,gBAAgB,EAAE;KAC7B,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;AACrD,CAAC,CAAC,CAAC;AAEL;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC,QAAQ,EAAE;IACnD,gBAAgB,EAAE,IAAI;IACtB,aAAa,EAAE,IAAI;CACpB,CAAC,CAAC"}
1
+ {"version":3,"file":"delete-command.js","sourceRoot":"","sources":["../../src/delete-command.ts"],"names":[],"mappings":"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"}
@@ -1,42 +1,18 @@
1
1
  import { z } from 'zod';
2
2
  import { AiOptionsSchema } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
3
3
  /**
4
- * Zod schema for validating options of the `ai index remove` command.
4
+ * Zod schema for the `ai index remove` command.
5
5
  *
6
- * Extends the base AI options schema ({@link AiOptionsSchema}) to require
7
- * Azure Search credentials and the embedding deployment (needed to initialise
8
- * the vector store service for document removal).
9
- *
10
- * @example
11
- * ```ts
12
- * const validated = await DeleteOptionsSchema.parseAsync(rawOptions);
13
- * // validated.dryRun, validated.filter, validated.azureSearchEndpoint, etc.
14
- * ```
6
+ * Extends the base AI options schema making `indexName` required.
15
7
  */
16
8
  export const DeleteOptionsSchema = AiOptionsSchema.extend({
17
- openaiEmbeddingDeployment: z
18
- .string({ message: 'Embedding deployment name is required to initialise the vector store.' })
19
- .min(1, 'Embedding deployment name must be a non-empty string.')
20
- .describe('Azure OpenAI embedding deployment name'),
21
- azureSearchEndpoint: z
22
- .string({ message: 'Azure Search endpoint is required for deletion.' })
23
- .url('Azure Search endpoint must be a valid URL.')
24
- .min(1, 'Azure Search endpoint must be a non-empty string.')
25
- .describe('Azure Search endpoint URL'),
26
- azureSearchApiKey: z
27
- .string({ message: 'Azure Search API key is required for deletion.' })
28
- .min(1, 'Azure Search API key must be a non-empty string.')
29
- .describe('Azure Search API key'),
30
- azureSearchIndexName: z
31
- .string({ message: 'Azure Search index name is required for deletion.' })
32
- .min(1, 'Azure Search index name must be a non-empty string.')
33
- .describe('Azure Search index name'),
34
- dryRun: z
35
- .boolean({ message: 'dryRun must be a boolean value.' })
36
- .describe('Preview what would be deleted without making changes'),
9
+ indexName: z
10
+ .string({ message: 'Index name is required for deletion.' })
11
+ .min(1, 'Index name must be a non-empty string.'),
12
+ dryRun: z.boolean().describe('Preview what would be deleted without making changes'),
37
13
  filter: z
38
14
  .string()
39
- .min(1, 'Filter expression must be a non-empty string.')
15
+ .min(1)
40
16
  .optional()
41
17
  .describe('Raw OData filter expression for selecting documents to delete'),
42
18
  }).describe('Command options for the delete command');
@@ -1 +1 @@
1
- {"version":3,"file":"delete-command.options.js","sourceRoot":"","sources":["../../src/delete-command.options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,eAAe,EAAE,MAAM,8DAA8D,CAAC;AAE/F;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAC,MAAM,CAAC;IACxD,yBAAyB,EAAE,CAAC;SACzB,MAAM,CAAC,EAAE,OAAO,EAAE,uEAAuE,EAAE,CAAC;SAC5F,GAAG,CAAC,CAAC,EAAE,uDAAuD,CAAC;SAC/D,QAAQ,CAAC,wCAAwC,CAAC;IACrD,mBAAmB,EAAE,CAAC;SACnB,MAAM,CAAC,EAAE,OAAO,EAAE,iDAAiD,EAAE,CAAC;SACtE,GAAG,CAAC,4CAA4C,CAAC;SACjD,GAAG,CAAC,CAAC,EAAE,mDAAmD,CAAC;SAC3D,QAAQ,CAAC,2BAA2B,CAAC;IACxC,iBAAiB,EAAE,CAAC;SACjB,MAAM,CAAC,EAAE,OAAO,EAAE,gDAAgD,EAAE,CAAC;SACrE,GAAG,CAAC,CAAC,EAAE,kDAAkD,CAAC;SAC1D,QAAQ,CAAC,sBAAsB,CAAC;IACnC,oBAAoB,EAAE,CAAC;SACpB,MAAM,CAAC,EAAE,OAAO,EAAE,mDAAmD,EAAE,CAAC;SACxE,GAAG,CAAC,CAAC,EAAE,qDAAqD,CAAC;SAC7D,QAAQ,CAAC,yBAAyB,CAAC;IACtC,MAAM,EAAE,CAAC;SACN,OAAO,CAAC,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC;SACvD,QAAQ,CAAC,sDAAsD,CAAC;IACnE,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,EAAE,+CAA+C,CAAC;SACvD,QAAQ,EAAE;SACV,QAAQ,CAAC,+DAA+D,CAAC;CAC7E,CAAC,CAAC,QAAQ,CAAC,wCAAwC,CAAC,CAAC"}
1
+ {"version":3,"file":"delete-command.options.js","sourceRoot":"","sources":["../../src/delete-command.options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,8DAA8D,CAAC;AAE/F;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAC,MAAM,CAAC;IACxD,SAAS,EAAE,CAAC;SACT,MAAM,CAAC,EAAE,OAAO,EAAE,sCAAsC,EAAE,CAAC;SAC3D,GAAG,CAAC,CAAC,EAAE,wCAAwC,CAAC;IACnD,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,sDAAsD,CAAC;IACpF,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,EAAE;SACV,QAAQ,CAAC,+DAA+D,CAAC;CAC7E,CAAC,CAAC,QAAQ,CAAC,wCAAwC,CAAC,CAAC"}
@@ -0,0 +1,94 @@
1
+ import { createCommand, createOption } from 'commander';
2
+ import { loadFusionAIConfig, setupFramework } from '@equinor/fusion-framework-cli-plugin-ai-base';
3
+ import { withOptions as withAiOptions, } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
4
+ /**
5
+ * CLI command: `ai index delete`
6
+ *
7
+ * Permanently deletes an Azure AI Search index and all its documents.
8
+ *
9
+ * This operation is irreversible — once deleted, the index definition and all
10
+ * indexed documents are permanently removed. Requires `Fusion.AI.Search.Manage`
11
+ * with a matching `index-name` scope, or the `Fusion.AI.Admin` role.
12
+ *
13
+ * Usage:
14
+ * $ ffc ai index delete [options]
15
+ *
16
+ * Options:
17
+ * --name <name> Index name to delete (overrides config)
18
+ * --config <config> Path to a config file (default: fusion-ai.config)
19
+ * --yes Skip the confirmation prompt
20
+ *
21
+ * Examples:
22
+ * $ ffc ai index delete
23
+ * $ ffc ai index delete --name my-index --yes
24
+ * $ ffc ai index delete --config fusion-ai.config.eds.ts
25
+ */
26
+ const _command = createCommand('delete')
27
+ .description('Permanently delete an Azure AI Search index and all its documents')
28
+ .addOption(createOption('--name <name>', 'Index name to delete (overrides config)'))
29
+ .addOption(createOption('--config <config>', 'Path to a config file').default('fusion-ai.config'))
30
+ .addOption(createOption('--yes', 'Skip the confirmation prompt').default(false))
31
+ .hook('preAction', async (thisCommand) => {
32
+ const opts = thisCommand.opts();
33
+ const config = await loadFusionAIConfig(opts.config ?? 'fusion-ai.config', { baseDir: process.cwd() });
34
+ const indexConfig = config.index ?? {};
35
+ // --name flag takes priority, then fall back to config
36
+ if (!opts.name?.trim() && indexConfig.name) {
37
+ thisCommand.setOptionValue('name', indexConfig.name);
38
+ }
39
+ })
40
+ .action(async function (commandOptions) {
41
+ const indexName = commandOptions.name?.trim();
42
+ if (!indexName) {
43
+ console.error('❌ Index name is required. Set `name` in the index config or pass --name.');
44
+ process.exit(1);
45
+ }
46
+ console.log(`\n🗑️ Target index: ${indexName}`);
47
+ // Guard against accidental deletion — require explicit confirmation
48
+ if (!commandOptions.yes) {
49
+ const { createInterface } = await import('node:readline');
50
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
51
+ const answer = await new Promise((resolve) => {
52
+ rl.question(`\n⚠️ This will permanently delete index "${indexName}" and ALL its documents.\n Type the index name to confirm: `, resolve);
53
+ });
54
+ rl.close();
55
+ if (answer.trim() !== indexName) {
56
+ console.log('❌ Confirmation did not match. Aborting.');
57
+ process.exit(1);
58
+ }
59
+ }
60
+ const framework = await setupFramework(commandOptions);
61
+ const service = await framework.serviceDiscovery.resolveService('ai');
62
+ const baseUri = service.uri.replace(/\/+$/, '');
63
+ const scopes = service.scopes ?? service.defaultScopes ?? [];
64
+ const token = await framework.auth.acquireAccessToken({ request: { scopes } });
65
+ if (!token) {
66
+ console.error('❌ Failed to acquire access token for the AI service.');
67
+ process.exit(1);
68
+ }
69
+ const url = `${baseUri}/indexes/${encodeURIComponent(indexName)}?api-version=2024-07-01`;
70
+ const response = await fetch(url, {
71
+ method: 'DELETE',
72
+ headers: {
73
+ Authorization: `Bearer ${token}`,
74
+ },
75
+ });
76
+ // 204 No Content = successful deletion, 404 = index doesn't exist
77
+ if (response.status === 404) {
78
+ console.error(`❌ Index "${indexName}" not found.`);
79
+ process.exit(1);
80
+ }
81
+ if (!response.ok) {
82
+ const body = await response.text();
83
+ console.error(`❌ Index deletion failed (${response.status} ${response.statusText})`);
84
+ console.error(body);
85
+ process.exit(1);
86
+ }
87
+ console.log(`✅ Index "${indexName}" deleted successfully.`);
88
+ });
89
+ /**
90
+ * The `ai index delete` command with inherited AI base options for
91
+ * authentication and service discovery.
92
+ */
93
+ export const deleteIndexCommand = withAiOptions(_command);
94
+ //# sourceMappingURL=delete-index-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-index-command.js","sourceRoot":"","sources":["../../src/delete-index-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { createCommand } from 'commander';
2
+ import { setupFramework } from '@equinor/fusion-framework-cli-plugin-ai-base';
3
+ import { withOptions as withAiOptions, } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
4
+ /**
5
+ * CLI command: `ai index embed <text>`
6
+ *
7
+ * Embeds a single text string and prints the resulting vector.
8
+ * Useful for verifying the embeddings endpoint and model are reachable.
9
+ *
10
+ * @example
11
+ * ```sh
12
+ * ffc ai index embed "hello world"
13
+ * ```
14
+ */
15
+ export const embedCommand = withAiOptions(createCommand('embed')
16
+ .description('Embed a text string and print the resulting vector (for testing)')
17
+ .argument('<text>', 'Text to embed')
18
+ .action(async (text, options) => {
19
+ const framework = await setupFramework(options);
20
+ const embedder = framework.ai.useEmbed(options.embedModel);
21
+ console.log(`Embedding model: ${options.embedModel ?? 'default'}`);
22
+ console.log(`Input: ${JSON.stringify(text)}`);
23
+ const vector = await embedder.embedQuery(text);
24
+ console.log(`Dimensions: ${vector.length}`);
25
+ console.log(`Vector (first 8): [${vector
26
+ .slice(0, 8)
27
+ .map((v) => v.toFixed(6))
28
+ .join(', ')}, ...]`);
29
+ }), { includeEmbedding: true });
30
+ //# sourceMappingURL=embed-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embed-command.js","sourceRoot":"","sources":["../../src/embed-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AAC9E,OAAO,EACL,WAAW,IAAI,aAAa,GAE7B,MAAM,8DAA8D,CAAC;AAItE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CACvC,aAAa,CAAC,OAAO,CAAC;KACnB,WAAW,CAAC,kEAAkE,CAAC;KAC/E,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;KACnC,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,OAAuB,EAAE,EAAE;IACtD,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAE3D,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,CAAC,UAAU,IAAI,SAAS,EAAE,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAE9C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAE/C,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CACT,sBAAsB,MAAM;SACzB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;SACxB,IAAI,CAAC,IAAI,CAAC,QAAQ,CACtB,CAAC;AACJ,CAAC,CAAC,EACJ,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAC3B,CAAC"}
@@ -45,27 +45,24 @@ const _command = createCommand('add')
45
45
  .addOption(createOption('--base-ref <ref>', 'Git reference to compare against').default('HEAD~1'))
46
46
  .addOption(createOption('--clean', 'Delete all existing documents from the vector store before processing').default(false))
47
47
  .argument('[glob-patterns...]', 'Glob patterns to match files (optional when using --diff)')
48
+ .hook('preAction', async (thisCommand) => {
49
+ // Load config early so index name and embed model are available
50
+ // before the withOptions validation hook fires.
51
+ const opts = thisCommand.opts();
52
+ const config = await loadFusionAIConfig(opts.config ?? 'fusion-ai.config', { baseDir: process.cwd() });
53
+ const indexConfig = config.index ?? {};
54
+ if (indexConfig.name && !opts.indexName?.trim()) {
55
+ thisCommand.setOptionValue('indexName', indexConfig.name);
56
+ }
57
+ if (indexConfig.model && !opts.embedModel?.trim()) {
58
+ thisCommand.setOptionValue('embedModel', indexConfig.model);
59
+ }
60
+ })
48
61
  .action(async function (patterns, commandOptions) {
49
- // Load configuration before validation so config values can fill gaps
62
+ // Config was already loaded in preAction; reload here for embed() usage.
50
63
  const preOptions = commandOptions;
51
64
  const config = await loadFusionAIConfig(preOptions.config ?? 'fusion-ai.config', { baseDir: process.cwd() });
52
65
  const indexConfig = config.index ?? {};
53
- // Config file values override env-var defaults but not explicit CLI flags.
54
- // Commander merges env vars before the action runs, so we use
55
- // getOptionValueSource to distinguish "user passed --flag" from "came from env".
56
- const parentCommand = this.parent ?? this;
57
- if (indexConfig.name) {
58
- const source = parentCommand.getOptionValueSource('azureSearchIndexName');
59
- if (source !== 'cli') {
60
- preOptions.azureSearchIndexName = indexConfig.name;
61
- }
62
- }
63
- if (indexConfig.model) {
64
- const source = parentCommand.getOptionValueSource('openaiEmbeddingDeployment');
65
- if (source !== 'cli') {
66
- preOptions.openaiEmbeddingDeployment = indexConfig.model;
67
- }
68
- }
69
66
  const options = await CommandOptionsSchema.parseAsync(preOptions);
70
67
  // CLI args take precedence over config patterns
71
68
  const allowedFilePatterns = indexConfig.patterns ?? ['**/*.ts', '**/*.md', '**/*.mdx'];
@@ -1 +1 @@
1
- {"version":3,"file":"embeddings-command.js","sourceRoot":"","sources":["../../src/embeddings-command.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"embeddings-command.js","sourceRoot":"","sources":["../../src/embeddings-command.ts"],"names":[],"mappings":"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"}
@@ -1,55 +1,24 @@
1
1
  import { z } from 'zod';
2
2
  import { AiOptionsSchema } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
3
3
  /**
4
- * Zod schema for validating command options for the `ai index add` command.
4
+ * Zod schema for the `ai index add` command.
5
5
  *
6
- * Extends the base AI options schema ({@link AiOptionsSchema}) with
7
- * add-specific options such as `--dry-run`, `--diff`, `--config`,
8
- * `--base-ref`, and `--clean`.
9
- *
10
- * Azure Search and embedding options that are optional in the base schema
11
- * become **required** because the add command always writes to a
12
- * vector store.
13
- *
14
- * @example
15
- * ```ts
16
- * const validated = await CommandOptionsSchema.parseAsync(rawOptions);
17
- * // validated.dryRun, validated.azureSearchEndpoint, etc.
18
- * ```
6
+ * Extends the base AI options schema making `embedModel` and `indexName` required.
19
7
  */
20
8
  export const CommandOptionsSchema = AiOptionsSchema.extend({
21
- // Override optional AI options to make them required for embeddings command
22
- openaiEmbeddingDeployment: z
23
- .string({ message: 'Embedding deployment name is required for embeddings command.' })
24
- .min(1, 'Embedding deployment name must be a non-empty string.')
25
- .describe('Azure OpenAI embedding deployment name'),
26
- azureSearchEndpoint: z
27
- .string({ message: 'Azure Search endpoint is required for embeddings command.' })
28
- .url('Azure Search endpoint must be a valid URL.')
29
- .min(1, 'Azure Search endpoint must be a non-empty string.')
30
- .describe('Azure Search endpoint URL'),
31
- azureSearchApiKey: z
32
- .string({ message: 'Azure Search API key is required for embeddings command.' })
33
- .min(1, 'Azure Search API key must be a non-empty string.')
34
- .describe('Azure Search API key'),
35
- azureSearchIndexName: z
36
- .string({ message: 'Azure Search index name is required for embeddings command.' })
37
- .min(1, 'Azure Search index name must be a non-empty string.')
38
- .describe('Azure Search index name'),
9
+ embedModel: z
10
+ .string({ message: 'Embedding model name is required for the index add command.' })
11
+ .min(1, 'Embedding model name must be a non-empty string.'),
12
+ indexName: z
13
+ .string({ message: 'Index name is required for the index add command.' })
14
+ .min(1, 'Index name must be a non-empty string.'),
39
15
  // Embeddings-specific options
40
- dryRun: z
41
- .boolean({ message: 'dryRun must be a boolean value.' })
42
- .describe('Show what would be processed without actually doing it'),
43
- config: z
44
- .string({ message: 'Config file path is required and must be a non-empty string.' })
45
- .min(1, 'Config file path must be a non-empty string.')
46
- .describe('Path to a config file'),
47
- diff: z
48
- .boolean({ message: 'diff must be a boolean value.' })
49
- .describe('Process only changed files (workflow mode)'),
16
+ dryRun: z.boolean().describe('Show what would be processed without actually doing it'),
17
+ config: z.string().min(1).describe('Path to a config file'),
18
+ diff: z.boolean().describe('Process only changed files (workflow mode)'),
50
19
  baseRef: z.string().min(1).optional().describe('Git reference to compare against'),
51
20
  clean: z
52
- .boolean({ message: 'clean must be a boolean value.' })
21
+ .boolean()
53
22
  .describe('Delete all existing documents from the vector store before processing'),
54
23
  }).describe('Command options for the embeddings command');
55
24
  //# sourceMappingURL=embeddings-command.options.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"embeddings-command.options.js","sourceRoot":"","sources":["../../src/embeddings-command.options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,eAAe,EAAE,MAAM,8DAA8D,CAAC;AAE/F;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC,MAAM,CAAC;IACzD,4EAA4E;IAC5E,yBAAyB,EAAE,CAAC;SACzB,MAAM,CAAC,EAAE,OAAO,EAAE,+DAA+D,EAAE,CAAC;SACpF,GAAG,CAAC,CAAC,EAAE,uDAAuD,CAAC;SAC/D,QAAQ,CAAC,wCAAwC,CAAC;IACrD,mBAAmB,EAAE,CAAC;SACnB,MAAM,CAAC,EAAE,OAAO,EAAE,2DAA2D,EAAE,CAAC;SAChF,GAAG,CAAC,4CAA4C,CAAC;SACjD,GAAG,CAAC,CAAC,EAAE,mDAAmD,CAAC;SAC3D,QAAQ,CAAC,2BAA2B,CAAC;IACxC,iBAAiB,EAAE,CAAC;SACjB,MAAM,CAAC,EAAE,OAAO,EAAE,0DAA0D,EAAE,CAAC;SAC/E,GAAG,CAAC,CAAC,EAAE,kDAAkD,CAAC;SAC1D,QAAQ,CAAC,sBAAsB,CAAC;IACnC,oBAAoB,EAAE,CAAC;SACpB,MAAM,CAAC,EAAE,OAAO,EAAE,6DAA6D,EAAE,CAAC;SAClF,GAAG,CAAC,CAAC,EAAE,qDAAqD,CAAC;SAC7D,QAAQ,CAAC,yBAAyB,CAAC;IAEtC,8BAA8B;IAC9B,MAAM,EAAE,CAAC;SACN,OAAO,CAAC,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC;SACvD,QAAQ,CAAC,wDAAwD,CAAC;IACrE,MAAM,EAAE,CAAC;SACN,MAAM,CAAC,EAAE,OAAO,EAAE,8DAA8D,EAAE,CAAC;SACnF,GAAG,CAAC,CAAC,EAAE,8CAA8C,CAAC;SACtD,QAAQ,CAAC,uBAAuB,CAAC;IACpC,IAAI,EAAE,CAAC;SACJ,OAAO,CAAC,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC;SACrD,QAAQ,CAAC,4CAA4C,CAAC;IACzD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;IAClF,KAAK,EAAE,CAAC;SACL,OAAO,CAAC,EAAE,OAAO,EAAE,gCAAgC,EAAE,CAAC;SACtD,QAAQ,CAAC,uEAAuE,CAAC;CACrF,CAAC,CAAC,QAAQ,CAAC,4CAA4C,CAAC,CAAC"}
1
+ {"version":3,"file":"embeddings-command.options.js","sourceRoot":"","sources":["../../src/embeddings-command.options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,8DAA8D,CAAC;AAE/F;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC,MAAM,CAAC;IACzD,UAAU,EAAE,CAAC;SACV,MAAM,CAAC,EAAE,OAAO,EAAE,6DAA6D,EAAE,CAAC;SAClF,GAAG,CAAC,CAAC,EAAE,kDAAkD,CAAC;IAC7D,SAAS,EAAE,CAAC;SACT,MAAM,CAAC,EAAE,OAAO,EAAE,mDAAmD,EAAE,CAAC;SACxE,GAAG,CAAC,CAAC,EAAE,wCAAwC,CAAC;IAEnD,8BAA8B;IAC9B,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,wDAAwD,CAAC;IACtF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC;IAC3D,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;IACxE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;IAClF,KAAK,EAAE,CAAC;SACL,OAAO,EAAE;SACT,QAAQ,CAAC,uEAAuE,CAAC;CACrF,CAAC,CAAC,QAAQ,CAAC,4CAA4C,CAAC,CAAC"}
package/dist/esm/index.js CHANGED
@@ -3,19 +3,28 @@ import { registerAiPlugin as registerAiPluginBase } from '@equinor/fusion-framew
3
3
  import { command as addCommand } from './embeddings-command.js';
4
4
  import { deleteCommand as removeCommand } from './delete-command.js';
5
5
  import { searchCommand } from './search-command.js';
6
+ import { embedCommand } from './embed-command.js';
7
+ import { createIndexCommand } from './create-command.js';
8
+ import { deleteIndexCommand } from './delete-index-command.js';
9
+ export { defineIndexSchema } from './schema.js';
6
10
  /**
7
11
  * Parent command for the `ai index` group.
8
12
  *
9
- * Owns three subcommands:
13
+ * Owns subcommands:
10
14
  * - `add` — index documents into the Azure AI Search vector store.
11
15
  * - `remove` — remove documents from the vector store.
12
16
  * - `search` — query the vector store for indexed documents.
17
+ * - `create` — create an index from the config schema definition.
18
+ * - `delete` — permanently delete an index and all its documents.
13
19
  */
14
20
  const indexCommand = createCommand('index')
15
- .description('Manage the AI search index (add, search, remove)')
21
+ .description('Manage the AI search index (add, search, remove, create, delete)')
16
22
  .addCommand(addCommand)
17
23
  .addCommand(removeCommand)
18
- .addCommand(searchCommand);
24
+ .addCommand(searchCommand)
25
+ .addCommand(embedCommand)
26
+ .addCommand(createIndexCommand)
27
+ .addCommand(deleteIndexCommand);
19
28
  /**
20
29
  * Registers the `ai index` command with the Fusion Framework CLI.
21
30
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,gBAAgB,IAAI,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AACxG,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,aAAa,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIpD;;;;;;;GAOG;AACH,MAAM,YAAY,GAAG,aAAa,CAAC,OAAO,CAAC;KACxC,WAAW,CAAC,kDAAkD,CAAC;KAC/D,UAAU,CAAC,UAAU,CAAC;KACtB,UAAU,CAAC,aAAa,CAAC;KACzB,UAAU,CAAC,aAAa,CAAC,CAAC;AAE7B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,oBAAoB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AAC9C,CAAC;AAED,eAAe,gBAAgB,CAAC;AAEhC,6CAA6C;AAC7C,OAAO,EACL,iBAAiB,GAElB,MAAM,8CAA8C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,gBAAgB,IAAI,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AACxG,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,aAAa,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAG/D,OAAO,EAAE,iBAAiB,EAAqB,MAAM,aAAa,CAAC;AAEnE;;;;;;;;;GASG;AACH,MAAM,YAAY,GAAG,aAAa,CAAC,OAAO,CAAC;KACxC,WAAW,CAAC,kEAAkE,CAAC;KAC/E,UAAU,CAAC,UAAU,CAAC;KACtB,UAAU,CAAC,aAAa,CAAC;KACzB,UAAU,CAAC,aAAa,CAAC;KACzB,UAAU,CAAC,YAAY,CAAC;KACxB,UAAU,CAAC,kBAAkB,CAAC;KAC9B,UAAU,CAAC,kBAAkB,CAAC,CAAC;AAElC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,oBAAoB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AAC9C,CAAC;AAED,eAAe,gBAAgB,CAAC;AAEhC,6CAA6C;AAC7C,OAAO,EACL,iBAAiB,GAElB,MAAM,8CAA8C,CAAC"}