@redocly/realm 0.129.0-next.5 → 0.129.0-next.6

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 (31) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/constants/common.d.ts +1 -0
  3. package/dist/constants/common.js +1 -1
  4. package/dist/server/plugins/catalog-entities/database/constants/relation-normalization.d.ts +3 -0
  5. package/dist/server/plugins/catalog-entities/database/constants/relation-normalization.js +1 -0
  6. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-relation-db-record-from-dto.js +1 -1
  7. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-relation-db-record-from-file-schema.js +1 -1
  8. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-bff-repository.d.ts +14 -0
  9. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-bff-repository.js +112 -0
  10. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.js +12 -130
  11. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.js +1 -1
  12. package/dist/server/plugins/catalog-entities/utils/normalize-relation.d.ts +77 -0
  13. package/dist/server/plugins/catalog-entities/utils/normalize-relation.js +1 -0
  14. package/dist/server/plugins/config-parser/format-error.js +13 -5
  15. package/dist/server/plugins/config-parser/loaders/utils/read-and-validate-config.js +1 -1
  16. package/dist/server/providers/database/databases/catalog-sqlite/migrations/0003_catalog_versions_and_revisions_relations.sql +12 -6
  17. package/dist/server/providers/database/databases/catalog-sqlite/migrations/0004_normalize_relation_types.sql +147 -0
  18. package/dist/server/providers/database/databases/catalog-sqlite/migrations/meta/0004_snapshot.json +392 -0
  19. package/dist/server/providers/database/databases/catalog-sqlite/migrations/meta/_journal.json +7 -0
  20. package/dist/server/providers/database/databases/sqld-sqlite/migrations/0006_catalog-versions-and-revisions-relations.sql +12 -6
  21. package/dist/server/providers/database/pagination/filter.d.ts +1 -0
  22. package/dist/server/providers/database/pagination/filter.js +1 -1
  23. package/dist/server/web-server/auth.js +2 -2
  24. package/dist/server/web-server/routes/auth.d.ts +1 -0
  25. package/dist/server/web-server/routes/auth.js +1 -1
  26. package/dist/server/web-server/routes/index.js +1 -1
  27. package/dist/server/web-server/routes/mcp-oauth.d.ts +10 -0
  28. package/dist/server/web-server/routes/mcp-oauth.js +1 -1
  29. package/dist/server/web-server/utils/get-request-origin.d.ts +3 -0
  30. package/dist/server/web-server/utils/get-request-origin.js +1 -0
  31. package/package.json +2 -2
