@galadrim/galadmin 0.2.11 → 0.3.0-alpha.2.1

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 (233) hide show
  1. package/.agents/report/blockers.json +1 -0
  2. package/.agents/report/failures/2026-09-23-api-user-filter-contract.md +31 -0
  3. package/.agents/report/failures/2026-09-23-api-values-contract.md +25 -0
  4. package/.agents/report/failures/2026-10-01-cycle-02-create-callback-contract.md +17 -0
  5. package/.agents/report/failures/2026-10-01-cycle-06-delete-callback-id-contract.md +17 -0
  6. package/.agents/report/failures/2026-10-01-cycle-07-panel-delete-callback-id-contract.md +24 -0
  7. package/.agents/report/failures/2026-10-01-cycle-13-update-callback-id-contract.md +17 -0
  8. package/.agents/report/failures/2026-10-01-cycle-15-rich-text-upload-boundary-contract.md +24 -0
  9. package/.agents/report/failures/2026-10-03-cycle-06-record-import-parser-contract.md +11 -0
  10. package/.agents/report/failures/2026-10-03-cycle-07-panel-import-parser-contract.md +24 -0
  11. package/.agents/report/failures/2026-10-07-resume-cycle-02-api-assembly-contract.md +46 -0
  12. package/.agents/report/port/2026-09-23-api-config-enrichment.md +13 -0
  13. package/.agents/report/port/2026-09-23-api-file-upload.md +11 -0
  14. package/.agents/report/port/2026-09-23-api-query-authorization.md +14 -0
  15. package/.agents/report/port/2026-09-23-api-request-configuration.md +11 -0
  16. package/.agents/report/port/2026-09-23-database-manager.md +13 -0
  17. package/.agents/report/port/2026-10-01-api-adjacent-record-id.md +9 -0
  18. package/.agents/report/port/2026-10-01-cycle-01-api-config-route.md +9 -0
  19. package/.agents/report/port/2026-10-01-cycle-03-custom-action.md +9 -0
  20. package/.agents/report/port/2026-10-01-cycle-04-custom-component.md +7 -0
  21. package/.agents/report/port/2026-10-01-cycle-05-custom-query.md +7 -0
  22. package/.agents/report/port/2026-10-01-cycle-08-bulk-delete.md +9 -0
  23. package/.agents/report/port/2026-10-01-cycle-09-duplicate-record.md +9 -0
  24. package/.agents/report/port/2026-10-01-cycle-10-notification-badges.md +9 -0
  25. package/.agents/report/port/2026-10-01-cycle-11-record.md +7 -0
  26. package/.agents/report/port/2026-10-01-cycle-12-search-companies.md +11 -0
  27. package/.agents/report/port/2026-10-01-cycle-14-upload-file.md +7 -0
  28. package/.agents/report/port/2026-10-03-cycle-01-create-record.md +11 -0
  29. package/.agents/report/port/2026-10-03-cycle-02-delete-record.md +11 -0
  30. package/.agents/report/port/2026-10-03-cycle-03-panel-delete-record.md +11 -0
  31. package/.agents/report/port/2026-10-03-cycle-04-update-record.md +11 -0
  32. package/.agents/report/port/2026-10-03-cycle-05-api-values.md +11 -0
  33. package/.agents/report/port/2026-10-06-cycle-01-record-import.md +9 -0
  34. package/.agents/report/port/2026-10-06-cycle-03-rich-text-upload.md +7 -0
  35. package/.agents/report/port/2026-10-06-cycle-04-user-filters.md +11 -0
  36. package/.agents/report/port/2026-10-06-resume-cycle-01-panel-import.md +9 -0
  37. package/.agents/report/port/2026-10-07-cycle-01-api-assembly.md +16 -0
  38. package/.agents/report/port/2026-10-07-cycle-02-index-entry-point.md +13 -0
  39. package/.agents/report/remediation/2026-10-02-api-user-filter-remediation.md +71 -0
  40. package/.agents/report/remediation/2026-10-02-api-values-remediation.md +17 -0
  41. package/.agents/report/remediation/2026-10-03-callback-id-contract-remediation.md +36 -0
  42. package/.agents/report/remediation/2026-10-06-import-parser-remediation.md +41 -0
  43. package/.agents/report/remediation/2026-10-06-rich-text-upload-remediation.md +33 -0
  44. package/.agents/report/remediation/2026-10-07-api-assembly-remediation.md +32 -0
  45. package/.agents/skills/port-javascript-to-typescript/SKILL.md +42 -0
  46. package/.agents/skills/port-javascript-to-typescript/agents/openai.yaml +3 -0
  47. package/.agents/skills/port-javascript-to-typescript/references/blockers.md +31 -0
  48. package/.agents/skills/port-javascript-to-typescript/references/planning.md +43 -0
  49. package/.agents/skills/port-javascript-to-typescript/references/porting.md +9 -0
  50. package/.agents/skills/port-javascript-to-typescript/references/reporting.md +24 -0
  51. package/.agents/skills/port-javascript-to-typescript/references/rules.md +8 -0
  52. package/.agents/skills/port-javascript-to-typescript/references/selection.md +16 -0
  53. package/.agents/skills/port-javascript-to-typescript/references/tools.md +20 -0
  54. package/.agents/skills/port-javascript-to-typescript/scripts/check.sh +17 -0
  55. package/.agents/skills/port-javascript-to-typescript/scripts/graph.sh +30 -0
  56. package/.agents/skills/port-javascript-to-typescript/scripts/madge.json +12 -0
  57. package/.agents/skills/port-javascript-to-typescript/scripts/oxlint.json +14 -0
  58. package/.agents/skills/port-javascript-to-typescript/scripts/test-tools.cjs +76 -0
  59. package/.github/actions/version-bump/action.yml +41 -0
  60. package/.github/workflows/alpha.yml +53 -0
  61. package/.github/workflows/ci.yml +8 -9
  62. package/.github/workflows/main.yml +13 -14
  63. package/AGENTS.md +5 -0
  64. package/dist/api/authorization.d.ts +38 -0
  65. package/dist/api/authorization.js +74 -0
  66. package/dist/api/authorization.js.map +1 -0
  67. package/dist/api/config.d.ts +42 -0
  68. package/dist/api/config.js +105 -0
  69. package/dist/api/config.js.map +1 -0
  70. package/dist/api/filterUser.d.ts +2 -0
  71. package/dist/api/filterUser.js +24 -0
  72. package/dist/api/filterUser.js.map +1 -0
  73. package/dist/api/importRecords.d.ts +1 -0
  74. package/dist/api/importRecords.js +16 -0
  75. package/dist/api/importRecords.js.map +1 -0
  76. package/dist/api/queries.d.ts +48 -0
  77. package/dist/api/queries.js +139 -0
  78. package/dist/api/queries.js.map +1 -0
  79. package/dist/api/request.d.ts +29 -0
  80. package/dist/api/request.js +3 -0
  81. package/dist/api/request.js.map +1 -0
  82. package/dist/api/routes/adjacentRecordId.d.ts +10 -0
  83. package/dist/api/routes/adjacentRecordId.js +13 -0
  84. package/dist/api/routes/adjacentRecordId.js.map +1 -0
  85. package/dist/api/routes/config.d.ts +3 -0
  86. package/dist/api/routes/config.js +27 -0
  87. package/dist/api/routes/config.js.map +1 -0
  88. package/dist/api/routes/createRecord.d.ts +19 -0
  89. package/dist/api/routes/createRecord.js +93 -0
  90. package/dist/api/routes/createRecord.js.map +1 -0
  91. package/dist/api/routes/customAction.d.ts +17 -0
  92. package/dist/api/routes/customAction.js +35 -0
  93. package/dist/api/routes/customAction.js.map +1 -0
  94. package/dist/api/routes/customComponent.d.ts +3 -0
  95. package/dist/api/routes/customComponent.js +34 -0
  96. package/dist/api/routes/customComponent.js.map +1 -0
  97. package/dist/api/routes/customQuery.d.ts +7 -0
  98. package/dist/api/routes/customQuery.js +33 -0
  99. package/dist/api/routes/customQuery.js.map +1 -0
  100. package/dist/api/routes/deleteRecord.d.ts +9 -0
  101. package/dist/api/routes/deleteRecord.js +46 -0
  102. package/dist/api/routes/deleteRecord.js.map +1 -0
  103. package/dist/api/routes/deleteRecordFromPanel.d.ts +10 -0
  104. package/dist/api/routes/deleteRecordFromPanel.js +36 -0
  105. package/dist/api/routes/deleteRecordFromPanel.js.map +1 -0
  106. package/dist/api/routes/deleteRecords.d.ts +9 -0
  107. package/dist/api/routes/deleteRecords.js +12 -0
  108. package/dist/api/routes/deleteRecords.js.map +1 -0
  109. package/dist/api/routes/duplicateRecord.d.ts +17 -0
  110. package/dist/api/routes/duplicateRecord.js +55 -0
  111. package/dist/api/routes/duplicateRecord.js.map +1 -0
  112. package/dist/api/routes/foreignSelectRecords.d.ts +10 -0
  113. package/dist/api/routes/foreignSelectRecords.js +61 -0
  114. package/dist/api/routes/foreignSelectRecords.js.map +1 -0
  115. package/dist/api/routes/notificationBadges.d.ts +6 -0
  116. package/dist/api/routes/notificationBadges.js +31 -0
  117. package/dist/api/routes/notificationBadges.js.map +1 -0
  118. package/dist/api/routes/record.d.ts +7 -0
  119. package/dist/api/routes/record.js +32 -0
  120. package/dist/api/routes/record.js.map +1 -0
  121. package/dist/api/routes/records.d.ts +14 -0
  122. package/dist/api/routes/records.js +57 -0
  123. package/dist/api/routes/records.js.map +1 -0
  124. package/dist/api/routes/recordsExport.d.ts +13 -0
  125. package/dist/api/routes/recordsExport.js +67 -0
  126. package/dist/api/routes/recordsExport.js.map +1 -0
  127. package/dist/api/routes/recordsImport.d.ts +4 -0
  128. package/dist/api/routes/recordsImport.js +100 -0
  129. package/dist/api/routes/recordsImport.js.map +1 -0
  130. package/dist/api/routes/searchCompanies.d.ts +17 -0
  131. package/dist/api/routes/searchCompanies.js +72 -0
  132. package/dist/api/routes/searchCompanies.js.map +1 -0
  133. package/dist/api/routes/subrecordsImport.d.ts +4 -0
  134. package/dist/api/routes/subrecordsImport.js +94 -0
  135. package/dist/api/routes/subrecordsImport.js.map +1 -0
  136. package/dist/api/routes/updateRecord.d.ts +13 -0
  137. package/dist/api/routes/updateRecord.js +55 -0
  138. package/dist/api/routes/updateRecord.js.map +1 -0
  139. package/dist/api/routes/uploadFile.d.ts +3 -0
  140. package/dist/api/routes/uploadFile.js +13 -0
  141. package/dist/api/routes/uploadFile.js.map +1 -0
  142. package/dist/api/routes/uploadFileFromBetterRichTextInput.d.ts +3 -0
  143. package/dist/api/routes/uploadFileFromBetterRichTextInput.js +33 -0
  144. package/dist/api/routes/uploadFileFromBetterRichTextInput.js.map +1 -0
  145. package/dist/api/uploadFile.d.ts +4 -0
  146. package/dist/api/uploadFile.js +209 -0
  147. package/dist/api/uploadFile.js.map +1 -0
  148. package/dist/api/values.d.ts +6 -0
  149. package/dist/api/values.js +88 -0
  150. package/dist/api/values.js.map +1 -0
  151. package/dist/api.d.ts +8 -27
  152. package/dist/api.js +80 -1387
  153. package/dist/api.js.map +1 -1
  154. package/dist/index.d.ts +2 -2
  155. package/dist/index.js +8 -2
  156. package/dist/index.js.map +1 -1
  157. package/dist/tsconfig.strict.tsbuildinfo +1 -0
  158. package/dist/types/config.d.ts +15 -5
  159. package/dist/types/config.js +4 -0
  160. package/dist/types/config.js.map +1 -1
  161. package/dist/types/database.d.ts +1 -0
  162. package/dist/types/database.js +3 -0
  163. package/dist/types/database.js.map +1 -0
  164. package/dist/utils/dbManager.d.ts +32 -7
  165. package/dist/utils/dbManager.js +59 -7
  166. package/dist/utils/dbManager.js.map +1 -1
  167. package/package.json +12 -3
  168. package/src/api/authorization.ts +129 -0
  169. package/src/api/config.ts +152 -0
  170. package/src/api/filterUser.ts +28 -0
  171. package/src/api/importRecords.ts +16 -0
  172. package/src/api/queries.ts +194 -0
  173. package/src/api/request.ts +31 -0
  174. package/src/api/routes/adjacentRecordId.ts +20 -0
  175. package/src/api/routes/config.ts +15 -0
  176. package/src/api/routes/createRecord.ts +131 -0
  177. package/src/api/routes/customAction.ts +60 -0
  178. package/src/api/routes/customComponent.ts +44 -0
  179. package/src/api/routes/customQuery.ts +53 -0
  180. package/src/api/routes/deleteRecord.ts +59 -0
  181. package/src/api/routes/deleteRecordFromPanel.ts +58 -0
  182. package/src/api/routes/deleteRecords.ts +28 -0
  183. package/src/api/routes/duplicateRecord.ts +73 -0
  184. package/src/api/routes/foreignSelectRecords.ts +80 -0
  185. package/src/api/routes/notificationBadges.ts +47 -0
  186. package/src/api/routes/record.ts +48 -0
  187. package/src/api/routes/records.ts +91 -0
  188. package/src/api/routes/recordsExport.ts +92 -0
  189. package/src/api/routes/recordsImport.ts +115 -0
  190. package/src/api/routes/searchCompanies.ts +96 -0
  191. package/src/api/routes/subrecordsImport.ts +114 -0
  192. package/src/api/routes/updateRecord.ts +74 -0
  193. package/src/api/routes/uploadFile.ts +16 -0
  194. package/src/api/routes/uploadFileFromBetterRichTextInput.ts +41 -0
  195. package/src/api/uploadFile.ts +249 -0
  196. package/src/api/values.ts +96 -0
  197. package/src/api.ts +94 -1580
  198. package/src/front/ckeditor5-build/node_modules/semver/bin/semver.js +0 -0
  199. package/src/index.ts +42 -25
  200. package/src/types/config.ts +15 -5
  201. package/src/types/database.ts +2 -0
  202. package/src/utils/dbManager.ts +99 -14
  203. package/tests/api-helpers.test.ts +59 -0
  204. package/tests/dbManager.test.ts +16 -1
  205. package/tests/helpers/fakeDb.ts +9 -7
  206. package/tests/integration/authorizationBoundary.integration.test.ts +57 -0
  207. package/tests/integration/configEnrichment.integration.test.ts +79 -0
  208. package/tests/integration/customComponentBoundary.integration.test.ts +58 -0
  209. package/tests/integration/dbManager.integration.test.ts +105 -3
  210. package/tests/integration/importParserChild.cjs +55 -0
  211. package/tests/integration/indexRuntime.integration.test.ts +22 -0
  212. package/tests/integration/indexRuntimeChild.cjs +110 -0
  213. package/tests/integration/queries.integration.test.ts +88 -0
  214. package/tests/integration/requestConfig.integration.test.ts +118 -0
  215. package/tests/integration/routes.authorization.integration.test.ts +1 -0
  216. package/tests/integration/routes.config.integration.test.ts +39 -1
  217. package/tests/integration/routes.crud.integration.test.ts +233 -1
  218. package/tests/integration/routes.custom.integration.test.ts +119 -0
  219. package/tests/integration/routes.foreign.integration.test.ts +3 -2
  220. package/tests/integration/routes.importExport.integration.test.ts +308 -6
  221. package/tests/integration/routes.integration.test.ts +4 -0
  222. package/tests/integration/routes.records.integration.test.ts +82 -6
  223. package/tests/integration/routes.upload.integration.test.ts +123 -0
  224. package/tests/integration/userFilters.integration.test.ts +225 -0
  225. package/tsconfig.json +1 -1
  226. package/tsconfig.strict.json +45 -0
  227. package/dist/front/ckeditor5-build/src/ckeditor.d.ts +0 -43
  228. package/dist/front/ckeditor5-build/src/ckeditor.js +0 -130
  229. package/dist/front/ckeditor5-build/src/ckeditor.js.map +0 -1
  230. package/dist/tsconfig.tsbuildinfo +0 -1
  231. package/src/front/ckeditor5-build/node_modules/.bin/semver +0 -12
  232. package/src/front/ckeditor5-build/node_modules/.bin/semver.cmd +0 -17
  233. package/src/front/ckeditor5-build/node_modules/.bin/semver.ps1 +0 -28
@@ -0,0 +1,14 @@
1
+ {
2
+ "plugins": ["typescript"],
3
+ "categories": { "correctness": "off" },
4
+ "rules": {
5
+ "typescript/no-explicit-any": "warn",
6
+ "typescript/no-non-null-assertion": "warn",
7
+ "typescript/ban-ts-comment": ["warn", {
8
+ "ts-ignore": true,
9
+ "ts-expect-error": true,
10
+ "ts-nocheck": true,
11
+ "ts-check": false
12
+ }]
13
+ }
14
+ }
@@ -0,0 +1,76 @@
1
+ const assert = require('node:assert/strict');
2
+ const fs = require('node:fs');
3
+ const os = require('node:os');
4
+ const path = require('node:path');
5
+ const { spawnSync } = require('node:child_process');
6
+
7
+ const temporary = fs.mkdtempSync(path.join(os.tmpdir(), 'port tools '));
8
+ const tools = path.join(temporary, 'copied skill');
9
+ const repo = path.join(temporary, 'target repo');
10
+ fs.cpSync(__dirname, tools, { recursive: true });
11
+ fs.mkdirSync(repo);
12
+
13
+ function run(script, args, status = 0) {
14
+ const result = spawnSync('bash', [path.join(tools, script), ...args], {
15
+ cwd: repo, encoding: 'utf8', timeout: 120000,
16
+ });
17
+ assert.ifError(result.error);
18
+ assert.equal(result.status, status, result.stderr + result.stdout);
19
+ return result;
20
+ }
21
+
22
+ try {
23
+ const inputs = {
24
+ 'tsconfig.json': JSON.stringify({ compilerOptions: {
25
+ baseUrl: '.', paths: { '@left': ['./left.ts'] }, allowJs: true,
26
+ } }),
27
+ 'package.json': JSON.stringify({ madge: { excludeRegExp: ['.*'] } }),
28
+ 'entry.ts': 'import { left } from "@left"; import type { Value } from "./types";\n'
29
+ + 'const common = require("./common.cjs"); import("./dynamic");\n',
30
+ 'left.ts': 'import "./right"; export const left = 1;',
31
+ 'right.ts': 'import "./left";',
32
+ 'types.ts': 'export type Value = string;',
33
+ 'common.cjs': 'module.exports = 1;',
34
+ 'dynamic.ts': 'export const dynamic = 1;',
35
+ 'missing.ts': 'import "./does-not-exist";',
36
+ 'warnings.ts': 'let value: any;\nvalue!.field;\n'
37
+ + '// @ts-expect-error documented suppression\nvalue.call();\n'
38
+ + '// @ts-check\nconst unused = 1; debugger;\n',
39
+ '.oxlintrc.json': JSON.stringify({ rules: {
40
+ 'typescript/no-explicit-any': 'off', 'no-unused-vars': 'error',
41
+ } }),
42
+ '.eslintignore': 'warnings.ts\n',
43
+ 'broken.ts': 'const = ;',
44
+ };
45
+ for (const [file, content] of Object.entries(inputs)) {
46
+ fs.writeFileSync(path.join(repo, file), content);
47
+ }
48
+ for (const script of ['graph.sh', 'check.sh']) {
49
+ run(script, ['--help']);
50
+ run(script, [], 2);
51
+ }
52
+ const graph = JSON.parse(run('graph.sh', ['tsconfig.json', 'entry.ts']).stdout);
53
+ assert.deepEqual(graph['entry.ts'], ['common.cjs', 'dynamic.ts', 'left.ts', 'types.ts']);
54
+ assert.deepEqual(graph['left.ts'], ['right.ts']);
55
+ assert.deepEqual(graph['right.ts'], ['left.ts']);
56
+ const missing = run('graph.sh', ['tsconfig.json', 'missing.ts']);
57
+ assert.match(missing.stderr, /does-not-exist/);
58
+ assert.deepEqual(JSON.parse(missing.stdout)['missing.ts'], []);
59
+ run('graph.sh', ['tsconfig.json', 'absent.ts'], 1);
60
+
61
+ const lint = JSON.parse(run('check.sh', ['warnings.ts']).stdout);
62
+ assert.equal(lint.number_of_files, 1);
63
+ assert.equal(lint.diagnostics.length, 3);
64
+ assert.ok(lint.diagnostics.every(diagnostic => diagnostic.severity === 'warning'));
65
+ for (const rule of ['no-explicit-any', 'no-non-null-assertion', 'ban-ts-comment']) {
66
+ assert.ok(lint.diagnostics.some(diagnostic => diagnostic.code.includes(rule)), rule);
67
+ }
68
+ run('check.sh', ['broken.ts'], 1);
69
+ run('check.sh', ['absent.ts'], 1);
70
+ for (const [file, content] of Object.entries(inputs)) {
71
+ assert.equal(fs.readFileSync(path.join(repo, file), 'utf8'), content);
72
+ }
73
+ console.log('Tool integration checks passed.');
74
+ } finally {
75
+ fs.rmSync(temporary, { recursive: true, force: true });
76
+ }
@@ -0,0 +1,41 @@
1
+ name: 'Automated Version Bump'
2
+ description: >-
3
+ Bumps the package version, commits package.json + package-lock.json,
4
+ tags the result and pushes both to the current branch.
5
+ Requires a checkout with persisted credentials and a job granting
6
+ `permissions: contents: write`.
7
+
8
+ inputs:
9
+ version-type:
10
+ description: 'SemVer release type: patch, minor or major'
11
+ required: false
12
+ default: 'patch'
13
+
14
+ outputs:
15
+ version:
16
+ description: 'The new version, without the v prefix (e.g. 0.2.12)'
17
+ value: ${{ steps.bump.outputs.version }}
18
+
19
+ runs:
20
+ using: 'composite'
21
+ steps:
22
+ - name: Configure git author
23
+ shell: bash
24
+ run: |
25
+ git config user.name "github-actions[bot]"
26
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
27
+
28
+ - name: Bump, commit and tag
29
+ id: bump
30
+ shell: bash
31
+ run: |
32
+ VERSION=$(npm version "${{ inputs.version-type }}" --no-git-tag-version)
33
+ VERSION="${VERSION#v}"
34
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
35
+ git add package.json package-lock.json
36
+ git commit -m "ci: version bump to $VERSION"
37
+ git tag "$VERSION"
38
+
39
+ - name: Push commit and tag
40
+ shell: bash
41
+ run: git push origin "HEAD:${{ github.ref_name }}" "${{ steps.bump.outputs.version }}"
@@ -0,0 +1,53 @@
1
+ name: Publish alpha
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ permissions:
7
+ contents: read
8
+
9
+ concurrency:
10
+ group: alpha-publish
11
+
12
+ jobs:
13
+ test:
14
+ uses: ./.github/workflows/ci.yml
15
+
16
+ build-and-publish-alpha:
17
+ needs: test
18
+ runs-on: ubicloud-standard-2
19
+ env:
20
+ CI: false
21
+ steps:
22
+ - name: Checkout code
23
+ uses: actions/checkout@v7
24
+ - uses: actions/setup-node@v7
25
+ with:
26
+ node-version: 22
27
+ registry-url: 'https://registry.npmjs.org'
28
+ cache: 'npm'
29
+ cache-dependency-path: |
30
+ package-lock.json
31
+ src/front/package-lock.json
32
+ - name: Compute alpha version
33
+ run: |
34
+ BASE=$(node -p "require('./package.json').version")
35
+ npm version "$BASE-alpha.${{ github.run_number }}.${{ github.run_attempt }}" --no-git-tag-version --allow-same-version
36
+ - name: Dependencies installation
37
+ run: npm ci
38
+ - name: Front-end - Dependencies installation
39
+ run: npm ci
40
+ working-directory: ./src/front
41
+ - name: Front-end - Generate build
42
+ run: npm run build
43
+ working-directory: ./src/front
44
+ - name: Generate build
45
+ run: npm run build
46
+ - name: Publish package
47
+ run: npm publish --tag alpha
48
+ env:
49
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
50
+ - name: Verify dist-tags
51
+ run: npm view @galadrim/galadmin dist-tags --json
52
+ env:
53
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -9,19 +9,18 @@ jobs:
9
9
  runs-on: ubicloud-standard-2