@@ -1 +1 @@
1
- import h from"path";import{lintConfig as C,loadConfig as P,createConfigTypes as T}from"@redocly/openapi-core";import{deepMerge as b}from"../../../../../utils/object/deep-merge.js";import{readEnvVariable as R}from"../../../../utils/envs/read-env-variable.js";import{logger as a}from"../../../../tools/notifiers/logger.js";import{safeParsePartial as A}from"../../safe-parse.js";import{formatConfigProblem as x}from"../../format-error.js";import{ExternalResolver as E}from"../../../../fs/utils/external-ref-resolver.js";import{resolveMutuallyExclusiveProps as $}from"../../resolve-mutual-exclusion.js";async function W(o,r,t,c){const u=r.getFileInfo(o)?.realRelativePath||o;async function y(){const i=new E(r),l=h.join(r.cwd,u),n=await P({configPath:l,externalRefResolver:i}),f=await c(n.resolvedConfig);if(f===void 0)return n.resolvedConfig;const g=[...n.document?.source?await C({config:n,externalConfigTypes:T(f,n)}):[],...n.document?.source?$(n.resolvedConfig,n.document?.source):[]];if(g.length>0)for(const w of g)t(new Error(x(w,r.cwd)));return n.resolvedConfig}const s=await r.exists(o)?await y():{},v=j(s),p=await c(s);"residency"in s&&s.residency&&typeof s.residency=="string"&&(/^https?:\/\/.*/.test(s.residency)||t(new Error(`Invalid residency URL: "${s.residency}". Residency must start with "http://" or "https://".`)));let d=p?A(p,s):s;const{env:m}=d;if(m){const i=R("REDOCLY_ENV")||"development",l=m[i]||{};d=b(d,l)}const e=M(d,v);if(e.imports&&e.imports.length>0){a.warn("The 'imports' property is deprecated. Please use 'plugins' property instead.");const i=new Set([...e.plugins||[],...e.imports.map(l=>h.posix.join(l,"plugin.js"))]);e.plugins=Array.from(i),delete e.imports}if(e.catalog&&(a.warn("The 'catalog' property is deprecated. Please use 'catalogClassic' property instead."),e.catalogClassic={...e.catalog},delete e.catalog),e.scorecard&&(a.warn("The 'scorecard' property is deprecated. Please use 'scorecardClassic' property instead."),e.scorecardClassic=e.scorecard,delete e.scorecard),e.search?.ai){a.warn("The 'search.ai' property is deprecated. Please use 'aiAssistant' property instead.");const i={...e.search?.ai,...e.aiAssistant,suggestions:e.aiAssistant?.suggestions?.length?e.aiAssistant.suggestions:e.search?.ai.suggestions||[]};e.aiAssistant=i,delete e.search.ai}return e}function j(o){if(!o.theme)return[];a.warn("The 'theme' property in redocly.yaml is deprecated. Please move all of the properties from 'theme' to the root of the config.");const r=[];for(const t of Object.keys(o.theme))o[t]==null?r.push(t):a.warn(`Detected both '${t}' and 'theme.${t}' properties in redocly.yaml. The 'theme.${t}' property will be ignored and needs to be removed or merged into the '${t}'.`);return r}function M(o,r){if(!o.theme||r.length===0)return o;const t={...o};for(const c of r)t[c]=o.theme[c];return delete t.theme,t}export{W as readAndValidateConfig};
1
+ import w from"path";import{lintConfig as R,loadConfig as C,createConfigTypes as T}from"@redocly/openapi-core";import{deepMerge as U}from"../../../../../utils/object/deep-merge.js";import{readEnvVariable as A}from"../../../../utils/envs/read-env-variable.js";import{logger as l}from"../../../../tools/notifiers/logger.js";import{safeParsePartial as L}from"../../safe-parse.js";import{formatConfigProblem as $}from"../../format-error.js";import{ExternalResolver as q}from"../../../../fs/utils/external-ref-resolver.js";import{resolveMutuallyExclusiveProps as x}from"../../resolve-mutual-exclusion.js";function f(o,e,t,r){e in o&&o[e]&&typeof o[e]=="string"&&(/^https?:\/\/.*/.test(o[e])||r(new Error(`Invalid ${t} URL: "${o[e]}". ${t} must start with "http://" or "https://".`)))}function j(o,e){if("access"in o&&o.access&&typeof o.access=="object"){const t=o.access;f(t,"logoutReturnUrl","access.logoutReturnUrl",e),f(t,"residency","access.residency",e);const r=["requiresLogin","logoutReturnUrl","residency","sso","rbac"];for(const n of r)n in t&&t[n]!==void 0&&n in o&&o[n]!==void 0&&e(new Error(`Property '${n}' is defined both at root level and in 'access' object. Please use 'access.${n}' to define this configuration.`))}}async function z(o,e,t,r){const m=e.getFileInfo(o)?.realRelativePath||o;async function d(){const c=new q(e),u=w.join(e.cwd,m),i=await C({configPath:u,externalRefResolver:c}),y=await r(i.resolvedConfig);if(y===void 0)return i.resolvedConfig;const v=[...i.document?.source?await R({config:i,externalConfigTypes:T(y,i)}):[],...i.document?.source?x(i.resolvedConfig,i.document?.source):[]];if(v.length>0)for(const b of v)t(new Error($(b,e.cwd)));return i.resolvedConfig}const a=await e.exists(o)?await d():{},P=E(a),g=await r(a);f(a,"residency","Residency",t),f(a,"logoutReturnUrl","Logout return URL",t),j(a,t);let p=g?L(g,a):a;const{env:h}=p;if(h){const c=A("REDOCLY_ENV")||"development",u=h[c]||{};p=U(p,u)}const s=M(p,P);if(s.imports&&s.imports.length>0){l.warn("The 'imports' property is deprecated. Please use 'plugins' property instead.");const c=new Set([...s.plugins||[],...s.imports.map(u=>w.posix.join(u,"plugin.js"))]);s.plugins=Array.from(c),delete s.imports}if(s.catalog&&(l.warn("The 'catalog' property is deprecated. Please use 'catalogClassic' property instead."),s.catalogClassic={...s.catalog},delete s.catalog),s.scorecard&&(l.warn("The 'scorecard' property is deprecated. Please use 'scorecardClassic' property instead."),s.scorecardClassic=s.scorecard,delete s.scorecard),s.search?.ai){l.warn("The 'search.ai' property is deprecated. Please use 'aiAssistant' property instead.");const c={...s.search?.ai,...s.aiAssistant,suggestions:s.aiAssistant?.suggestions?.length?s.aiAssistant.suggestions:s.search?.ai.suggestions||[]};s.aiAssistant=c,delete s.search.ai}return k(s)}function k(o){const e="access"in o?o.access:void 0;if(!e||typeof e!="object")return o;const t={...o},r=[{name:"requiresLogin",type:"boolean"},{name:"logoutReturnUrl",type:"string"},{name:"residency",type:"string"},{name:"sso",type:"string | string[]"},{name:"rbac",type:"object"}],n=[];for(const m of r){const d=m.name;d in t&&t[d]!==void 0&&!(d in e)&&n.push(d)}return n.length>0&&l.warn(`The following properties at root level are deprecated: ${n.join(", ")}. Please move them to the 'access' object.`),"requiresLogin"in e&&e.requiresLogin!==void 0&&(t.requiresLogin=e.requiresLogin),"logoutReturnUrl"in e&&e.logoutReturnUrl!==void 0&&(t.logoutReturnUrl=e.logoutReturnUrl),"residency"in e&&e.residency!==void 0&&(t.residency=e.residency),"sso"in e&&e.sso!==void 0&&(t.sso=e.sso),"rbac"in e&&e.rbac!==void 0&&(t.rbac=e.rbac),delete t.access,t}function E(o){if(!o.theme)return[];l.warn("The 'theme' property in redocly.yaml is deprecated. Please move all of the properties from 'theme' to the root of the config.");const e=[];for(const t of Object.keys(o.theme))o[t]==null?e.push(t):l.warn(`Detected both '${t}' and 'theme.${t}' properties in redocly.yaml. The 'theme.${t}' property will be ignored and needs to be removed or merged into the '${t}'.`);return e}function M(o,e){if(!o.theme||e.length===0)return o;const t={...o};for(const r of e)t[r]=o.theme[r];return delete t.theme,t}export{z as readAndValidateConfig};
@@ -9,9 +9,21 @@ DROP INDEX IF EXISTS `idx_entities_key_source_created_at`;--> statement-breakpoi
9
9
  DROP INDEX IF EXISTS `idx_entities_key_source_is_current`;--> statement-breakpoint