10
10
  steps:
11
11
  - name: Checkout code
12
- uses: actions/checkout@v2
13
- - uses: actions/setup-node@v3
12
+ uses: actions/checkout@v7
13
+ - uses: actions/setup-node@v7
14
14
  with:
15
15
  node-version: 22
16
+ cache: 'npm'
17
+ cache-dependency-path: |
18
+ package-lock.json
19
+ src/front/package-lock.json
16
20
  - name: Dependencies installation
17
- run: npm install
18
- - name: Front-end - Load cache
19
- uses: actions/cache@v4
20
- with:
21
- path: '**/src/front/node_modules'
22
- key: ${{ runner.os }}-npm-front-${{ hashFiles('**/src/front/package-lock.json') }}
21
+ run: npm ci
23
22
  - name: Front-end - Dependencies installation
24
- run: npm install
23
+ run: npm ci
25
24
  working-directory: ./src/front
26
25
  # The root tsconfig includes the custom CKEditor source under src/front.
27
26
  - name: Typecheck
@@ -11,29 +11,28 @@ jobs:
11
11
  build-and-deploy:
12
12
  needs: test
13
13
  runs-on: ubicloud-standard-2
14
+ permissions:
15
+ contents: write
14
16
  env:
15
17
  CI: false
16
18
  steps:
17
19
  - name: Checkout code
18
- uses: actions/checkout@v2
19
- - uses: actions/setup-node@v3
20
+ uses: actions/checkout@v7
21
+ - uses: actions/setup-node@v7
20
22
  with:
21
23
  node-version: 22
24
+ cache: 'npm'
25
+ cache-dependency-path: |
26
+ package-lock.json
27
+ src/front/package-lock.json
22
28
  - name: 'Automated Version Bump'
23
- uses: 'phips28/gh-action-bump-version@master'
24
- env:
25
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29
+ uses: ./.github/actions/version-bump
26
30
  with:
27
- version-type: 'patch'
31
+ version-type: 'patch'
28
32
  - name: Dependencies installation
29
- run: npm install
30
- - name: Front-end - Load cache
31
- uses: actions/cache@v4
32
- with:
33
- path: '**/src/front/node_modules'
34
- key: ${{ runner.os }}-npm-front-${{ hashFiles('**/src/front/package-lock.json') }}
33
+ run: npm ci
35
34
  - name: Front-end - Dependencies installation
36
- run: npm install
35
+ run: npm ci
37
36
  working-directory: ./src/front
38
37
  - name: Front-end - Generate build
39
38
  run: npm run build
@@ -41,6 +40,6 @@ jobs:
41
40
  - name: Generate build