10
10
  DROP INDEX IF EXISTS `idx_entities_key_source_is_default`;--> statement-breakpoint
11
11
  DROP INDEX IF EXISTS `idx_entities_key_source`;--> statement-breakpoint
12
+ -- Update all NULL values to '' first before creating unique index
12
13
  UPDATE `entities_relations` SET "source_version" = '' WHERE "source_version" IS NULL;--> statement-breakpoint
14
+ UPDATE `entities_relations` SET "source_revision" = '' WHERE "source_revision" IS NULL;--> statement-breakpoint
15
+ UPDATE `entities_relations` SET "target_version" = '' WHERE "target_version" IS NULL;--> statement-breakpoint
16
+ UPDATE `entities_relations` SET "target_revision" = '' WHERE "target_revision" IS NULL;--> statement-breakpoint
17
+ -- Delete duplicate relations keeping only the most recent one (by id)
18
+ DELETE FROM `entities_relations` WHERE `id` NOT IN (
19
+ SELECT MAX(`id`) FROM `entities_relations`
20
+ GROUP BY `source_key`, `target_key`, `source_version`, `target_version`, `source_revision`, `target_revision`
21
+ );--> statement-breakpoint
13
22
  -- We need to set default value to '', because NULL is not unique in sqlite
14
23
  ALTER TABLE `entities_relations` ALTER COLUMN "source_version" TO "source_version" text NOT NULL DEFAULT '';--> statement-breakpoint
24
+ ALTER TABLE `entities_relations` ALTER COLUMN "source_revision" TO "source_revision" text NOT NULL DEFAULT '';--> statement-breakpoint
25
+ ALTER TABLE `entities_relations` ALTER COLUMN "target_version" TO "target_version" text NOT NULL DEFAULT '';--> statement-breakpoint
26
+ ALTER TABLE `entities_relations` ALTER COLUMN "target_revision" TO "target_revision" text NOT NULL DEFAULT '';--> statement-breakpoint
15
27
  ALTER TABLE `entities_relations` ADD `is_deleted` integer DEFAULT false;--> statement-breakpoint
16
28
  CREATE INDEX `idx_entities_relations_source_key` ON `entities_relations` (`source_key`,`is_deleted`);--> statement-breakpoint
17
29
  CREATE INDEX `idx_entities_relations_target_key` ON `entities_relations` (`target_key`,`is_deleted`);--> statement-breakpoint
@@ -25,12 +37,6 @@ ALTER TABLE `entities` ADD `is_deleted` integer DEFAULT false;--> statement-brea
25
37
  CREATE INDEX `idx_entities_key_source_is_current` ON `entities` (`key`,`is_current`,`is_deleted`);--> statement-breakpoint
26
38
  CREATE INDEX `idx_entities_key_source_is_default` ON `entities` (`key`,`is_default_version`);--> statement-breakpoint
27
39
  CREATE UNIQUE INDEX `idx_entities_key_source` ON `entities` (`key`,`source`,`revision`,`version`);--> statement-breakpoint
28
- UPDATE `entities_relations` SET "source_revision" = '' WHERE "source_revision" IS NULL;--> statement-breakpoint
29
- ALTER TABLE `entities_relations` ALTER COLUMN "source_revision" TO "source_revision" text NOT NULL DEFAULT '';--> statement-breakpoint
30
- UPDATE `entities_relations` SET "target_version" = '' WHERE "target_version" IS NULL;--> statement-breakpoint
31
- ALTER TABLE `entities_relations` ALTER COLUMN "target_version" TO "target_version" text NOT NULL DEFAULT '';--> statement-breakpoint
32
- UPDATE `entities_relations` SET "target_revision" = '' WHERE "target_revision" IS NULL;--> statement-breakpoint
33
- ALTER TABLE `entities_relations` ALTER COLUMN "target_revision" TO "target_revision" text NOT NULL DEFAULT '';--> statement-breakpoint
34
40
  ALTER TABLE `entities_relations` DROP COLUMN `source_id`;--> statement-breakpoint
35
41
  ALTER TABLE `entities_relations` DROP COLUMN `target_id`;--> statement-breakpoint
36
42
  DROP INDEX IF EXISTS `idx_entities_key_source_is_current`;--> statement-breakpoint
@@ -0,0 +1,147 @@
1
+ -- Migration: Normalize relation types to canonical forms
2
+ -- This migration transforms bidirectional relation types to their canonical forms
3
+ -- by swapping source and target entities where needed.
4
+
5
+ -- Normalize ownedBy -> owns (swap source and target)
6
+ UPDATE `entities_relations`
7
+ SET
8
+ source_key = target_key,
9
+ target_key = source_key,
10
+ source_version = target_version,
11
+ target_version = source_version,
12
+ source_revision = target_revision,
13
+ target_revision = source_revision,
14
+ source_to_target_relation = 'owns',
15
+ target_to_source_relation = 'reverse:owns'
16
+ WHERE source_to_target_relation = 'ownedBy';--> statement-breakpoint
17
+
18
+ -- Normalize partOf -> hasParts (swap source and target)
19
+ UPDATE `entities_relations`
20
+ SET
21
+ source_key = target_key,
22
+ target_key = source_key,
23
+ source_version = target_version,
24
+ target_version = source_version,
25
+ source_revision = target_revision,
26
+ target_revision = source_revision,
27
+ source_to_target_relation = 'hasParts',
28
+ target_to_source_relation = 'reverse:hasParts'
29
+ WHERE source_to_target_relation = 'partOf';--> statement-breakpoint
30
+
31
+ -- Normalize createdBy -> creates (swap source and target)
32
+ UPDATE `entities_relations`
33
+ SET
34
+ source_key = target_key,
35
+ target_key = source_key,
36
+ source_version = target_version,
37
+ target_version = source_version,
38
+ source_revision = target_revision,
39
+ target_revision = source_revision,
40
+ source_to_target_relation = 'creates',
41
+ target_to_source_relation = 'reverse:creates'
42
+ WHERE source_to_target_relation = 'createdBy';--> statement-breakpoint
43
+
44
+ -- Normalize implementedBy -> implements (swap source and target)
45
+ UPDATE `entities_relations`
46
+ SET
47
+ source_key = target_key,
48
+ target_key = source_key,
49
+ source_version = target_version,
50
+ target_version = source_version,
51
+ source_revision = target_revision,
52
+ target_revision = source_revision,
53
+ source_to_target_relation = 'implements',
54
+ target_to_source_relation = 'reverse:implements'
55
+ WHERE source_to_target_relation = 'implementedBy';--> statement-breakpoint
56
+
57
+ -- Normalize dependencyOf -> dependsOn (swap source and target)
58
+ UPDATE `entities_relations`
59
+ SET
60
+ source_key = target_key,
61
+ target_key = source_key,
62
+ source_version = target_version,
63
+ target_version = source_version,
64
+ source_revision = target_revision,
65
+ target_revision = source_revision,
66
+ source_to_target_relation = 'dependsOn',
67
+ target_to_source_relation = 'reverse:dependsOn'
68
+ WHERE source_to_target_relation = 'dependencyOf';--> statement-breakpoint
69
+
70
+ -- Normalize usedBy -> uses (swap source and target)
71
+ UPDATE `entities_relations`
72
+ SET
73
+ source_key = target_key,
74
+ target_key = source_key,
75
+ source_version = target_version,
76
+ target_version = source_version,
77
+ source_revision = target_revision,
78
+ target_revision = source_revision,
79
+ source_to_target_relation = 'uses',
80
+ target_to_source_relation = 'reverse:uses'
81
+ WHERE source_to_target_relation = 'usedBy';--> statement-breakpoint
82
+
83
+ -- Normalize extendedBy -> extends (swap source and target)
84
+ UPDATE `entities_relations`
85
+ SET
86
+ source_key = target_key,
87
+ target_key = source_key,
88
+ source_version = target_version,
89
+ target_version = source_version,
90
+ source_revision = target_revision,
91
+ target_revision = source_revision,
92
+ source_to_target_relation = 'extends',
93
+ target_to_source_relation = 'reverse:extends'
94
+ WHERE source_to_target_relation = 'extendedBy';--> statement-breakpoint
95
+
96
+ -- Normalize supersededBy -> supersedes (swap source and target)
97
+ UPDATE `entities_relations`
98
+ SET
99
+ source_key = target_key,
100
+ target_key = source_key,
101
+ source_version = target_version,
102
+ target_version = source_version,
103
+ source_revision = target_revision,
104
+ target_revision = source_revision,
105
+ source_to_target_relation = 'supersedes',
106
+ target_to_source_relation = 'reverse:supersedes'
107
+ WHERE source_to_target_relation = 'supersededBy';--> statement-breakpoint
108
+
109
+ -- Normalize memberOf -> hasMember (swap source and target)
110
+ UPDATE `entities_relations`
111
+ SET
112
+ source_key = target_key,
113
+ target_key = source_key,
114
+ source_version = target_version,
115
+ target_version = source_version,
116
+ source_revision = target_revision,
117
+ target_revision = source_revision,
118
+ source_to_target_relation = 'hasMember',
119
+ target_to_source_relation = 'reverse:hasMember'
120
+ WHERE source_to_target_relation = 'memberOf';--> statement-breakpoint
121
+
122
+ -- Normalize triggeredBy -> triggers (swap source and target)
123
+ UPDATE `entities_relations`
124
+ SET
125
+ source_key = target_key,
126
+ target_key = source_key,
127
+ source_version = target_version,
128
+ target_version = source_version,
129
+ source_revision = target_revision,
130
+ target_revision = source_revision,
131
+ source_to_target_relation = 'triggers',
132
+ target_to_source_relation = 'reverse:triggers'
133
+ WHERE source_to_target_relation = 'triggeredBy';--> statement-breakpoint
134
+
135
+ -- Normalize returnedBy -> returns (swap source and target)
136
+ UPDATE `entities_relations`
137
+ SET
138
+ source_key = target_key,
139
+ target_key = source_key,
140
+ source_version = target_version,
141
+ target_version = source_version,
142
+ source_revision = target_revision,
143
+ target_revision = source_revision,
144
+ source_to_target_relation = 'returns',
145
+ target_to_source_relation = 'reverse:returns'
146
+ WHERE source_to_target_relation = 'returnedBy';
147
+
@@ -0,0 +1,392 @@
1
+ {
2
+ "version": "6",
3
+ "dialect": "sqlite",
4
+ "id": "a1b2c3d4-e5f6-4789-a012-3456789abcde",
5
+ "prevId": "81397c74-6950-4f46-a595-b92bf6bded70",
6
+ "tables": {
7
+ "entities_relations": {
8
+ "name": "entities_relations",
9
+ "columns": {
10
+ "id": {
11
+ "name": "id",
12
+ "type": "text",
13
+ "primaryKey": true,
14
+ "notNull": true,
15
+ "autoincrement": false
16
+ },
17
+ "organization_id": {
18
+ "name": "organization_id",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true,
22
+ "autoincrement": false
23
+ },
24
+ "project_id": {
25
+ "name": "project_id",
26
+ "type": "text",
27
+ "primaryKey": false,
28
+ "notNull": true,
29
+ "autoincrement": false
30
+ },
31
+ "source_key": {
32
+ "name": "source_key",
33
+ "type": "text",
34
+ "primaryKey": false,
35
+ "notNull": true,
36
+ "autoincrement": false
37
+ },
38
+ "source_version": {
39
+ "name": "source_version",
40
+ "type": "text",
41
+ "primaryKey": false,
42
+ "notNull": true,
43
+ "autoincrement": false,
44
+ "default": "''"
45
+ },
46
+ "source_revision": {
47
+ "name": "source_revision",
48
+ "type": "text",
49
+ "primaryKey": false,
50
+ "notNull": true,
51
+ "autoincrement": false,
52
+ "default": "''"
53
+ },
54
+ "source_to_target_relation": {
55
+ "name": "source_to_target_relation",
56
+ "type": "text",
57
+ "primaryKey": false,
58
+ "notNull": true,
59
+ "autoincrement": false
60
+ },
61
+ "target_key": {
62
+ "name": "target_key",
63
+ "type": "text",
64
+ "primaryKey": false,
65
+ "notNull": true,
66
+ "autoincrement": false
67
+ },
68
+ "target_version": {
69
+ "name": "target_version",
70
+ "type": "text",
71
+ "primaryKey": false,
72
+ "notNull": true,
73
+ "autoincrement": false,
74
+ "default": "''"
75
+ },
76
+ "target_revision": {
77
+ "name": "target_revision",
78
+ "type": "text",
79
+ "primaryKey": false,
80
+ "notNull": true,
81
+ "autoincrement": false,
82
+ "default": "''"
83
+ },
84
+ "target_to_source_relation": {
85
+ "name": "target_to_source_relation",
86
+ "type": "text",
87
+ "primaryKey": false,
88
+ "notNull": true,
89
+ "autoincrement": false
90
+ },
91
+ "source_file": {
92
+ "name": "source_file",
93
+ "type": "text",
94
+ "primaryKey": false,
95
+ "notNull": false,
96
+ "autoincrement": false
97
+ },
98
+ "file_hash": {
99
+ "name": "file_hash",
100
+ "type": "text",
101
+ "primaryKey": false,
102
+ "notNull": false,
103
+ "autoincrement": false
104
+ },
105
+ "is_deleted": {
106
+ "name": "is_deleted",
107
+ "type": "integer",
108
+ "primaryKey": false,
109
+ "notNull": false,
110
+ "autoincrement": false,
111
+ "default": false
112
+ },
113
+ "created_at": {
114
+ "name": "created_at",
115
+ "type": "text",
116
+ "primaryKey": false,
117
+ "notNull": true,
118
+ "autoincrement": false
119
+ },
120
+ "updated_at": {
121
+ "name": "updated_at",
122
+ "type": "text",
123
+ "primaryKey": false,
124
+ "notNull": true,
125
+ "autoincrement": false
126
+ }
127
+ },
128
+ "indexes": {
129
+ "idx_entities_relations_source_key": {
130
+ "name": "idx_entities_relations_source_key",
131
+ "columns": ["source_key", "is_deleted"],
132
+ "isUnique": false
133
+ },
134
+ "idx_entities_relations_target_key": {
135
+ "name": "idx_entities_relations_target_key",
136
+ "columns": ["target_key", "is_deleted"],
137
+ "isUnique": false
138
+ },
139
+ "idx_entities_relations_source_target": {
140
+ "name": "idx_entities_relations_source_target",
141
+ "columns": ["source_to_target_relation"],
142
+ "isUnique": false
143
+ },
144
+ "idx_entities_relations_target_source": {
145
+ "name": "idx_entities_relations_target_source",
146
+ "columns": ["target_to_source_relation"],
147
+ "isUnique": false
148
+ },
149
+ "idx_entities_relations_unique": {
150
+ "name": "idx_entities_relations_unique",
151
+ "columns": [
152
+ "source_key",
153
+ "target_key",
154
+ "source_version",
155
+ "target_version",
156
+ "source_revision",
157
+ "target_revision"
158
+ ],
159
+ "isUnique": true
160
+ }
161
+ },
162
+ "foreignKeys": {},
163
+ "compositePrimaryKeys": {},
164
+ "uniqueConstraints": {},
165
+ "checkConstraints": {}
166
+ },
167
+ "entities": {
168
+ "name": "entities",
169
+ "columns": {
170
+ "id": {
171
+ "name": "id",
172
+ "type": "text",
173
+ "primaryKey": true,
174
+ "notNull": true,
175
+ "autoincrement": false
176
+ },
177
+ "organization_id": {
178
+ "name": "organization_id",
179
+ "type": "text",
180
+ "primaryKey": false,
181
+ "notNull": true,
182
+ "autoincrement": false
183
+ },
184
+ "project_id": {
185
+ "name": "project_id",
186
+ "type": "text",
187
+ "primaryKey": false,
188
+ "notNull": true,
189
+ "autoincrement": false
190
+ },
191
+ "key": {
192
+ "name": "key",
193
+ "type": "text",
194
+ "primaryKey": false,
195
+ "notNull": true,
196
+ "autoincrement": false
197
+ },
198
+ "type": {
199
+ "name": "type",
200
+ "type": "text",
201
+ "primaryKey": false,
202
+ "notNull": true,
203
+ "autoincrement": false
204
+ },
205
+ "title": {
206
+ "name": "title",
207
+ "type": "text",
208
+ "primaryKey": false,
209
+ "notNull": true,
210
+ "autoincrement": false
211
+ },
212
+ "summary": {
213
+ "name": "summary",
214
+ "type": "text",
215
+ "primaryKey": false,
216
+ "notNull": false,
217
+ "autoincrement": false
218
+ },
219
+ "tags": {
220
+ "name": "tags",
221
+ "type": "text",
222
+ "primaryKey": false,
223
+ "notNull": false,
224
+ "autoincrement": false
225
+ },
226
+ "metadata": {
227
+ "name": "metadata",
228
+ "type": "text",
229
+ "primaryKey": false,
230
+ "notNull": false,
231
+ "autoincrement": false
232
+ },
233
+ "git": {
234
+ "name": "git",
235
+ "type": "text",
236
+ "primaryKey": false,
237
+ "notNull": false,
238
+ "autoincrement": false
239
+ },
240
+ "contact": {
241
+ "name": "contact",
242
+ "type": "text",
243
+ "primaryKey": false,
244
+ "notNull": false,
245
+ "autoincrement": false
246
+ },
247
+ "links": {
248
+ "name": "links",
249
+ "type": "text",
250
+ "primaryKey": false,
251
+ "notNull": false,
252
+ "autoincrement": false
253
+ },
254
+ "created_at": {
255
+ "name": "created_at",
256
+ "type": "text",
257
+ "primaryKey": false,
258
+ "notNull": true,
259
+ "autoincrement": false
260
+ },
261
+ "updated_at": {
262
+ "name": "updated_at",
263
+ "type": "text",
264
+ "primaryKey": false,
265
+ "notNull": true,
266
+ "autoincrement": false
267
+ },
268
+ "source": {
269
+ "name": "source",
270
+ "type": "text",
271
+ "primaryKey": false,
272
+ "notNull": false,
273
+ "autoincrement": false,
274
+ "default": "'file'"
275
+ },
276
+ "source_file": {
277
+ "name": "source_file",
278
+ "type": "text",
279
+ "primaryKey": false,
280
+ "notNull": false,
281
+ "autoincrement": false
282
+ },
283
+ "file_hash": {
284
+ "name": "file_hash",
285
+ "type": "text",
286
+ "primaryKey": false,
287
+ "notNull": false,
288
+ "autoincrement": false
289
+ },
290
+ "version": {
291
+ "name": "version",
292
+ "type": "text",
293
+ "primaryKey": false,
294
+ "notNull": true,
295
+ "autoincrement": false,
296
+ "default": "'not_specified_version'"
297
+ },
298
+ "revision": {
299
+ "name": "revision",
300
+ "type": "text",
301
+ "primaryKey": false,
302
+ "notNull": true,
303
+ "autoincrement": false
304
+ },
305
+ "hash": {
306
+ "name": "hash",
307
+ "type": "text",
308
+ "primaryKey": false,
309
+ "notNull": false,
310
+ "autoincrement": false
311
+ },
312
+ "is_current": {
313
+ "name": "is_current",
314
+ "type": "integer",
315
+ "primaryKey": false,
316
+ "notNull": false,
317
+ "autoincrement": false,
318
+ "default": true
319
+ },
320
+ "is_default_version": {
321
+ "name": "is_default_version",
322
+ "type": "integer",
323
+ "primaryKey": false,
324
+ "notNull": false,
325
+ "autoincrement": false,
326
+ "default": false
327
+ },
328
+ "is_deleted": {
329
+ "name": "is_deleted",
330
+ "type": "integer",
331
+ "primaryKey": false,
332
+ "notNull": false,
333
+ "autoincrement": false,
334
+ "default": false
335
+ },
336
+ "scorecards_status": {
337
+ "name": "scorecards_status",
338
+ "type": "text",
339
+ "primaryKey": false,
340
+ "notNull": false,
341
+ "autoincrement": false
342
+ }
343
+ },
344
+ "indexes": {
345
+ "idx_entities_type": {
346
+ "name": "idx_entities_type",
347
+ "columns": ["type"],
348
+ "isUnique": false
349
+ },
350
+ "idx_entities_hash": {
351
+ "name": "idx_entities_hash",
352
+ "columns": ["hash"],
353
+ "isUnique": false
354
+ },
355
+ "idx_entities_key_source_created_at": {
356
+ "name": "idx_entities_key_source_created_at",
357
+ "columns": ["key", "created_at"],
358
+ "isUnique": false
359
+ },
360
+ "idx_entities_key_source_is_current": {
361
+ "name": "idx_entities_key_source_is_current",
362
+ "columns": ["key", "is_current", "is_deleted"],
363
+ "isUnique": false
364
+ },
365
+ "idx_entities_key_source_is_default": {
366
+ "name": "idx_entities_key_source_is_default",
367
+ "columns": ["key", "is_default_version"],
368
+ "isUnique": false
369
+ },
370
+ "idx_entities_key_source": {
371
+ "name": "idx_entities_key_source",
372
+ "columns": ["key", "source", "revision", "version"],
373
+ "isUnique": true
374
+ }
375
+ },
376
+ "foreignKeys": {},
377
+ "compositePrimaryKeys": {},
378
+ "uniqueConstraints": {},
379
+ "checkConstraints": {}
380
+ }
381
+ },
382
+ "views": {},
383
+ "enums": {},
384
+ "_meta": {
385
+ "schemas": {},
386
+ "tables": {},
387
+ "columns": {}
388
+ },
389
+ "internal": {
390
+ "indexes": {}
391
+ }
392
+ }
@@ -29,6 +29,13 @@
29
29
  "when": 1765198112079,