42
41
  run: npm run build
43
42
  - name: Publish package
44
- uses: JS-DevTools/npm-publish@v1
43
+ uses: JS-DevTools/npm-publish@v4
45
44
  with:
46
45
  token: ${{ secrets.NPM_TOKEN }}
package/AGENTS.md ADDED
@@ -0,0 +1,5 @@
1
+ # Testing
2
+
3
+ - When adding tests, keep mocks to the minimum necessary.
4
+ - Never mock the database.
5
+ - If a test would require mocking, extend the integration tests instead.
@@ -0,0 +1,38 @@
1
+ import type { BaseTypeView, TablePanel } from "../types/config";
2
+ type SessionRequest = {
3
+ session?: object;
4
+ };
5
+ type WritableView = Pick<BaseTypeView, "roles"> & Pick<TablePanel, "tableName"> & {
6
+ recordViewPanels?: (Pick<TablePanel, "tableName"> & {
7
+ createConfig?: Pick<TablePanel, "tableName">;
8
+ })[];
9
+ };
10
+ export declare const ROOT_ROLE = "root";
11
+ export declare const roleOf: (req: SessionRequest) => string | undefined;
12
+ export declare const canWriteView: (view: Pick<BaseTypeView, "roles"> | undefined, role: string | undefined) => boolean;
13
+ export declare const viewFromRequest: <T = WritableView>(req: {
14
+ body?: {
15
+ viewIndex?: unknown;
16
+ };
17
+ query?: {
18
+ viewIndex?: unknown;
19
+ };
20
+ config?: {
21
+ views?: T[];
22
+ };
23
+ }) => T | undefined;
24
+ export declare const MUTATING_VIEW_ROUTES: Set<string>;
25
+ export declare const areSafeColumnNames: (data: unknown) => boolean;
26
+ export declare const writableTables: (req: SessionRequest & {
27
+ config?: {
28
+ views?: WritableView[];
29
+ };
30
+ }) => Set<string>;
31
+ export declare const looksLikeSqlBreakout: (frag: unknown) => boolean;
32
+ type HiddenColumnsView = {
33
+ __hiddenColumns?: string[];
34
+ };
35
+ export declare const hiddenColumnsOf: (view: HiddenColumnsView | undefined) => string[];
36
+ export declare const stripHiddenColumns: <T extends Record<string, unknown>>(view: HiddenColumnsView | undefined, record: T) => T;
37
+ export declare const touchesHiddenColumn: (view: HiddenColumnsView | undefined, data: unknown) => boolean;
38
+ export {};
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.touchesHiddenColumn = exports.stripHiddenColumns = exports.hiddenColumnsOf = exports.looksLikeSqlBreakout = exports.writableTables = exports.areSafeColumnNames = exports.MUTATING_VIEW_ROUTES = exports.viewFromRequest = exports.canWriteView = exports.roleOf = exports.ROOT_ROLE = void 0;
4
+ exports.ROOT_ROLE = "root";
5
+ const roleOf = (req) => {
6
+ const user = req.session && Reflect.get(req.session, "user");
7
+ if (!user || typeof user !== "object")
8
+ return undefined;
9
+ const role = Reflect.get(user, "role");
10
+ return typeof role === "string" ? role : undefined;
11
+ };
12
+ exports.roleOf = roleOf;
13
+ const canWriteView = (view, role) => role === exports.ROOT_ROLE || !view || !view.roles || (role !== undefined && view.roles.includes(role));
14
+ exports.canWriteView = canWriteView;
15
+ const viewFromRequest = (req) => {
16
+ const idx = req.body && req.body.viewIndex !== undefined
17
+ ? req.body.viewIndex
18
+ : req.query && req.query.viewIndex !== undefined
19
+ ? req.query.viewIndex
20
+ : undefined;
21
+ if (idx === undefined || !req.config || !req.config.views)
22
+ return undefined;
23
+ const key = String(idx);
24
+ const index = Number(key);
25
+ if (!Number.isInteger(index) || index < 0 || index >= req.config.views.length || String(index) !== key) {
26
+ return undefined;
27
+ }
28
+ return req.config.views[index];
29
+ };
30
+ exports.viewFromRequest = viewFromRequest;
31
+ exports.MUTATING_VIEW_ROUTES = new Set([
32
+ "/updateRecord",
33
+ "/createRecord",
34
+ "/deleteRecord",
35
+ "/deleteRecords",
36
+ "/deleteRecordFromPanel",
37
+ "/customAction",
38
+ "/uploadFile",
39
+ ]);
40
+ const areSafeColumnNames = (data) => !data || Object.keys(data).every((k) => /^[A-Za-z0-9_]+$/.test(k));
41
+ exports.areSafeColumnNames = areSafeColumnNames;
42
+ const writableTables = (req) => {
43
+ var _a, _b;
44
+ const role = (0, exports.roleOf)(req);
45
+ const tables = new Set();
46
+ for (const view of ((_a = req.config) === null || _a === void 0 ? void 0 : _a.views) || []) {
47
+ if (!(0, exports.canWriteView)(view, role))
48
+ continue;
49
+ if (view.tableName)
50
+ tables.add(view.tableName);
51
+ for (const panel of view.recordViewPanels || []) {
52
+ if (panel.tableName)
53
+ tables.add(panel.tableName);
54
+ if ((_b = panel.createConfig) === null || _b === void 0 ? void 0 : _b.tableName)
55
+ tables.add(panel.createConfig.tableName);
56
+ }
57
+ }
58
+ return tables;
59
+ };
60
+ exports.writableTables = writableTables;
61
+ const looksLikeSqlBreakout = (frag) => typeof frag === "string" &&
62
+ /(;|--|\/\*|\bunion\b|\binto\s+(out|dump)file\b|\bsleep\s*\(|\bbenchmark\s*\(|\bload_file\s*\()/i.test(frag);
63
+ exports.looksLikeSqlBreakout = looksLikeSqlBreakout;
64
+ const hiddenColumnsOf = (view) => (view && view.__hiddenColumns) || [];
65
+ exports.hiddenColumnsOf = hiddenColumnsOf;
66
+ const stripHiddenColumns = (view, record) => {
67
+ for (const name of (0, exports.hiddenColumnsOf)(view))
68
+ delete record[name];
69
+ return record;
70
+ };
71
+ exports.stripHiddenColumns = stripHiddenColumns;
72
+ const touchesHiddenColumn = (view, data) => (0, exports.hiddenColumnsOf)(view).some((name) => data && Object.prototype.hasOwnProperty.call(data, name));
73
+ exports.touchesHiddenColumn = touchesHiddenColumn;
74
+ //# sourceMappingURL=authorization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorization.js","sourceRoot":"","sources":["../../src/api/authorization.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { BaseTypeColumn, Config, FileUploadProperties, RichTextColumn, SelectColumn, StandardColumn, Subview, View } from "../types/config";
2
+ import type dbManager from "../utils/dbManager";
3
+ type Identified = {
4
+ __id__?: string;
5
+ };
6
+ type EnrichmentColumn = StandardColumn & Pick<BaseTypeColumn, "required"> & Pick<RichTextColumn, "contentField"> & Pick<FileUploadProperties, "s3Config" | "gcpConfig"> & Partial<Pick<SelectColumn, "options">> & Identified & {
7
+ baseUrl?: string;
8
+ };
9
+ type EnrichmentView = Identified & {
10
+ subviews?: (Subview & Identified)[];
11
+ } & ({
12
+ type: "table";
13
+ tableName: string;
14
+ primaryId?: string;
15
+ columns: EnrichmentColumn[];
16
+ recordViewPanels?: (Identified & {
17
+ type: string;
18
+ createConfig?: {
19
+ columns: EnrichmentColumn[];
20
+ };
21
+ })[];
22
+ } | {
23
+ type: Exclude<View["type"], "table">;
24
+ });
25
+ type EnrichmentConfig = Pick<Config, "mysql" | "postgresql" | "enriched"> & {
26
+ views: EnrichmentView[];
27
+ };
28
+ type SchemaColumn = {
29
+ TABLE_NAME?: string;
30
+ COLUMN_NAME?: string;
31
+ COLUMN_KEY?: string;
32
+ IS_NULLABLE?: string;
33
+ DATA_TYPE?: string;
34
+ COLUMN_TYPE?: string;
35
+ };
36
+ type SchemaDatabase = {
37
+ query(...args: Parameters<dbManager["query"]>): Promise<Partial<Pick<Awaited<ReturnType<dbManager["query"]>>, "err" | "rows">>>;
38
+ };
39
+ export declare function generateUniqueIdForObject(obj: unknown): string;
40
+ export declare function enrichConfig(config: EnrichmentConfig, db: SchemaDatabase): Promise<void>;
41
+ export declare function enrichColumn(column: EnrichmentColumn, tableName: string, info: SchemaColumn[]): void;
42
+ export {};
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateUniqueIdForObject = generateUniqueIdForObject;
4
+ exports.enrichConfig = enrichConfig;
5
+ exports.enrichColumn = enrichColumn;
6
+ const crypto = require("crypto");
7
+ function readSchemaColumns(value) {
8
+ if (!Array.isArray(value) || !value.every((row) => row !== null && typeof row === "object" && !Array.isArray(row)
9
+ && (!("TABLE_NAME" in row) || typeof row.TABLE_NAME === "string")
10
+ && (!("COLUMN_NAME" in row) || typeof row.COLUMN_NAME === "string")
11
+ && (!("COLUMN_KEY" in row) || typeof row.COLUMN_KEY === "string")
12
+ && (!("IS_NULLABLE" in row) || typeof row.IS_NULLABLE === "string")
13
+ && (!("DATA_TYPE" in row) || typeof row.DATA_TYPE === "string")
14
+ && (!("COLUMN_TYPE" in row) || typeof row.COLUMN_TYPE === "string")))
15
+ throw new TypeError("Invalid database schema columns");
16
+ return value;
17
+ }
18
+ function readEnumOptions(columnType) {
19
+ if (columnType === undefined)
20
+ throw new TypeError("Missing enum column type");
21
+ const options = JSON.parse(columnType.replace("enum(", "[").replace(")", "]").replace(/'/g, '"'));
22
+ if (!Array.isArray(options) || !options.every((option) => typeof option === "string")) {
23
+ throw new TypeError("Invalid enum options");
24
+ }
25
+ return options;
26
+ }
27
+ function generateUniqueIdForObject(obj) {
28
+ const str = JSON.stringify(obj);
29
+ const hash = crypto.createHash("sha256").update(str).digest("hex");
30
+ return hash;
31
+ }
32
+ async function enrichConfig(config, db) {
33
+ var _a, _b;
34
+ const { rows, err = null } = await db.query("SELECT * FROM information_schema.columns WHERE table_schema = ?", [((_a = config.mysql) === null || _a === void 0 ? void 0 : _a.database) || ((_b = config.postgresql) === null || _b === void 0 ? void 0 : _b.database)]);
35
+ if (err) {
36
+ console.error(err);
37
+ return;
38
+ }
39
+ const info = readSchemaColumns(rows);
40
+ for (const view of config.views) {
41
+ if (view.type == "table") {
42
+ const tableName = view.tableName;
43
+ for (const infoEl of info) {
44
+ if (infoEl.TABLE_NAME == tableName && infoEl.COLUMN_KEY == "PRI") {
45
+ view.primaryId = infoEl.COLUMN_NAME;
46
+ }
47
+ }
48
+ for (const column of view.columns) {
49
+ enrichColumn(column, tableName, info);
50
+ }
51
+ if (view.recordViewPanels) {
52
+ for (const panel of view.recordViewPanels) {
53
+ if (panel.createConfig) {
54
+ for (const column of panel.createConfig.columns) {
55
+ enrichColumn(column, tableName, info);
56
+ }
57
+ }
58
+ if (!panel.__id__) {
59
+ panel.__id__ = generateUniqueIdForObject(panel);
60
+ }
61
+ }
62
+ }
63
+ }
64
+ if (view.subviews) {
65
+ for (const subview of view.subviews) {
66
+ if (!subview.__id__) {
67
+ subview.__id__ = generateUniqueIdForObject(subview);
68
+ }
69
+ }
70
+ }
71
+ if (!view.__id__) {
72
+ view.__id__ = generateUniqueIdForObject(view);
73
+ }
74
+ }
75
+ config.enriched = true;
76
+ }
77
+ function enrichColumn(column, tableName, info) {
78
+ var _a, _b, _c, _d;
79
+ if (!column.__id__) {
80
+ column.__id__ = generateUniqueIdForObject(column);
81
+ }
82
+ const infoEl = info.find((x) => x.TABLE_NAME == tableName && x.COLUMN_NAME == column.name);
83
+ if ((infoEl === null || infoEl === void 0 ? void 0 : infoEl.IS_NULLABLE) == "NO" &&
84
+ (infoEl === null || infoEl === void 0 ? void 0 : infoEl.DATA_TYPE) != "text" &&
85
+ column.required !== true &&
86
+ column.required !== false) {
87
+ column.required = true;
88
+ }
89
+ if (!column.dataType && infoEl) {
90
+ column.dataType = infoEl.DATA_TYPE;
91
+ if (column.dataType == "enum") {
92
+ column.dataType = "select";
93
+ column.options = readEnumOptions(infoEl.COLUMN_TYPE);
94
+ }
95
+ }
96
+ if (column.dataType == "richText") {
97
+ column.name = column.contentField;
98
+ }
99
+ if (column.dataType == "file" && (column.s3Config || column.gcpConfig)) {
100
+ const host = ((_a = column.s3Config) === null || _a === void 0 ? void 0 : _a.host) || ((_b = column.gcpConfig) === null || _b === void 0 ? void 0 : _b.host);
101
+ const bucket = ((_c = column.s3Config) === null || _c === void 0 ? void 0 : _c.bucket) || ((_d = column.gcpConfig) === null || _d === void 0 ? void 0 : _d.bucket);
102
+ column.baseUrl = `https://${host}/${bucket}/`;
103
+ }
104
+ }
105
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/api/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { FilterUser } from "../types/config";
2
+ export declare function filterUserFromSession(value: unknown): FilterUser | undefined;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.filterUserFromSession = filterUserFromSession;
4
+ function filterUserFromSession(value) {
5
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
6
+ return undefined;
7
+ }
8
+ const role = "role" in value ? value.role : undefined;
9
+ if (typeof role !== "string") {
10
+ return undefined;
11
+ }
12
+ if (role === "root") {
13
+ return { role };
14
+ }
15
+ const userId = "userId" in value ? value.userId : undefined;
16
+ if (userId === undefined) {
17
+ return { role };
18
+ }
19
+ if (typeof userId === "string" || typeof userId === "number") {
20
+ return { role, userId };
21
+ }
22
+ return undefined;
23
+ }
24
+ //# sourceMappingURL=filterUser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filterUser.js","sourceRoot":"","sources":["../../src/api/filterUser.ts"],"names":[],"mappings":";;AAMA,sDAqBC;AArBD,SAAgB,qBAAqB,CAAC,KAAc;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,IAAI,GAAY,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/D,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAY,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,EAAE,IAAI,EAAE,CAAC;IAClB,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function isImportRecords(value: unknown): value is Record<string, unknown>[];
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isImportRecords = isImportRecords;
4
+ function isImportRecords(value) {
5
+ if (!Array.isArray(value)) {
6
+ return false;
7
+ }
8
+ for (let index = 0; index < value.length; index += 1) {
9
+ const record = value[index];
10
+ if (typeof record !== "object" || record === null || Array.isArray(record)) {
11
+ return false;
12
+ }
13
+ }
14
+ return true;
15
+ }
16
+ //# sourceMappingURL=importRecords.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"importRecords.js","sourceRoot":"","sources":["../../src/api/importRecords.ts"],"names":[],"mappings":";;AAAA,0CAeC;AAfD,SAAgB,eAAe,CAC7B,KAAc;IAEd,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACrD,MAAM,MAAM,GAAY,KAAK,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3E,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,48 @@
1
+ import type dbManager from "../utils/dbManager";
2
+ import type { DatabaseRow } from "../utils/dbManager";
3
+ import type { BaseTypeColumn, Filter, StandardColumn } from "../types/config";
4
+ type Condition = string | Filter[];
5
+ type RecordQueryParams = {
6
+ table: string;
7
+ page: string | number;
8
+ limit: string | number;
9
+ allRecords?: boolean;
10
+ filters?: Condition | null;
11
+ query?: string;
12
+ columns?: (Pick<BaseTypeColumn, "searchable" | "searchableName"> & StandardColumn)[];
13
+ customQuery?: string;
14
+ selectExpression?: string;
15
+ join?: string;
16
+ groupBy?: string;
17
+ having?: string;
18
+ orderBy?: string | null;
19
+ primaryId?: string;
20
+ };
21
+ type RecordQueryResult = {
22
+ rows: DatabaseRow[];
23
+ queryString: string;
24
+ input: {
25
+ query: string;
26
+ params: RecordQueryParams;
27
+ };
28
+ count: NonNullable<DatabaseRow[string]> | undefined;
29
+ error?: never;
30
+ } | {
31
+ error: Error;
32
+ rows?: never;
33
+ queryString?: never;
34
+ input?: never;
35
+ count?: never;
36
+ };
37
+ export declare function sqlAnd(conditions: (Condition | null | undefined)[]): Condition | null;
38
+ export declare function collectAllowedQueries(node: unknown, acc?: Set<string>): Set<string>;
39
+ declare const _default: (db: Pick<dbManager, "query" | "dbType">) => {
40
+ getRecords: (params: RecordQueryParams, computeCount?: boolean) => Promise<RecordQueryResult>;
41
+ findRecordByPosition: (params: Omit<RecordQueryParams, "page" | "limit"> & {
42
+ position: string | number;
43
+ offset: string | number;
44
+ page?: string | number;
45
+ limit?: string | number;
46
+ }) => Promise<RecordQueryResult>;
47
+ };
48
+ export default _default;