30
30
  "tag": "0003_catalog_versions_and_revisions_relations",
31
31
  "breakpoints": true
32
+ },
33
+ {
34
+ "idx": 4,
35
+ "version": "6",
36
+ "when": 1734624000000,
37
+ "tag": "0004_normalize_relation_types",
38
+ "breakpoints": true
32
39
  }
33
40
  ]
34
41
  }
@@ -9,9 +9,21 @@ DROP INDEX IF EXISTS `idx_entities_key_source_created_at`;--> statement-breakpoi
9
9
  DROP INDEX IF EXISTS `idx_entities_key_source_is_current`;--> statement-breakpoint
10
10
  DROP INDEX IF EXISTS `idx_entities_key_source_is_default`;--> statement-breakpoint
11
11
  DROP INDEX IF EXISTS `idx_entities_key_source`;--> statement-breakpoint
12
+ -- Update all NULL values to '' first before creating unique index
12
13
  UPDATE `entities_relations` SET "source_version" = '' WHERE "source_version" IS NULL;--> statement-breakpoint
14
+ UPDATE `entities_relations` SET "source_revision" = '' WHERE "source_revision" IS NULL;--> statement-breakpoint
15
+ UPDATE `entities_relations` SET "target_version" = '' WHERE "target_version" IS NULL;--> statement-breakpoint
16
+ UPDATE `entities_relations` SET "target_revision" = '' WHERE "target_revision" IS NULL;--> statement-breakpoint
17
+ -- Delete duplicate relations keeping only the most recent one (by id)
18
+ DELETE FROM `entities_relations` WHERE `id` NOT IN (
19
+ SELECT MAX(`id`) FROM `entities_relations`
20
+ GROUP BY `source_key`, `target_key`, `source_version`, `target_version`, `source_revision`, `target_revision`
21
+ );--> statement-breakpoint
13
22
  -- We need to set default value to '', because NULL is not unique in sqlite
14
23
  ALTER TABLE `entities_relations` ALTER COLUMN "source_version" TO "source_version" text NOT NULL DEFAULT '';--> statement-breakpoint
24
+ ALTER TABLE `entities_relations` ALTER COLUMN "source_revision" TO "source_revision" text NOT NULL DEFAULT '';--> statement-breakpoint
25
+ ALTER TABLE `entities_relations` ALTER COLUMN "target_version" TO "target_version" text NOT NULL DEFAULT '';--> statement-breakpoint
26
+ ALTER TABLE `entities_relations` ALTER COLUMN "target_revision" TO "target_revision" text NOT NULL DEFAULT '';--> statement-breakpoint
15
27
  ALTER TABLE `entities_relations` ADD `is_deleted` integer DEFAULT false;--> statement-breakpoint
16
28
  CREATE INDEX `idx_entities_relations_source_key` ON `entities_relations` (`source_key`,`is_deleted`);--> statement-breakpoint
17
29
  CREATE INDEX `idx_entities_relations_target_key` ON `entities_relations` (`target_key`,`is_deleted`);--> statement-breakpoint
@@ -25,12 +37,6 @@ ALTER TABLE `entities` ADD `is_deleted` integer DEFAULT false;--> statement-brea
25
37
  CREATE INDEX `idx_entities_key_source_is_current` ON `entities` (`key`,`is_current`,`is_deleted`);--> statement-breakpoint
26
38
  CREATE INDEX `idx_entities_key_source_is_default` ON `entities` (`key`,`is_default_version`);--> statement-breakpoint
27
39
  CREATE UNIQUE INDEX `idx_entities_key_source` ON `entities` (`key`,`source`,`revision`,`version`);--> statement-breakpoint
28
- UPDATE `entities_relations` SET "source_revision" = '' WHERE "source_revision" IS NULL;--> statement-breakpoint
29
- ALTER TABLE `entities_relations` ALTER COLUMN "source_revision" TO "source_revision" text NOT NULL DEFAULT '';--> statement-breakpoint
30
- UPDATE `entities_relations` SET "target_version" = '' WHERE "target_version" IS NULL;--> statement-breakpoint
31
- ALTER TABLE `entities_relations` ALTER COLUMN "target_version" TO "target_version" text NOT NULL DEFAULT '';--> statement-breakpoint
32
- UPDATE `entities_relations` SET "target_revision" = '' WHERE "target_revision" IS NULL;--> statement-breakpoint
33
- ALTER TABLE `entities_relations` ALTER COLUMN "target_revision" TO "target_revision" text NOT NULL DEFAULT '';--> statement-breakpoint
34
40
  ALTER TABLE `entities_relations` DROP COLUMN `source_id`;--> statement-breakpoint
35
41
  ALTER TABLE `entities_relations` DROP COLUMN `target_id`;--> statement-breakpoint
36
42
  DROP INDEX IF EXISTS `idx_entities_key_source_is_current`;--> statement-breakpoint
@@ -7,6 +7,7 @@ export declare function applyFilter<T extends SQLiteSelect | SQLiteDelete>(sqlBu
7
7
  };
8
8
  export declare function convertFilterToWhereCondition(filter?: Filter): SQL | undefined;
9
9
  export declare function getFirstFilterFieldValue(filter: Filter | undefined, fieldName: string): FilterClause['value'] | undefined;
10
+ export declare function getAllFilterFieldValues(filter: Filter | undefined, fieldName: string): string[];
10
11
  export declare function parseFilterQuery(query?: string, availableFields?: string[], fieldsTransformations?: Record<string, string>): Filter | undefined;
11
12
  export declare function excludeFieldsFromFilter(filter: Filter | undefined, fieldsToExclude: string[]): Filter | undefined;
12
13
  //# sourceMappingURL=filter.d.ts.map