apexrest 1.3.0-beta.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -140
- package/dist/codex-compat/.claude-plugin/marketplace.json +20 -0
- package/dist/codex-compat/plugins/apexrest-apex/.claude-plugin/plugin.json +28 -0
- package/dist/codex-compat/plugins/apexrest-apex/.codex-plugin/plugin.json +7 -7
- package/dist/codex-compat/plugins/apexrest-apex/resources/blocks/generator.json +1 -1
- package/dist/codex-compat/plugins/apexrest-apex/resources/blocks/manifest.json +6 -6
- package/dist/codex-compat/plugins/apexrest-apex/resources/blocks/packages/analytics/status-summary/1.0.0/block.yaml +1 -1
- package/dist/codex-compat/plugins/apexrest-apex/resources/blocks/packages/crud/report-dialog/1.0.0/block.yaml +1 -1
- package/dist/codex-compat/plugins/apexrest-apex/resources/blocks/packages/read/detail/1.0.0/block.yaml +1 -1
- package/dist/codex-compat/plugins/apexrest-apex/resources/blocks/packages/read/filtered-list/1.0.0/block.yaml +1 -1
- package/dist/codex-compat/plugins/apexrest-apex/resources/blocks/packages/read/history/1.0.0/block.yaml +1 -1
- package/dist/codex-compat/plugins/apexrest-apex/resources/blocks/packages/read/master-detail/1.0.0/block.yaml +1 -1
- package/dist/codex-compat/plugins/apexrest-apex/resources/schemas/composer-blueprint.schema.json +5 -4
- package/dist/codex-compat/plugins/apexrest-apex/resources/schemas/composer-contract.schema.json +2 -2
- package/dist/codex-compat/plugins/apexrest-apex/resources/schemas/composer-entity.schema.json +2 -1
- package/dist/codex-compat/plugins/apexrest-apex/resources/schemas/composer-field.schema.json +2 -1
- package/dist/codex-compat/plugins/apexrest-apex/resources/schemas/composer-instance.schema.json +1 -1
- package/dist/codex-compat/plugins/apexrest-apex/resources/schemas/composer-operation.schema.json +1 -1
- package/dist/codex-compat/plugins/apexrest-apex/resources/schemas/composer-plan.schema.json +5 -4
- package/dist/codex-compat/plugins/apexrest-apex/resources/schemas/deploy-plan.schema.json +18 -24
- package/dist/codex-compat/plugins/apexrest-apex/resources/schemas/operations.schema.json +352 -569
- package/dist/codex-compat/plugins/apexrest-apex/resources/schemas/policy.schema.json +21 -0
- package/dist/codex-compat/plugins/apexrest-apex/resources/schemas/project.schema.json +4 -7
- package/dist/codex-compat/plugins/apexrest-apex/resources/templates/blank-app/README.md +0 -2
- package/dist/codex-compat/plugins/apexrest-apex/resources/templates/customer-crm/README.md +1 -3
- package/dist/codex-compat/plugins/apexrest-apex/resources/templates/existing-app/README.md +0 -2
- package/dist/codex-compat/plugins/apexrest-apex/runtime/apexrest.mjs +70 -44
- package/dist/codex-compat/plugins/apexrest-apex/runtime/chunk-5PCC7GZM.mjs +4090 -0
- package/dist/codex-compat/plugins/apexrest-apex/runtime/chunk-BVPAS3TD.mjs +18 -0
- package/dist/codex-compat/plugins/apexrest-apex/runtime/chunk-CVMECW6D.mjs +65 -0
- package/dist/codex-compat/plugins/apexrest-apex/runtime/{chunk-EBBEN4AV.mjs → chunk-JYN3YHP3.mjs} +4220 -10639
- package/dist/codex-compat/plugins/apexrest-apex/runtime/chunk-KGTE7Q5Y.mjs +23 -0
- package/dist/{runtime/chunk-33GE2NWZ.mjs → codex-compat/plugins/apexrest-apex/runtime/chunk-KKRFM7Q7.mjs} +21 -4
- package/dist/codex-compat/plugins/apexrest-apex/runtime/{chunk-2VBZESVC.mjs → chunk-MNU54A7W.mjs} +7 -1
- package/dist/codex-compat/plugins/apexrest-apex/runtime/chunk-N4C2SKCN.mjs +6912 -0
- package/dist/{runtime/chunk-KQ5IDT7Z.mjs → codex-compat/plugins/apexrest-apex/runtime/chunk-P3CVQAZW.mjs} +822 -102
- package/dist/{runtime/chunk-BAHECVGO.mjs → codex-compat/plugins/apexrest-apex/runtime/chunk-QKYF6N6U.mjs} +192 -114
- package/dist/codex-compat/plugins/apexrest-apex/runtime/{chunk-G3KR57BY.mjs → chunk-RBJJNQ5O.mjs} +7 -7
- package/dist/codex-compat/plugins/apexrest-apex/runtime/{chunk-YPLIIQ4Y.mjs → chunk-TMSMKVRP.mjs} +486 -352
- package/dist/codex-compat/plugins/apexrest-apex/runtime/{chunk-2Z3BZF66.mjs → chunk-WPS3CSQJ.mjs} +124 -11
- package/dist/codex-compat/plugins/apexrest-apex/runtime/mcp.mjs +5 -10
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-apexlang/SKILL.md +22 -25
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-apexlang/agents/openai.yaml +3 -3
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-apexlang/references/component-routes.md +1 -5
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-pattern-catalog/SKILL.md +4 -4
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-pattern-catalog/agents/openai.yaml +1 -1
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-pattern-catalog/references/capture-and-curation.md +2 -2
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-safety/SKILL.md +18 -0
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-safety/agents/openai.yaml +4 -0
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-setup/SKILL.md +20 -10
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-setup/agents/openai.yaml +3 -3
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-work/SKILL.md +11 -8
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-work/agents/openai.yaml +3 -3
- package/dist/resources/blocks/generator.json +1 -1
- package/dist/resources/blocks/manifest.json +6 -6
- package/dist/resources/blocks/packages/analytics/status-summary/1.0.0/block.yaml +1 -1
- package/dist/resources/blocks/packages/crud/report-dialog/1.0.0/block.yaml +1 -1
- package/dist/resources/blocks/packages/read/detail/1.0.0/block.yaml +1 -1
- package/dist/resources/blocks/packages/read/filtered-list/1.0.0/block.yaml +1 -1
- package/dist/resources/blocks/packages/read/history/1.0.0/block.yaml +1 -1
- package/dist/resources/blocks/packages/read/master-detail/1.0.0/block.yaml +1 -1
- package/dist/resources/schemas/composer-blueprint.schema.json +5 -4
- package/dist/resources/schemas/composer-contract.schema.json +2 -2
- package/dist/resources/schemas/composer-entity.schema.json +2 -1
- package/dist/resources/schemas/composer-field.schema.json +2 -1
- package/dist/resources/schemas/composer-instance.schema.json +1 -1
- package/dist/resources/schemas/composer-operation.schema.json +1 -1
- package/dist/resources/schemas/composer-plan.schema.json +5 -4
- package/dist/resources/schemas/deploy-plan.schema.json +18 -24
- package/dist/resources/schemas/operations.schema.json +352 -569
- package/dist/resources/schemas/policy.schema.json +21 -0
- package/dist/resources/schemas/project.schema.json +4 -7
- package/dist/resources/templates/blank-app/README.md +0 -2
- package/dist/resources/templates/customer-crm/README.md +1 -3
- package/dist/resources/templates/existing-app/README.md +0 -2
- package/dist/runtime/apexrest.mjs +70 -44
- package/dist/runtime/chunk-5PCC7GZM.mjs +4090 -0
- package/dist/runtime/chunk-BVPAS3TD.mjs +18 -0
- package/dist/runtime/chunk-CVMECW6D.mjs +65 -0
- package/dist/runtime/{chunk-EBBEN4AV.mjs → chunk-JYN3YHP3.mjs} +4220 -10639
- package/dist/runtime/chunk-KGTE7Q5Y.mjs +23 -0
- package/dist/{codex-compat/plugins/apexrest-apex/runtime/chunk-33GE2NWZ.mjs → runtime/chunk-KKRFM7Q7.mjs} +21 -4
- package/dist/runtime/{chunk-2VBZESVC.mjs → chunk-MNU54A7W.mjs} +7 -1
- package/dist/runtime/chunk-N4C2SKCN.mjs +6912 -0
- package/dist/{codex-compat/plugins/apexrest-apex/runtime/chunk-KQ5IDT7Z.mjs → runtime/chunk-P3CVQAZW.mjs} +822 -102
- package/dist/{codex-compat/plugins/apexrest-apex/runtime/chunk-BAHECVGO.mjs → runtime/chunk-QKYF6N6U.mjs} +192 -114
- package/dist/runtime/{chunk-G3KR57BY.mjs → chunk-RBJJNQ5O.mjs} +7 -7
- package/dist/runtime/{chunk-YPLIIQ4Y.mjs → chunk-TMSMKVRP.mjs} +486 -352
- package/dist/runtime/{chunk-2Z3BZF66.mjs → chunk-WPS3CSQJ.mjs} +124 -11
- package/dist/runtime/mcp.mjs +5 -10
- package/package.json +6 -6
- package/README.uk.md +0 -212
- package/dist/codex-compat/plugins/apexrest-apex/resources/panel/index.html +0 -68
- package/dist/codex-compat/plugins/apexrest-apex/resources/panel/panel.css +0 -627
- package/dist/codex-compat/plugins/apexrest-apex/resources/panel/panel.js +0 -861
- package/dist/codex-compat/plugins/apexrest-apex/resources/templates/blank-app/README.uk.md +0 -5
- package/dist/codex-compat/plugins/apexrest-apex/resources/templates/customer-crm/README.uk.md +0 -7
- package/dist/codex-compat/plugins/apexrest-apex/resources/templates/database-control/install.sql +0 -17
- package/dist/codex-compat/plugins/apexrest-apex/resources/templates/existing-app/README.uk.md +0 -9
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__@playwright__test__LICENSE +0 -202
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__@playwright__test__NOTICE +0 -5
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__@types__node__LICENSE +0 -21
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__@types__yauzl__LICENSE +0 -21
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__@typescript__typescript-darwin-arm64__LICENSE +0 -55
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__@typescript__typescript-darwin-arm64__NOTICE.txt +0 -436
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__esbuild__LICENSE.md +0 -21
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__fflate__LICENSE +0 -21
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__marked__LICENSE +0 -44
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__playwright-core__LICENSE +0 -202
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__playwright-core__NOTICE +0 -5
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__playwright__LICENSE +0 -202
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__playwright__NOTICE +0 -5
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__prettier__LICENSE +0 -7
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__typescript__LICENSE +0 -55
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__typescript__NOTICE.txt +0 -436
- package/dist/codex-compat/plugins/apexrest-apex/resources/third-party/node_modules__undici-types__LICENSE +0 -21
- package/dist/codex-compat/plugins/apexrest-apex/runtime/chunk-2BBNJVKW.mjs +0 -1996
- package/dist/codex-compat/plugins/apexrest-apex/runtime/chunk-5JI3XEAK.mjs +0 -14
- package/dist/codex-compat/plugins/apexrest-apex/runtime/chunk-CYPFCUNE.mjs +0 -150
- package/dist/codex-compat/plugins/apexrest-apex/runtime/chunk-ESDVN7DS.mjs +0 -14
- package/dist/codex-compat/plugins/apexrest-apex/runtime/chunk-FTTPESNK.mjs +0 -203
- package/dist/codex-compat/plugins/apexrest-apex/runtime/chunk-HKJVCGQQ.mjs +0 -1302
- package/dist/codex-compat/plugins/apexrest-apex/runtime/chunk-RWGJITHZ.mjs +0 -992
- package/dist/codex-compat/plugins/apexrest-apex/runtime/chunk-TLYYCRQA.mjs +0 -329
- package/dist/codex-compat/plugins/apexrest-apex/runtime/chunk-WXP75UUP.mjs +0 -18
- package/dist/codex-compat/plugins/apexrest-apex/runtime/chunk-YQHHPRJH.mjs +0 -14
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-compose/SKILL.md +0 -18
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-compose/agents/openai.yaml +0 -4
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-compose/references/workflow.md +0 -15
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-database/SKILL.md +0 -9
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-database/agents/openai.yaml +0 -4
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-debug/SKILL.md +0 -9
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-debug/agents/openai.yaml +0 -4
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-deploy/SKILL.md +0 -21
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-deploy/agents/openai.yaml +0 -4
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-install-dependencies/SKILL.md +0 -38
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-install-dependencies/agents/openai.yaml +0 -4
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-menu/SKILL.md +0 -30
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-menu/agents/openai.yaml +0 -4
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-menu/references/cli-catalog.md +0 -30
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-panel/SKILL.md +0 -14
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-panel/agents/openai.yaml +0 -4
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-project/SKILL.md +0 -11
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-project/agents/openai.yaml +0 -4
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-review/SKILL.md +0 -11
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-review/agents/openai.yaml +0 -4
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-test/SKILL.md +0 -29
- package/dist/codex-compat/plugins/apexrest-apex/skills/apexrest-test/agents/openai.yaml +0 -4
- package/dist/resources/panel/index.html +0 -68
- package/dist/resources/panel/panel.css +0 -627
- package/dist/resources/panel/panel.js +0 -861
- package/dist/resources/templates/blank-app/README.uk.md +0 -5
- package/dist/resources/templates/customer-crm/README.uk.md +0 -7
- package/dist/resources/templates/database-control/install.sql +0 -17
- package/dist/resources/templates/existing-app/README.uk.md +0 -9
- package/dist/resources/third-party/node_modules__@playwright__test__LICENSE +0 -202
- package/dist/resources/third-party/node_modules__@playwright__test__NOTICE +0 -5
- package/dist/resources/third-party/node_modules__@types__node__LICENSE +0 -21
- package/dist/resources/third-party/node_modules__@types__yauzl__LICENSE +0 -21
- package/dist/resources/third-party/node_modules__@typescript__typescript-darwin-arm64__LICENSE +0 -55
- package/dist/resources/third-party/node_modules__@typescript__typescript-darwin-arm64__NOTICE.txt +0 -436
- package/dist/resources/third-party/node_modules__esbuild__LICENSE.md +0 -21
- package/dist/resources/third-party/node_modules__fflate__LICENSE +0 -21
- package/dist/resources/third-party/node_modules__marked__LICENSE +0 -44
- package/dist/resources/third-party/node_modules__playwright-core__LICENSE +0 -202
- package/dist/resources/third-party/node_modules__playwright-core__NOTICE +0 -5
- package/dist/resources/third-party/node_modules__playwright__LICENSE +0 -202
- package/dist/resources/third-party/node_modules__playwright__NOTICE +0 -5
- package/dist/resources/third-party/node_modules__prettier__LICENSE +0 -7
- package/dist/resources/third-party/node_modules__typescript__LICENSE +0 -55
- package/dist/resources/third-party/node_modules__typescript__NOTICE.txt +0 -436
- package/dist/resources/third-party/node_modules__undici-types__LICENSE +0 -21
- package/dist/runtime/chunk-2BBNJVKW.mjs +0 -1996
- package/dist/runtime/chunk-5JI3XEAK.mjs +0 -14
- package/dist/runtime/chunk-CYPFCUNE.mjs +0 -150
- package/dist/runtime/chunk-ESDVN7DS.mjs +0 -14
- package/dist/runtime/chunk-FTTPESNK.mjs +0 -203
- package/dist/runtime/chunk-HKJVCGQQ.mjs +0 -1302
- package/dist/runtime/chunk-RWGJITHZ.mjs +0 -992
- package/dist/runtime/chunk-TLYYCRQA.mjs +0 -329
- package/dist/runtime/chunk-WXP75UUP.mjs +0 -18
- package/dist/runtime/chunk-YQHHPRJH.mjs +0 -14
|
@@ -1,1302 +0,0 @@
|
|
|
1
|
-
import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
JobService,
|
|
4
|
-
PanelService,
|
|
5
|
-
composeMaterialize,
|
|
6
|
-
composeMaterializeInput,
|
|
7
|
-
composePlan,
|
|
8
|
-
composePlanInput,
|
|
9
|
-
metadataInputSchema,
|
|
10
|
-
metadataRead,
|
|
11
|
-
panelActionSchema,
|
|
12
|
-
panelReadSchema,
|
|
13
|
-
publicPanelActionSchema
|
|
14
|
-
} from "./chunk-2BBNJVKW.mjs";
|
|
15
|
-
import {
|
|
16
|
-
ArtifactService,
|
|
17
|
-
DeploymentService,
|
|
18
|
-
SyncStore,
|
|
19
|
-
TestService,
|
|
20
|
-
catalogRead,
|
|
21
|
-
catalogSearch,
|
|
22
|
-
checkpoint
|
|
23
|
-
} from "./chunk-YPLIIQ4Y.mjs";
|
|
24
|
-
import {
|
|
25
|
-
VERSION
|
|
26
|
-
} from "./chunk-G3KR57BY.mjs";
|
|
27
|
-
import {
|
|
28
|
-
OracleAdapter,
|
|
29
|
-
configureConnection,
|
|
30
|
-
configureSqlcl,
|
|
31
|
-
connections,
|
|
32
|
-
databaseTransport,
|
|
33
|
-
editConnection,
|
|
34
|
-
environment,
|
|
35
|
-
external_exports,
|
|
36
|
-
installSources,
|
|
37
|
-
loadProject,
|
|
38
|
-
managedHome,
|
|
39
|
-
ordsUrl,
|
|
40
|
-
ordsUsername,
|
|
41
|
-
parse,
|
|
42
|
-
projectInit,
|
|
43
|
-
projectInspect,
|
|
44
|
-
refName,
|
|
45
|
-
relativePath,
|
|
46
|
-
requireTrust,
|
|
47
|
-
resolveConnection,
|
|
48
|
-
resourceRoot,
|
|
49
|
-
runProcess,
|
|
50
|
-
runtimeState,
|
|
51
|
-
savedConnectionName,
|
|
52
|
-
sqlclConfig,
|
|
53
|
-
sqlclMode,
|
|
54
|
-
sqlclRestriction
|
|
55
|
-
} from "./chunk-EBBEN4AV.mjs";
|
|
56
|
-
import {
|
|
57
|
-
Fault,
|
|
58
|
-
artifactPage,
|
|
59
|
-
canonical,
|
|
60
|
-
contained,
|
|
61
|
-
exists,
|
|
62
|
-
failure,
|
|
63
|
-
hash,
|
|
64
|
-
readJson,
|
|
65
|
-
redact,
|
|
66
|
-
sanitized,
|
|
67
|
-
success,
|
|
68
|
-
writeJson
|
|
69
|
-
} from "./chunk-2Z3BZF66.mjs";
|
|
70
|
-
|
|
71
|
-
// packages/core/src/operations.ts
|
|
72
|
-
var project = external_exports.string().min(1).max(4096).optional();
|
|
73
|
-
var env = refName;
|
|
74
|
-
var base = { project };
|
|
75
|
-
var dependencies = {
|
|
76
|
-
home: external_exports.string().optional(),
|
|
77
|
-
yes: external_exports.boolean().default(false),
|
|
78
|
-
nonInteractive: external_exports.boolean().default(false),
|
|
79
|
-
offline: external_exports.boolean().default(false),
|
|
80
|
-
cacheDir: external_exports.string().optional(),
|
|
81
|
-
dryRun: external_exports.boolean().default(false),
|
|
82
|
-
acceptOracleLicense: external_exports.boolean().default(false),
|
|
83
|
-
skipBrowser: external_exports.boolean().default(false),
|
|
84
|
-
installOsDeps: external_exports.boolean().default(false)
|
|
85
|
-
};
|
|
86
|
-
var setup = {
|
|
87
|
-
...base,
|
|
88
|
-
...dependencies,
|
|
89
|
-
from: external_exports.string().optional(),
|
|
90
|
-
codexHome: external_exports.string().optional(),
|
|
91
|
-
scope: external_exports.enum(["user", "project"]).default("user"),
|
|
92
|
-
version: external_exports.string().optional(),
|
|
93
|
-
nativeOnly: external_exports.boolean().default(false)
|
|
94
|
-
};
|
|
95
|
-
var schemas = {
|
|
96
|
-
version: external_exports.strictObject({}),
|
|
97
|
-
doctor: external_exports.strictObject(base),
|
|
98
|
-
"sqlcl.status": external_exports.strictObject({}),
|
|
99
|
-
"sqlcl.configure": external_exports.strictObject({
|
|
100
|
-
mode: sqlclMode,
|
|
101
|
-
mcpRestrictLevel: sqlclRestriction.optional(),
|
|
102
|
-
databaseTransport: databaseTransport.optional()
|
|
103
|
-
}),
|
|
104
|
-
"panel.open": panelReadSchema,
|
|
105
|
-
"panel.status": panelReadSchema,
|
|
106
|
-
"panel.action": publicPanelActionSchema,
|
|
107
|
-
setup: external_exports.strictObject(setup),
|
|
108
|
-
"dependencies.install": external_exports.strictObject(dependencies),
|
|
109
|
-
"dependencies.uninstall": external_exports.strictObject({
|
|
110
|
-
home: external_exports.string().optional(),
|
|
111
|
-
dryRun: external_exports.boolean().default(false),
|
|
112
|
-
yes: external_exports.boolean().default(false)
|
|
113
|
-
}),
|
|
114
|
-
"plugin.validate": external_exports.strictObject({ ...base, from: external_exports.string().optional() }),
|
|
115
|
-
"plugin.install": external_exports.strictObject(setup),
|
|
116
|
-
"plugin.update": external_exports.strictObject({ ...setup, version: external_exports.string().min(1) }),
|
|
117
|
-
"plugin.uninstall": external_exports.strictObject({
|
|
118
|
-
...base,
|
|
119
|
-
home: external_exports.string().optional(),
|
|
120
|
-
keepRuntime: external_exports.boolean().default(false)
|
|
121
|
-
}),
|
|
122
|
-
"project.init": external_exports.strictObject({
|
|
123
|
-
...base,
|
|
124
|
-
directory: external_exports.string().min(1),
|
|
125
|
-
template: external_exports.enum(["blank-app", "customer-crm", "existing-app"]).default("blank-app"),
|
|
126
|
-
alias: refName.optional()
|
|
127
|
-
}),
|
|
128
|
-
"project.adopt": external_exports.strictObject({
|
|
129
|
-
...base,
|
|
130
|
-
env,
|
|
131
|
-
appId: external_exports.number().int().positive(),
|
|
132
|
-
workingCopy: external_exports.boolean().default(false)
|
|
133
|
-
}),
|
|
134
|
-
"project.inspect": external_exports.strictObject({ ...base, detail: external_exports.enum(["full", "summary"]).default("full") }),
|
|
135
|
-
"connection.add": external_exports.strictObject({
|
|
136
|
-
...base,
|
|
137
|
-
name: refName,
|
|
138
|
-
sqlclName: savedConnectionName.optional(),
|
|
139
|
-
ordsUrl: ordsUrl.optional(),
|
|
140
|
-
ordsUsername: ordsUsername.optional(),
|
|
141
|
-
passwordFile: external_exports.string().min(1).max(4096).optional()
|
|
142
|
-
}).refine(
|
|
143
|
-
(value) => !!value.sqlclName || !!(value.ordsUrl && value.ordsUsername),
|
|
144
|
-
"Supply a direct SQLcl name or ORDS URL and username."
|
|
145
|
-
),
|
|
146
|
-
"connection.list": external_exports.strictObject({ ...base, saved: external_exports.boolean().default(false) }),
|
|
147
|
-
"connection.test": external_exports.strictObject({
|
|
148
|
-
...base,
|
|
149
|
-
name: savedConnectionName,
|
|
150
|
-
saved: external_exports.boolean().default(false)
|
|
151
|
-
}),
|
|
152
|
-
"connection.remove": external_exports.strictObject({ ...base, name: refName }),
|
|
153
|
-
"compose.plan": composePlanInput,
|
|
154
|
-
"compose.materialize": composeMaterializeInput,
|
|
155
|
-
"docs.search": external_exports.strictObject({
|
|
156
|
-
...base,
|
|
157
|
-
query: external_exports.string().min(1).max(256),
|
|
158
|
-
corpus: external_exports.enum(["apexlang", "components", "patterns", "blocks", "blueprints"]).default("apexlang"),
|
|
159
|
-
version: external_exports.string().optional(),
|
|
160
|
-
kind: external_exports.enum(["grammar", "template", "contract", "guide"]).optional(),
|
|
161
|
-
family: external_exports.string().min(1).max(200).optional(),
|
|
162
|
-
profile: external_exports.string().max(200).optional(),
|
|
163
|
-
status: external_exports.enum(["draft", "experimental", "verified", "deprecated", "revoked"]).optional(),
|
|
164
|
-
locale: external_exports.enum(["en", "uk"]).optional(),
|
|
165
|
-
cursor: external_exports.string().regex(/^[a-f0-9]{64}$/).optional(),
|
|
166
|
-
offset: external_exports.number().int().min(0).max(1e4).default(0),
|
|
167
|
-
limit: external_exports.number().int().min(1).max(8).default(3)
|
|
168
|
-
}),
|
|
169
|
-
"docs.read": external_exports.strictObject({
|
|
170
|
-
...base,
|
|
171
|
-
id: external_exports.string().max(200),
|
|
172
|
-
offset: external_exports.number().int().min(0).default(0),
|
|
173
|
-
limit: external_exports.number().int().min(1).max(8192).default(4096)
|
|
174
|
-
}),
|
|
175
|
-
"docs.sync": external_exports.strictObject({ version: external_exports.string().min(1), dryRun: external_exports.boolean().default(false) }),
|
|
176
|
-
"metadata.read": metadataInputSchema.extend({ ...base, env }).strict(),
|
|
177
|
-
"apex.generate": external_exports.strictObject({
|
|
178
|
-
...base,
|
|
179
|
-
name: external_exports.string().min(1).max(120),
|
|
180
|
-
output: relativePath,
|
|
181
|
-
alias: refName.optional()
|
|
182
|
-
}),
|
|
183
|
-
"apex.sync": external_exports.strictObject({ ...base, env, action: external_exports.enum(["init", "status", "refresh", "invalidate"]) }),
|
|
184
|
-
"apex.export": external_exports.strictObject({ ...base, env, output: relativePath }),
|
|
185
|
-
"apex.validate": external_exports.strictObject({ ...base, env: env.optional() }),
|
|
186
|
-
"apex.diff": external_exports.strictObject({ ...base, env, comparison: external_exports.enum(["auto", "live"]).default("auto") }),
|
|
187
|
-
"db.plan": external_exports.strictObject({ ...base, env }),
|
|
188
|
-
"deploy.plan": external_exports.strictObject({ ...base, env, out: relativePath }),
|
|
189
|
-
"deploy.apply": external_exports.strictObject({ ...base, plan: relativePath }),
|
|
190
|
-
"deploy.status": external_exports.strictObject({ ...base, run: external_exports.uuid() }),
|
|
191
|
-
"deploy.restore-plan": external_exports.strictObject({ ...base, backup: external_exports.uuid(), out: relativePath }),
|
|
192
|
-
"test.run": external_exports.strictObject({
|
|
193
|
-
...base,
|
|
194
|
-
suite: external_exports.enum(["unit", "sql", "api", "e2e", "all"]),
|
|
195
|
-
env: env.optional(),
|
|
196
|
-
headed: external_exports.boolean().default(false)
|
|
197
|
-
}),
|
|
198
|
-
"test.report": external_exports.strictObject({ ...base, run: external_exports.uuid() }),
|
|
199
|
-
"test.auth": external_exports.strictObject({ ...base, env }),
|
|
200
|
-
"browser.open": external_exports.strictObject({ ...base, env, browserMode: external_exports.enum(["codex", "external"]).optional() }),
|
|
201
|
-
"jobs.status": external_exports.strictObject({
|
|
202
|
-
...base,
|
|
203
|
-
id: external_exports.uuid(),
|
|
204
|
-
waitSeconds: external_exports.number().int().min(0).max(30).default(0)
|
|
205
|
-
}),
|
|
206
|
-
"jobs.cancel": external_exports.strictObject({ ...base, id: external_exports.uuid() }),
|
|
207
|
-
"artifacts.read": external_exports.strictObject({
|
|
208
|
-
...base,
|
|
209
|
-
id: external_exports.uuid(),
|
|
210
|
-
offset: external_exports.number().int().min(0).default(0),
|
|
211
|
-
limit: external_exports.number().int().min(1).max(16384).default(4096)
|
|
212
|
-
}),
|
|
213
|
-
"sandbox.up": external_exports.strictObject(base),
|
|
214
|
-
"sandbox.status": external_exports.strictObject(base),
|
|
215
|
-
"sandbox.down": external_exports.strictObject(base)
|
|
216
|
-
};
|
|
217
|
-
var toolCatalog = [
|
|
218
|
-
{
|
|
219
|
-
name: "apexrest_compose_plan",
|
|
220
|
-
operation: "compose.plan",
|
|
221
|
-
description: "Create an immutable Composer plan. Offline by default; connected requires an explicit environment. No import or database writes. Full plans are artifacts.",
|
|
222
|
-
readOnly: false,
|
|
223
|
-
destructive: false,
|
|
224
|
-
long: true
|
|
225
|
-
},
|
|
226
|
-
{
|
|
227
|
-
name: "apexrest_compose_materialize",
|
|
228
|
-
operation: "compose.materialize",
|
|
229
|
-
description: "Apply a reviewed Composer plan using its expected digest. Journaled local source writes only; never deploys. Recovery is explicit.",
|
|
230
|
-
readOnly: false,
|
|
231
|
-
destructive: false,
|
|
232
|
-
long: true
|
|
233
|
-
},
|
|
234
|
-
{
|
|
235
|
-
name: "apexrest_browser_open",
|
|
236
|
-
operation: "browser.open",
|
|
237
|
-
description: "Open a configured APEX environment in the selected browser. Codex returns a host handoff; external launches the system browser. Opening is not verification or test authorization.",
|
|
238
|
-
readOnly: false,
|
|
239
|
-
destructive: false
|
|
240
|
-
},
|
|
241
|
-
{
|
|
242
|
-
name: "apexrest_panel_open",
|
|
243
|
-
operation: "panel.open",
|
|
244
|
-
description: "Open the Codex development panel: private local URL and optional native UI for settings and APEX jobs.",
|
|
245
|
-
readOnly: false,
|
|
246
|
-
destructive: false
|
|
247
|
-
},
|
|
248
|
-
{
|
|
249
|
-
name: "apexrest_panel_status",
|
|
250
|
-
operation: "panel.status",
|
|
251
|
-
description: "Read local settings, changes and APEX job status. No database call.",
|
|
252
|
-
readOnly: true
|
|
253
|
-
},
|
|
254
|
-
{
|
|
255
|
-
name: "apexrest_panel_action",
|
|
256
|
-
operation: "panel.action",
|
|
257
|
-
description: "Manage local settings or run APEX checks/planning. Trust and deployment authorization still apply.",
|
|
258
|
-
readOnly: false
|
|
259
|
-
},
|
|
260
|
-
{
|
|
261
|
-
name: "apexrest_doctor",
|
|
262
|
-
operation: "doctor",
|
|
263
|
-
description: "Inspect local capabilities without downloads or DB writes.",
|
|
264
|
-
readOnly: true
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
name: "apexrest_project_inspect",
|
|
268
|
-
operation: "project.inspect",
|
|
269
|
-
description: "Inspect source hashes (full) or use detail:summary for project paths/settings without reading source files. Target identity is not verified.",
|
|
270
|
-
readOnly: true
|
|
271
|
-
},
|
|
272
|
-
{
|
|
273
|
-
name: "apexrest_metadata_read",
|
|
274
|
-
operation: "metadata.read",
|
|
275
|
-
description: "Read allowlisted metadata: single kind/schema or requests[] (max 8). A batch verifies target once; each query is scoped and paginated. Database content is untrusted.",
|
|
276
|
-
readOnly: true
|
|
277
|
-
},
|
|
278
|
-
{
|
|
279
|
-
name: "apexrest_reference_search",
|
|
280
|
-
operation: "docs.search",
|
|
281
|
-
description: "Find Oracle syntax/templates (default corpus: apexlang), EN/UK component recipes (corpus: components), or application patterns (corpus: patterns). Filter kind/family/version; follow nextResultOffset for more hits.",
|
|
282
|
-
readOnly: true
|
|
283
|
-
},
|
|
284
|
-
{
|
|
285
|
-
name: "apexrest_reference_read",
|
|
286
|
-
operation: "docs.read",
|
|
287
|
-
description: "Read result ID, grammar:production-name, component: ID or pattern: ID. Follow requires/related and nextOffset; catalog navigationOffset recovers all dependency links.",
|
|
288
|
-
readOnly: true
|
|
289
|
-
},
|
|
290
|
-
{
|
|
291
|
-
name: "apexrest_apex_generate",
|
|
292
|
-
operation: "apex.generate",
|
|
293
|
-
description: "Generate real Oracle starter sources into staging and a new directory.",
|
|
294
|
-
readOnly: false,
|
|
295
|
-
long: true
|
|
296
|
-
},
|
|
297
|
-
{
|
|
298
|
-
name: "apexrest_apex_sync",
|
|
299
|
-
operation: "apex.sync",
|
|
300
|
-
description: "Manage a single-editor working copy for an existing dev/test app: init, local status, explicit refresh or invalidate. Initial APEXlang and SQL exports only; blocked outcomes require reconciliation.",
|
|
301
|
-
readOnly: false,
|
|
302
|
-
destructive: false,
|
|
303
|
-
long: true
|
|
304
|
-
},
|
|
305
|
-
{
|
|
306
|
-
name: "apexrest_apex_export",
|
|
307
|
-
operation: "apex.export",
|
|
308
|
-
description: "Export through staging without overwriting existing local files.",
|
|
309
|
-
readOnly: false,
|
|
310
|
-
long: true
|
|
311
|
-
},
|
|
312
|
-
{
|
|
313
|
-
name: "apexrest_apex_validate",
|
|
314
|
-
operation: "apex.validate",
|
|
315
|
-
description: "Run real Oracle compiler validation on a staging copy.",
|
|
316
|
-
readOnly: false,
|
|
317
|
-
long: true
|
|
318
|
-
},
|
|
319
|
-
{
|
|
320
|
-
name: "apexrest_deploy_plan",
|
|
321
|
-
operation: "deploy.plan",
|
|
322
|
-
description: "Read target and write an immutable plan without deployment.",
|
|
323
|
-
readOnly: false,
|
|
324
|
-
long: true
|
|
325
|
-
},
|
|
326
|
-
{
|
|
327
|
-
name: "apexrest_deploy_apply",
|
|
328
|
-
operation: "deploy.apply",
|
|
329
|
-
description: "Apply a fixed plan under external policy, backup and target lease.",
|
|
330
|
-
readOnly: false,
|
|
331
|
-
destructive: true,
|
|
332
|
-
long: true
|
|
333
|
-
},
|
|
334
|
-
{
|
|
335
|
-
name: "apexrest_test_run",
|
|
336
|
-
operation: "test.run",
|
|
337
|
-
description: "Run application tests; remote suites can mutate data and require environment policy.",
|
|
338
|
-
readOnly: false,
|
|
339
|
-
long: true
|
|
340
|
-
},
|
|
341
|
-
{
|
|
342
|
-
name: "apexrest_job_status",
|
|
343
|
-
operation: "jobs.status",
|
|
344
|
-
description: "Read job status; waitSeconds:25 waits for completion without repeated polls. Reuse jobId; never rerun work to retrieve results.",
|
|
345
|
-
readOnly: true
|
|
346
|
-
},
|
|
347
|
-
{
|
|
348
|
-
name: "apexrest_job_cancel",
|
|
349
|
-
operation: "jobs.cancel",
|
|
350
|
-
description: "Request cancellation; database outcome may remain unknown.",
|
|
351
|
-
readOnly: false
|
|
352
|
-
},
|
|
353
|
-
{
|
|
354
|
-
name: "apexrest_artifact_read",
|
|
355
|
-
operation: "artifacts.read",
|
|
356
|
-
description: "Read registered sanitized text by opaque ID and bounded range.",
|
|
357
|
-
readOnly: true
|
|
358
|
-
}
|
|
359
|
-
];
|
|
360
|
-
|
|
361
|
-
// packages/core/src/service.ts
|
|
362
|
-
import path4 from "node:path";
|
|
363
|
-
|
|
364
|
-
// packages/core/src/doctor.ts
|
|
365
|
-
import path from "node:path";
|
|
366
|
-
async function doctor() {
|
|
367
|
-
const state = await runtimeState();
|
|
368
|
-
const java = process.env.APEXREST_JAVA_HOME ? path.join(process.env.APEXREST_JAVA_HOME, "bin", process.platform === "win32" ? "java.exe" : "java") : state.java ?? "java";
|
|
369
|
-
const probes = await Promise.all(
|
|
370
|
-
[
|
|
371
|
-
["codex", ["--version"]],
|
|
372
|
-
[process.env.APEXREST_SQLCL ?? state.sqlcl ?? "sql", ["-version"]],
|
|
373
|
-
[java, ["-version"]]
|
|
374
|
-
].map(async ([exe, args]) => {
|
|
375
|
-
try {
|
|
376
|
-
const r = await runProcess({
|
|
377
|
-
executable: exe,
|
|
378
|
-
args,
|
|
379
|
-
cwd: process.env.TMPDIR ?? process.cwd(),
|
|
380
|
-
timeoutMs: 1e4,
|
|
381
|
-
env: {
|
|
382
|
-
...process.env,
|
|
383
|
-
JAVA_HOME: path.isAbsolute(java) ? path.dirname(path.dirname(java)) : process.env.JAVA_HOME
|
|
384
|
-
}
|
|
385
|
-
});
|
|
386
|
-
return {
|
|
387
|
-
command: exe,
|
|
388
|
-
state: r.code === 0 ? "detected" : "unavailable",
|
|
389
|
-
version: (r.stdout + r.stderr).trim().slice(0, 500)
|
|
390
|
-
};
|
|
391
|
-
} catch {
|
|
392
|
-
return { command: exe, state: "missing" };
|
|
393
|
-
}
|
|
394
|
-
})
|
|
395
|
-
);
|
|
396
|
-
return {
|
|
397
|
-
platform: process.platform,
|
|
398
|
-
architecture: process.arch,
|
|
399
|
-
runtime: {
|
|
400
|
-
executable: process.execPath,
|
|
401
|
-
version: process.version,
|
|
402
|
-
baseline: process.versions.node.split(".")[0] === "24"
|
|
403
|
-
},
|
|
404
|
-
managedComponents: state.components,
|
|
405
|
-
sqlcl: await sqlclConfig(),
|
|
406
|
-
probes,
|
|
407
|
-
database: "not-configured",
|
|
408
|
-
nativeHost: "requires-host-verification",
|
|
409
|
-
telemetry: false
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// packages/core/src/references.ts
|
|
414
|
-
import path3 from "node:path";
|
|
415
|
-
import { stat as stat2, readFile as readFile2 } from "node:fs/promises";
|
|
416
|
-
|
|
417
|
-
// packages/core/src/reference-index.ts
|
|
418
|
-
var referenceWords = (text) => text.replace(/([a-z\d])([A-Z])/g, "$1 $2").toLowerCase().match(/[\p{L}\p{N}]+/gu) ?? [];
|
|
419
|
-
var normalizeReference = (text) => referenceWords(text).join(" ");
|
|
420
|
-
function buildReferencePostings(entries) {
|
|
421
|
-
const postings = /* @__PURE__ */ Object.create(null);
|
|
422
|
-
entries.forEach((entry, position) => {
|
|
423
|
-
for (const word of new Set(referenceWords(entry.id + " " + (entry.title ?? "") + " " + entry.text)))
|
|
424
|
-
(postings[word] ??= []).push(position);
|
|
425
|
-
});
|
|
426
|
-
return postings;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
// packages/core/src/reference-catalog.ts
|
|
430
|
-
import path2 from "node:path";
|
|
431
|
-
import { readFile, realpath, stat } from "node:fs/promises";
|
|
432
|
-
var digest = external_exports.string().regex(/^[a-f0-9]{64}$/);
|
|
433
|
-
var ascii = (max) => external_exports.string().min(1).max(max).regex(/^[\x20-\x7e]+$/);
|
|
434
|
-
var referenceId = ascii(200);
|
|
435
|
-
var compatibilitySchema = external_exports.object({
|
|
436
|
-
apexVersion: ascii(64),
|
|
437
|
-
themeVersion: ascii(64),
|
|
438
|
-
mmdVersion: ascii(64)
|
|
439
|
-
});
|
|
440
|
-
var entrySchema = external_exports.object({
|
|
441
|
-
id: referenceId,
|
|
442
|
-
title: external_exports.string().min(1).max(240),
|
|
443
|
-
kind: external_exports.enum(["contract", "template", "guide"]),
|
|
444
|
-
family: ascii(200),
|
|
445
|
-
version: ascii(120),
|
|
446
|
-
source: ascii(2048),
|
|
447
|
-
document: ascii(240),
|
|
448
|
-
sha256: digest,
|
|
449
|
-
searchText: external_exports.string().max(2e5),
|
|
450
|
-
requires: external_exports.array(referenceId),
|
|
451
|
-
related: external_exports.array(referenceId),
|
|
452
|
-
readiness: external_exports.enum(["ready", "reference", "unresolved"]),
|
|
453
|
-
compatibility: compatibilitySchema,
|
|
454
|
-
length: external_exports.number().int().nonnegative().optional()
|
|
455
|
-
});
|
|
456
|
-
var manifestSchema = external_exports.object({
|
|
457
|
-
schemaVersion: external_exports.literal(1),
|
|
458
|
-
catalogVersion: ascii(120),
|
|
459
|
-
source: external_exports.object({ apexVersion: ascii(64), themeVersion: ascii(64), mmdVersion: ascii(64) }).passthrough(),
|
|
460
|
-
indexSha256: digest,
|
|
461
|
-
files: external_exports.record(external_exports.string(), digest),
|
|
462
|
-
counts: external_exports.record(external_exports.string(), external_exports.unknown())
|
|
463
|
-
});
|
|
464
|
-
function createReferenceCatalog(definition) {
|
|
465
|
-
function invalid(message) {
|
|
466
|
-
throw new Fault(`${definition.faultPrefix}_CATALOG_INVALID`, message, 3);
|
|
467
|
-
}
|
|
468
|
-
function relativeFile(file) {
|
|
469
|
-
if (!/^[A-Za-z0-9_./-]+$/.test(file) || path2.isAbsolute(file) || file.split("/").some((part) => !part || part === "." || part === ".."))
|
|
470
|
-
invalid(`${definition.label} catalog contains an unsafe file path.`);
|
|
471
|
-
return file;
|
|
472
|
-
}
|
|
473
|
-
async function containedFile(root, file) {
|
|
474
|
-
const resolved = await realpath(path2.join(root, relativeFile(file)));
|
|
475
|
-
const relative = path2.relative(root, resolved);
|
|
476
|
-
if (!relative || relative.startsWith(".." + path2.sep) || relative === ".." || path2.isAbsolute(relative))
|
|
477
|
-
invalid(`${definition.label} catalog file resolves outside its resource directory.`);
|
|
478
|
-
return resolved;
|
|
479
|
-
}
|
|
480
|
-
async function stamp(file) {
|
|
481
|
-
const info = await stat(file, { bigint: true });
|
|
482
|
-
return `${info.dev}:${info.ino}:${info.size}:${info.mtimeNs}:${info.ctimeNs}`;
|
|
483
|
-
}
|
|
484
|
-
async function loadIndex(root, manifestFile, indexFile) {
|
|
485
|
-
try {
|
|
486
|
-
const manifest = manifestSchema.parse(JSON.parse(await readFile(manifestFile, "utf8")));
|
|
487
|
-
for (const file of Object.keys(manifest.files)) relativeFile(file);
|
|
488
|
-
if (manifest.files["index.json"] !== manifest.indexSha256)
|
|
489
|
-
invalid(`${definition.label} catalog manifest index hashes disagree.`);
|
|
490
|
-
const raw = await readFile(indexFile, "utf8");
|
|
491
|
-
if (hash(raw) !== manifest.indexSha256)
|
|
492
|
-
invalid(`${definition.label} catalog index checksum does not match its manifest.`);
|
|
493
|
-
const entries = external_exports.array(entrySchema).parse(JSON.parse(raw));
|
|
494
|
-
const byId = /* @__PURE__ */ new Map();
|
|
495
|
-
const searchable = entries.map((entry) => {
|
|
496
|
-
if (!entry.id.startsWith(definition.prefix))
|
|
497
|
-
invalid(`${definition.label} catalog contains a reference ID with an invalid prefix.`);
|
|
498
|
-
relativeFile(entry.document);
|
|
499
|
-
if (!entry.document.startsWith(definition.documentDirectory + "/") || !entry.document.endsWith(".md"))
|
|
500
|
-
invalid(
|
|
501
|
-
`${definition.label} documents must be Markdown files inside ${definition.documentDirectory}/.`
|
|
502
|
-
);
|
|
503
|
-
if (manifest.files[entry.document] !== entry.sha256)
|
|
504
|
-
invalid(`${definition.label} document checksum is missing or disagrees with its manifest.`);
|
|
505
|
-
if (byId.has(entry.id)) invalid(`${definition.label} catalog contains duplicate reference IDs.`);
|
|
506
|
-
byId.set(entry.id, entry);
|
|
507
|
-
return {
|
|
508
|
-
entry,
|
|
509
|
-
words: new Set(referenceWords(`${entry.id} ${entry.title} ${entry.searchText}`)),
|
|
510
|
-
title: normalizeReference(entry.title),
|
|
511
|
-
body: normalizeReference(entry.searchText)
|
|
512
|
-
};
|
|
513
|
-
});
|
|
514
|
-
for (const entry of entries)
|
|
515
|
-
for (const id of [...entry.requires, ...entry.related])
|
|
516
|
-
if (id.startsWith(definition.prefix) && !byId.has(id))
|
|
517
|
-
invalid(
|
|
518
|
-
`${definition.label} catalog contains an unresolved ${definition.label.toLowerCase()} reference.`
|
|
519
|
-
);
|
|
520
|
-
return { root, manifest, byId, searchable };
|
|
521
|
-
} catch (error) {
|
|
522
|
-
if (error instanceof Fault) throw error;
|
|
523
|
-
invalid(`${definition.label} catalog manifest or index cannot be read or has an invalid format.`);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
let cached2;
|
|
527
|
-
async function catalogIndex() {
|
|
528
|
-
let root, manifestFile, indexFile, revision;
|
|
529
|
-
try {
|
|
530
|
-
root = await realpath(path2.join(resourceRoot(), definition.directory));
|
|
531
|
-
manifestFile = await containedFile(root, "manifest.json");
|
|
532
|
-
indexFile = await containedFile(root, "index.json");
|
|
533
|
-
revision = await stamp(manifestFile) + ":" + await stamp(indexFile);
|
|
534
|
-
} catch (error) {
|
|
535
|
-
cached2 = void 0;
|
|
536
|
-
if (error instanceof Fault) throw error;
|
|
537
|
-
throw new Fault(
|
|
538
|
-
`${definition.faultPrefix}_CATALOG_UNAVAILABLE`,
|
|
539
|
-
`Install a reviewed release containing the ${definition.label.toLowerCase()} catalog.`,
|
|
540
|
-
3
|
|
541
|
-
);
|
|
542
|
-
}
|
|
543
|
-
if (cached2?.root === root && cached2.stamp === revision) return cached2.pending;
|
|
544
|
-
const pending = loadIndex(root, manifestFile, indexFile);
|
|
545
|
-
cached2 = { root, stamp: revision, pending };
|
|
546
|
-
try {
|
|
547
|
-
return await pending;
|
|
548
|
-
} catch (error) {
|
|
549
|
-
if (cached2?.pending === pending) cached2 = void 0;
|
|
550
|
-
throw error;
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
const stopwords2 = /* @__PURE__ */ new Set(["a", "an", "the", "for", "with", "and", "of", "to", "in"]);
|
|
554
|
-
const bytes = (value) => Buffer.byteLength(JSON.stringify(sanitized(value)), "utf8");
|
|
555
|
-
function metadata(entry) {
|
|
556
|
-
return {
|
|
557
|
-
id: entry.id,
|
|
558
|
-
title: entry.title,
|
|
559
|
-
kind: entry.kind,
|
|
560
|
-
family: entry.family,
|
|
561
|
-
version: entry.version,
|
|
562
|
-
source: entry.source,
|
|
563
|
-
readiness: entry.readiness,
|
|
564
|
-
compatibility: entry.compatibility,
|
|
565
|
-
classification: definition.classification
|
|
566
|
-
};
|
|
567
|
-
}
|
|
568
|
-
function links(entry, count) {
|
|
569
|
-
return {
|
|
570
|
-
requires: entry.requires.slice(0, count),
|
|
571
|
-
requiresCount: entry.requires.length,
|
|
572
|
-
requiresOmittedCount: Math.max(0, entry.requires.length - count),
|
|
573
|
-
related: entry.related.slice(0, count),
|
|
574
|
-
relatedCount: entry.related.length,
|
|
575
|
-
relatedOmittedCount: Math.max(0, entry.related.length - count)
|
|
576
|
-
};
|
|
577
|
-
}
|
|
578
|
-
function window(text, start, length) {
|
|
579
|
-
let end = Math.min(text.length, start + length);
|
|
580
|
-
if (end > start && /[\uD800-\uDBFF]/.test(text[end - 1]) && /[\uDC00-\uDFFF]/.test(text[end] ?? ""))
|
|
581
|
-
end += end - start === 1 ? 1 : -1;
|
|
582
|
-
return text.slice(start, end);
|
|
583
|
-
}
|
|
584
|
-
async function search(query, version, options = {}) {
|
|
585
|
-
const terms = [...new Set(referenceWords(query).filter((term) => !stopwords2.has(term)))];
|
|
586
|
-
if (!terms.length) return [];
|
|
587
|
-
const index = await catalogIndex();
|
|
588
|
-
const normalized = normalizeReference(query);
|
|
589
|
-
const ranked = index.searchable.filter(
|
|
590
|
-
({ entry, words }) => (entry.id === query.trim() || terms.every((term) => words.has(term))) && (!version || entry.version === version || !version.includes("@") && entry.version.split("@")[0] === version) && (!options.kind || entry.kind === options.kind) && (!options.family || entry.family === options.family || entry.family.startsWith(options.family + "/"))
|
|
591
|
-
).map(({ entry, title, body }) => ({
|
|
592
|
-
entry,
|
|
593
|
-
score: (entry.id === query.trim() ? 1e4 : 0) + (title === normalized ? 2e3 : 0) + (title.includes(normalized) ? 400 : 0) + terms.filter((term) => [...referenceWords(title)].includes(term)).length * 50 + (body.includes(normalized) ? 80 : 0) + (entry.readiness === "ready" ? 10 : 0) + (entry.kind === "contract" ? 5 : 0)
|
|
594
|
-
})).sort((a, b) => b.score - a.score || (a.entry.id < b.entry.id ? -1 : a.entry.id > b.entry.id ? 1 : 0));
|
|
595
|
-
const offset = Math.max(0, options.offset ?? 0), limit = Math.max(1, Math.min(8, options.limit ?? 3));
|
|
596
|
-
const candidates = ranked.slice(offset, offset + limit).map(({ entry }) => {
|
|
597
|
-
const first = terms.map((term) => entry.searchText.toLowerCase().indexOf(term)).filter((n) => n >= 0);
|
|
598
|
-
const matchOffset = first.length ? Math.min(...first) : null;
|
|
599
|
-
let snippetOffset = Math.max(0, (matchOffset ?? 0) - 80);
|
|
600
|
-
if (snippetOffset && /[\uDC00-\uDFFF]/.test(entry.searchText[snippetOffset] ?? "") && /[\uD800-\uDBFF]/.test(entry.searchText[snippetOffset - 1] ?? ""))
|
|
601
|
-
snippetOffset--;
|
|
602
|
-
const text = window(entry.searchText, snippetOffset, 600);
|
|
603
|
-
return {
|
|
604
|
-
...metadata(entry),
|
|
605
|
-
...links(entry, 2),
|
|
606
|
-
text,
|
|
607
|
-
// Index summaries are intentionally independent of documents; read a result at offset 0.
|
|
608
|
-
snippetSource: "index",
|
|
609
|
-
readOffset: 0,
|
|
610
|
-
offset: snippetOffset,
|
|
611
|
-
matchOffset,
|
|
612
|
-
length: entry.searchText.length,
|
|
613
|
-
nextOffset: null,
|
|
614
|
-
totalMatches: ranked.length,
|
|
615
|
-
nextResultOffset: null
|
|
616
|
-
};
|
|
617
|
-
});
|
|
618
|
-
const results = [];
|
|
619
|
-
for (const hit of candidates) {
|
|
620
|
-
while (bytes([...results, hit]) > 7e3 && hit.text.length) {
|
|
621
|
-
const remaining = Math.floor(hit.text.length / 2);
|
|
622
|
-
hit.text = remaining < 2 ? "" : window(hit.text, 0, remaining);
|
|
623
|
-
}
|
|
624
|
-
if (bytes([...results, hit]) > 7e3) break;
|
|
625
|
-
results.push(hit);
|
|
626
|
-
}
|
|
627
|
-
if (!results.length && candidates.length)
|
|
628
|
-
invalid(`${definition.label} result metadata exceeds the response budget.`);
|
|
629
|
-
const next = offset + results.length < ranked.length ? offset + results.length : null;
|
|
630
|
-
for (const result of results) result.nextResultOffset = next;
|
|
631
|
-
return results;
|
|
632
|
-
}
|
|
633
|
-
async function read(id, offset, limit) {
|
|
634
|
-
const index = await catalogIndex();
|
|
635
|
-
const entry = index.byId.get(id);
|
|
636
|
-
if (!entry)
|
|
637
|
-
throw new Fault(
|
|
638
|
-
"REFERENCE_NOT_FOUND",
|
|
639
|
-
`No registered ${definition.label.toLowerCase()} reference with this ID.`,
|
|
640
|
-
2
|
|
641
|
-
);
|
|
642
|
-
let raw;
|
|
643
|
-
try {
|
|
644
|
-
raw = await readFile(await containedFile(index.root, entry.document), "utf8");
|
|
645
|
-
} catch (error) {
|
|
646
|
-
if (error instanceof Fault) throw error;
|
|
647
|
-
invalid(`${definition.label} document cannot be read.`);
|
|
648
|
-
}
|
|
649
|
-
if (hash(raw) !== entry.sha256)
|
|
650
|
-
invalid(`${definition.label} document checksum does not match the catalog.`);
|
|
651
|
-
if (entry.length !== void 0 && entry.length !== raw.length)
|
|
652
|
-
invalid(`${definition.label} document length does not match the catalog.`);
|
|
653
|
-
const navigation = "\n\n## Catalog navigation\n\n" + entry.requires.map((target) => `- requires: ${target}
|
|
654
|
-
`).join("") + entry.related.map((target) => `- related: ${target}
|
|
655
|
-
`).join("");
|
|
656
|
-
const safeRaw = redact(raw);
|
|
657
|
-
const document = safeRaw + redact(navigation);
|
|
658
|
-
const start = Math.max(0, offset);
|
|
659
|
-
let count = Math.max(1, Math.min(8192, limit));
|
|
660
|
-
const create = () => artifactPage(document, "text", id, start, count, {
|
|
661
|
-
...metadata(entry),
|
|
662
|
-
...links(entry, 16),
|
|
663
|
-
length: document.length,
|
|
664
|
-
documentLength: safeRaw.length,
|
|
665
|
-
sourceDocumentLength: raw.length,
|
|
666
|
-
contentSanitized: true,
|
|
667
|
-
navigationOffset: safeRaw.length,
|
|
668
|
-
sha256: entry.sha256
|
|
669
|
-
});
|
|
670
|
-
let result = create();
|
|
671
|
-
while (bytes(result) > 3e4 && count > 1) {
|
|
672
|
-
count = Math.max(1, Math.floor(count / 2));
|
|
673
|
-
result = create();
|
|
674
|
-
}
|
|
675
|
-
if (bytes(result) > 3e4) invalid(`${definition.label} document metadata exceeds the response budget.`);
|
|
676
|
-
return result;
|
|
677
|
-
}
|
|
678
|
-
return { search, read };
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
// packages/core/src/components.ts
|
|
682
|
-
var catalog = createReferenceCatalog({
|
|
683
|
-
directory: "components",
|
|
684
|
-
prefix: "component:",
|
|
685
|
-
documentDirectory: "documents",
|
|
686
|
-
label: "Component",
|
|
687
|
-
faultPrefix: "COMPONENT",
|
|
688
|
-
classification: "component-reference-data"
|
|
689
|
-
});
|
|
690
|
-
var componentSearch = catalog.search;
|
|
691
|
-
var componentRead = catalog.read;
|
|
692
|
-
|
|
693
|
-
// packages/core/src/patterns.ts
|
|
694
|
-
var catalog2 = createReferenceCatalog({
|
|
695
|
-
directory: "patterns",
|
|
696
|
-
prefix: "pattern:",
|
|
697
|
-
documentDirectory: "docs",
|
|
698
|
-
label: "Pattern",
|
|
699
|
-
faultPrefix: "PATTERN",
|
|
700
|
-
classification: "pattern-reference-data"
|
|
701
|
-
});
|
|
702
|
-
var patternSearch = catalog2.search;
|
|
703
|
-
var patternRead = catalog2.read;
|
|
704
|
-
|
|
705
|
-
// packages/core/src/references.ts
|
|
706
|
-
var references = [
|
|
707
|
-
{
|
|
708
|
-
id: "apexlang-lifecycle",
|
|
709
|
-
version: "26.1",
|
|
710
|
-
source: "https://docs.oracle.com/en/database/oracle/sql-developer-command-line/26.1/sqcug/apexlang.html",
|
|
711
|
-
text: 'Generate starter files using apex generate -name "Name" -dir ./fresh. Validate with apex validate -input ./application. Export requires a connection and always uses fresh staging. Import deploys the full application and requires a reviewed plan. Preserve .apex/apexlang.json and its compiler metadata.'
|
|
712
|
-
},
|
|
713
|
-
{
|
|
714
|
-
id: "deployment-safety",
|
|
715
|
-
version: "1.0.0",
|
|
716
|
-
source: "docs/adr/007-clean-apex-deployment.md",
|
|
717
|
-
text: "Use an explicit environment. Plans bind source hashes and target identity. Recheck drift, acquire local coordination by default and create an export backup before writes. Clean APEX deployment needs no service tables. Local runners must share one managed home; independent machines need external serialization or explicitly selected database coordination. DDL cannot be generally rolled back. Interrupted writes require reconciliation. Production requires an external approval boundary."
|
|
718
|
-
}
|
|
719
|
-
];
|
|
720
|
-
var stopwords = /* @__PURE__ */ new Set(["a", "an", "the", "for", "with", "and", "of", "to", "in"]);
|
|
721
|
-
var termsFor = (text) => [...new Set(referenceWords(text).filter((word) => !stopwords.has(word)))];
|
|
722
|
-
function versionMatches(actual, requested) {
|
|
723
|
-
if (!requested) return true;
|
|
724
|
-
return actual === requested || !requested.includes("@") && actual.split("@")[0] === requested;
|
|
725
|
-
}
|
|
726
|
-
function indexReferences(upstream, file, digest2) {
|
|
727
|
-
const entries = [...references, ...upstream];
|
|
728
|
-
const byId = /* @__PURE__ */ new Map();
|
|
729
|
-
const bySymbol = /* @__PURE__ */ new Map();
|
|
730
|
-
const searchable = entries.map((reference) => {
|
|
731
|
-
if (!byId.has(reference.id)) byId.set(reference.id, reference);
|
|
732
|
-
const symbol = reference.text.match(/^<([^>\n]+)>\s*::=/)?.[1];
|
|
733
|
-
if (symbol) bySymbol.set(symbol, reference.id);
|
|
734
|
-
const title = reference.title ?? symbol ?? reference.id;
|
|
735
|
-
return {
|
|
736
|
-
reference,
|
|
737
|
-
title,
|
|
738
|
-
titleText: normalizeReference(title),
|
|
739
|
-
ranking: void 0
|
|
740
|
-
};
|
|
741
|
-
});
|
|
742
|
-
let pendingPostings;
|
|
743
|
-
const postings = () => pendingPostings ??= (async () => {
|
|
744
|
-
if (file) {
|
|
745
|
-
try {
|
|
746
|
-
const prebuilt = await readJson(path3.join(path3.dirname(file), "search.json"));
|
|
747
|
-
if (prebuilt && prebuilt.schemaVersion === 1 && prebuilt.indexSha256 === digest2 && prebuilt.postings && Object.values(prebuilt.postings).every(
|
|
748
|
-
(list) => Array.isArray(list) && list.every(
|
|
749
|
-
(n) => Number.isInteger(n) && Number(n) >= 0 && Number(n) < upstream.length
|
|
750
|
-
)
|
|
751
|
-
)) {
|
|
752
|
-
const result = buildReferencePostings(references);
|
|
753
|
-
for (const [term, list] of Object.entries(prebuilt.postings))
|
|
754
|
-
result[term] = [
|
|
755
|
-
...result[term] ?? [],
|
|
756
|
-
...list.map((position) => position + references.length)
|
|
757
|
-
];
|
|
758
|
-
return result;
|
|
759
|
-
}
|
|
760
|
-
} catch {
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
return buildReferencePostings(entries);
|
|
764
|
-
})();
|
|
765
|
-
return { upstream, byId, bySymbol, searchable, postings, queries: /* @__PURE__ */ new Map() };
|
|
766
|
-
}
|
|
767
|
-
var cached;
|
|
768
|
-
async function referenceIndex() {
|
|
769
|
-
const file = path3.join(resourceRoot(), "references/index.json");
|
|
770
|
-
let info;
|
|
771
|
-
try {
|
|
772
|
-
info = await stat2(file, { bigint: true });
|
|
773
|
-
} catch (error) {
|
|
774
|
-
if (error.code !== "ENOENT") throw error;
|
|
775
|
-
cached = void 0;
|
|
776
|
-
return indexReferences([]);
|
|
777
|
-
}
|
|
778
|
-
const stamp = `${info.dev}:${info.ino}:${info.size}:${info.mtimeNs}:${info.ctimeNs}`;
|
|
779
|
-
if (cached?.file === file && cached.stamp === stamp) return cached.pending;
|
|
780
|
-
const pending = readFile2(file, "utf8").then(
|
|
781
|
-
(raw) => indexReferences(JSON.parse(raw), file, hash(raw))
|
|
782
|
-
);
|
|
783
|
-
cached = { file, stamp, pending };
|
|
784
|
-
try {
|
|
785
|
-
return await pending;
|
|
786
|
-
} catch (error) {
|
|
787
|
-
if (cached?.pending === pending) cached = void 0;
|
|
788
|
-
throw error;
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
function snippet(text, query, terms) {
|
|
792
|
-
const lower = text.toLowerCase();
|
|
793
|
-
let matchOffset = lower.indexOf(query.trim().toLowerCase());
|
|
794
|
-
if (matchOffset < 0) {
|
|
795
|
-
const pattern = referenceWords(query).join("[\\s._:-]*");
|
|
796
|
-
if (pattern) matchOffset = lower.search(new RegExp(pattern, "u"));
|
|
797
|
-
}
|
|
798
|
-
if (matchOffset < 0) {
|
|
799
|
-
const locations = terms.map((term) => lower.indexOf(term)).filter((offset2) => offset2 >= 0);
|
|
800
|
-
matchOffset = locations.length ? Math.min(...locations) : -1;
|
|
801
|
-
}
|
|
802
|
-
const offset = Math.max(0, Math.min(matchOffset - 160, text.length - 1200));
|
|
803
|
-
return {
|
|
804
|
-
text: text.slice(offset, offset + 1200),
|
|
805
|
-
offset,
|
|
806
|
-
matchOffset: matchOffset < 0 ? null : matchOffset,
|
|
807
|
-
length: text.length,
|
|
808
|
-
nextOffset: offset + 1200 < text.length ? offset + 1200 : null
|
|
809
|
-
};
|
|
810
|
-
}
|
|
811
|
-
async function referenceSearch(query, version, options = {}) {
|
|
812
|
-
if (options.corpus === "blocks" || options.corpus === "blueprints") {
|
|
813
|
-
const found = await catalogSearch(query, { ...options, ...version ? { version } : {} });
|
|
814
|
-
return found.results.map((hit) => ({
|
|
815
|
-
...hit,
|
|
816
|
-
source: "bundled-composer-catalog",
|
|
817
|
-
version: "version" in hit ? hit.version : "1",
|
|
818
|
-
kind: "template",
|
|
819
|
-
family: "composer",
|
|
820
|
-
text: hit.title,
|
|
821
|
-
offset: 0,
|
|
822
|
-
matchOffset: 0,
|
|
823
|
-
length: hit.title.length,
|
|
824
|
-
nextOffset: null,
|
|
825
|
-
requires: [],
|
|
826
|
-
totalMatches: found.totalMatches,
|
|
827
|
-
nextResultOffset: found.nextResultOffset
|
|
828
|
-
}));
|
|
829
|
-
}
|
|
830
|
-
if (options.corpus === "components") return componentSearch(query, version, options);
|
|
831
|
-
if (options.corpus === "patterns") return patternSearch(query, version, options);
|
|
832
|
-
const terms = termsFor(query);
|
|
833
|
-
if (!terms.length) return [];
|
|
834
|
-
const index = await referenceIndex();
|
|
835
|
-
const normalized = normalizeReference(query);
|
|
836
|
-
const key = JSON.stringify([query.trim(), version, options.kind, options.family]);
|
|
837
|
-
let ranked = index.queries.get(key);
|
|
838
|
-
if (!ranked) {
|
|
839
|
-
const postings = await index.postings();
|
|
840
|
-
const lists = terms.map((term) => postings[term] ?? []).sort((a, b) => a.length - b.length);
|
|
841
|
-
const membership = lists.slice(1).map((list) => new Set(list));
|
|
842
|
-
const candidates = (lists[0] ?? []).filter((position) => membership.every((list) => list.has(position)));
|
|
843
|
-
const exactId = index.byId.get(query) ?? index.byId.get(index.bySymbol.get(query.replace(/^grammar:/, "")) ?? "");
|
|
844
|
-
if (exactId) {
|
|
845
|
-
const position = index.searchable.findIndex(({ reference }) => reference === exactId);
|
|
846
|
-
if (!candidates.includes(position)) candidates.push(position);
|
|
847
|
-
}
|
|
848
|
-
ranked = candidates.filter((position) => {
|
|
849
|
-
const r = index.searchable[position].reference;
|
|
850
|
-
return versionMatches(r.version, version) && (!options.kind || r.kind === options.kind) && (!options.family || r.family === options.family || r.family?.startsWith(options.family + "/"));
|
|
851
|
-
}).map((position) => {
|
|
852
|
-
const entry = index.searchable[position];
|
|
853
|
-
const { reference, titleText } = entry;
|
|
854
|
-
const exact = reference === exactId;
|
|
855
|
-
const { titleTerms, bodyText } = entry.ranking ??= {
|
|
856
|
-
titleTerms: termsFor(titleText),
|
|
857
|
-
bodyText: normalizeReference(reference.text)
|
|
858
|
-
};
|
|
859
|
-
const adjacentHits = terms.slice(1).filter((term, i) => bodyText.includes(terms[i] + " " + term)).length;
|
|
860
|
-
const titleHits = terms.filter((term) => titleTerms.includes(term)).length;
|
|
861
|
-
const score = (exact ? 1e4 : 0) + (titleText === normalized ? 2e3 : 0) + (titleText.includes(normalized) ? 400 : 0) + titleHits * 50 + (titleHits === terms.length ? 200 : 0) + (bodyText.includes(normalized) ? 40 : 0) + adjacentHits * 60 + (reference.text.includes('"' + query.trim() + '"') ? 80 : 0) + (reference.kind === "contract" ? 5 : 0) + 1 / (1 + reference.text.length / 1e3);
|
|
862
|
-
return { position, score };
|
|
863
|
-
}).sort((a, b) => b.score - a.score || a.position - b.position).map(({ position }) => position);
|
|
864
|
-
if (index.queries.size >= 64) index.queries.delete(index.queries.keys().next().value);
|
|
865
|
-
index.queries.set(key, ranked);
|
|
866
|
-
}
|
|
867
|
-
const offset = options.offset ?? 0;
|
|
868
|
-
const limit = options.limit ?? 3;
|
|
869
|
-
return ranked.slice(offset, offset + limit).map((position) => {
|
|
870
|
-
const { reference: r, title } = index.searchable[position];
|
|
871
|
-
return {
|
|
872
|
-
id: r.id,
|
|
873
|
-
title,
|
|
874
|
-
version: r.version,
|
|
875
|
-
source: r.source,
|
|
876
|
-
kind: r.kind ?? "guide",
|
|
877
|
-
family: r.family ?? "workflow",
|
|
878
|
-
...snippet(r.text, query, terms),
|
|
879
|
-
requires: r.requires ?? [],
|
|
880
|
-
totalMatches: ranked.length,
|
|
881
|
-
nextResultOffset: offset + limit < ranked.length ? offset + limit : null
|
|
882
|
-
};
|
|
883
|
-
});
|
|
884
|
-
}
|
|
885
|
-
async function referenceRead(id, offset, limit, project2) {
|
|
886
|
-
if (id.startsWith("block:") || id.startsWith("blueprint:")) return catalogRead(id, offset, limit, project2);
|
|
887
|
-
if (id.startsWith("component:")) return componentRead(id, offset, limit);
|
|
888
|
-
if (id.startsWith("pattern:")) return patternRead(id, offset, limit);
|
|
889
|
-
const index = await referenceIndex();
|
|
890
|
-
const item = index.byId.get(id) ?? index.byId.get(index.bySymbol.get(id.replace(/^grammar:/, "")) ?? "");
|
|
891
|
-
if (!item)
|
|
892
|
-
throw new Fault("REFERENCE_NOT_FOUND", "No registered reference with this ID or grammar symbol.", 2);
|
|
893
|
-
const content = item.text.slice(offset, offset + limit);
|
|
894
|
-
const symbols = [...content.matchAll(/<([^>\n]+)>/g)].map((match) => index.bySymbol.get(match[1]));
|
|
895
|
-
const related = [
|
|
896
|
-
...new Set(
|
|
897
|
-
[...item.related ?? [], ...symbols].filter(
|
|
898
|
-
(target) => Boolean(target) && target !== item.id
|
|
899
|
-
)
|
|
900
|
-
)
|
|
901
|
-
];
|
|
902
|
-
return {
|
|
903
|
-
id: item.id,
|
|
904
|
-
title: item.title ?? item.id,
|
|
905
|
-
version: item.version,
|
|
906
|
-
source: item.source,
|
|
907
|
-
content,
|
|
908
|
-
offset,
|
|
909
|
-
length: item.text.length,
|
|
910
|
-
nextOffset: offset + limit < item.text.length ? offset + limit : null,
|
|
911
|
-
requires: item.requires ?? [],
|
|
912
|
-
related: related.slice(0, 16),
|
|
913
|
-
relatedCount: related.length,
|
|
914
|
-
relatedOmittedCount: Math.max(0, related.length - 16),
|
|
915
|
-
classification: "vendor-reference-data"
|
|
916
|
-
};
|
|
917
|
-
}
|
|
918
|
-
async function referenceSync(version, dryRun) {
|
|
919
|
-
const entries = (await referenceIndex()).upstream.filter((r) => versionMatches(r.version, version));
|
|
920
|
-
if (!entries.length)
|
|
921
|
-
throw new Fault(
|
|
922
|
-
"REFERENCE_VERSION_UNAVAILABLE",
|
|
923
|
-
"Requested version is not in this reviewed release snapshot. Install a reviewed release containing it.",
|
|
924
|
-
3
|
|
925
|
-
);
|
|
926
|
-
const destination = path3.join(managedHome(), "references", version + ".json");
|
|
927
|
-
const before = await exists(destination) ? hash(canonical(await readJson(destination))) : null, after = hash(canonical(entries));
|
|
928
|
-
if (!dryRun && before !== after) await writeJson(destination, entries);
|
|
929
|
-
return {
|
|
930
|
-
status: dryRun ? "planned" : before === after ? "unchanged" : "synced",
|
|
931
|
-
version,
|
|
932
|
-
before,
|
|
933
|
-
after,
|
|
934
|
-
count: entries.length
|
|
935
|
-
};
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
// packages/core/src/sandbox.ts
|
|
939
|
-
async function sandboxAction(action) {
|
|
940
|
-
const engines = await Promise.all(
|
|
941
|
-
["docker", "podman"].map(async (executable) => {
|
|
942
|
-
try {
|
|
943
|
-
const r = await runProcess({
|
|
944
|
-
executable,
|
|
945
|
-
args: ["info", "--format", "{{json .}}"],
|
|
946
|
-
cwd: process.cwd(),
|
|
947
|
-
timeoutMs: 1e4
|
|
948
|
-
});
|
|
949
|
-
return { engine: executable, available: r.code === 0 };
|
|
950
|
-
} catch {
|
|
951
|
-
return { engine: executable, available: false };
|
|
952
|
-
}
|
|
953
|
-
})
|
|
954
|
-
);
|
|
955
|
-
const state = {
|
|
956
|
-
profile: "optional",
|
|
957
|
-
platform: `${process.platform}/${process.arch}`,
|
|
958
|
-
engines,
|
|
959
|
-
supported: false,
|
|
960
|
-
reason: "No provisioned Oracle DB Free + APEX 26.1 + ORDS artifact tuple has been verified on this host.",
|
|
961
|
-
volumesRemoved: false
|
|
962
|
-
};
|
|
963
|
-
if (action === "status") return state;
|
|
964
|
-
if (action === "down") return { ...state, status: "not-configured", changed: false };
|
|
965
|
-
throw new Fault(
|
|
966
|
-
"SANDBOX_PROFILE_UNVERIFIED",
|
|
967
|
-
state.reason + " Remote APEX targets remain independent.",
|
|
968
|
-
3,
|
|
969
|
-
"blocked"
|
|
970
|
-
);
|
|
971
|
-
}
|
|
972
|
-
|
|
973
|
-
// packages/core/src/service.ts
|
|
974
|
-
import { realpath as realpath2 } from "node:fs/promises";
|
|
975
|
-
async function dispatch(operation, input = {}, signal) {
|
|
976
|
-
try {
|
|
977
|
-
if (signal?.aborted)
|
|
978
|
-
throw new Fault("CANCELLED", "Operation cancelled before execution.", 6, "cancelled");
|
|
979
|
-
if (!(operation in schemas)) throw new Fault("INVALID_INPUT", `Unknown operation: ${operation}`, 2);
|
|
980
|
-
const parsed = parse(
|
|
981
|
-
schemas[operation],
|
|
982
|
-
input
|
|
983
|
-
);
|
|
984
|
-
const text = (key) => parsed[key];
|
|
985
|
-
const root = text("project") ?? process.cwd();
|
|
986
|
-
const oracle = new OracleAdapter(), tests = new TestService(oracle), deployment = new DeploymentService(oracle, (ctx, env2) => tests.all(ctx, env2));
|
|
987
|
-
let data;
|
|
988
|
-
switch (operation) {
|
|
989
|
-
case "panel.open": {
|
|
990
|
-
const { openPanel } = await import("./chunk-WXP75UUP.mjs");
|
|
991
|
-
data = await openPanel(await realpath2(root));
|
|
992
|
-
break;
|
|
993
|
-
}
|
|
994
|
-
case "panel.status":
|
|
995
|
-
data = await new PanelService(root).snapshot();
|
|
996
|
-
break;
|
|
997
|
-
case "panel.action":
|
|
998
|
-
{
|
|
999
|
-
const action = panelActionSchema.parse(parsed).action;
|
|
1000
|
-
if (action.kind === "connection" && action.password !== void 0)
|
|
1001
|
-
throw new Fault(
|
|
1002
|
-
"LOCAL_CREDENTIAL_ENTRY_REQUIRED",
|
|
1003
|
-
"Enter the ORDS password only in the local browser settings form, or supply a local password file to connection.add.",
|
|
1004
|
-
3,
|
|
1005
|
-
"blocked"
|
|
1006
|
-
);
|
|
1007
|
-
data = await new PanelService(root).act(action);
|
|
1008
|
-
}
|
|
1009
|
-
break;
|
|
1010
|
-
case "version":
|
|
1011
|
-
data = { version: VERSION, node: process.version };
|
|
1012
|
-
break;
|
|
1013
|
-
case "doctor":
|
|
1014
|
-
data = await doctor();
|
|
1015
|
-
break;
|
|
1016
|
-
case "sqlcl.status":
|
|
1017
|
-
data = await sqlclConfig();
|
|
1018
|
-
break;
|
|
1019
|
-
case "sqlcl.configure":
|
|
1020
|
-
data = await configureSqlcl(
|
|
1021
|
-
text("mode"),
|
|
1022
|
-
parsed.mcpRestrictLevel,
|
|
1023
|
-
parsed.databaseTransport
|
|
1024
|
-
);
|
|
1025
|
-
break;
|
|
1026
|
-
case "dependencies.install": {
|
|
1027
|
-
const { ToolchainService } = await import("./chunk-YQHHPRJH.mjs");
|
|
1028
|
-
data = await new ToolchainService().apply(parsed);
|
|
1029
|
-
break;
|
|
1030
|
-
}
|
|
1031
|
-
case "dependencies.uninstall": {
|
|
1032
|
-
const { uninstallTools } = await import("./chunk-33GE2NWZ.mjs");
|
|
1033
|
-
data = await uninstallTools(parsed);
|
|
1034
|
-
break;
|
|
1035
|
-
}
|
|
1036
|
-
case "setup":
|
|
1037
|
-
case "plugin.install":
|
|
1038
|
-
case "plugin.update": {
|
|
1039
|
-
const { setup: setup2 } = await import("./chunk-KQ5IDT7Z.mjs");
|
|
1040
|
-
data = await setup2(parsed);
|
|
1041
|
-
break;
|
|
1042
|
-
}
|
|
1043
|
-
case "plugin.validate": {
|
|
1044
|
-
const { validateNative } = await import("./chunk-KQ5IDT7Z.mjs");
|
|
1045
|
-
data = await validateNative(text("from"));
|
|
1046
|
-
break;
|
|
1047
|
-
}
|
|
1048
|
-
case "plugin.uninstall": {
|
|
1049
|
-
const { uninstallNative } = await import("./chunk-KQ5IDT7Z.mjs");
|
|
1050
|
-
data = await uninstallNative(text("home") ?? managedHome(), Boolean(parsed.keepRuntime));
|
|
1051
|
-
break;
|
|
1052
|
-
}
|
|
1053
|
-
case "project.init":
|
|
1054
|
-
data = await projectInit(
|
|
1055
|
-
text("directory"),
|
|
1056
|
-
text("template"),
|
|
1057
|
-
text("alias") ?? path4.basename(path4.resolve(text("directory"))).toLowerCase().replace(/[^a-z0-9-]/g, "-")
|
|
1058
|
-
);
|
|
1059
|
-
break;
|
|
1060
|
-
case "connection.add":
|
|
1061
|
-
data = await configureConnection(text("name"), {
|
|
1062
|
-
sqlclName: text("sqlclName"),
|
|
1063
|
-
ordsUrl: text("ordsUrl"),
|
|
1064
|
-
ordsUsername: text("ordsUsername"),
|
|
1065
|
-
passwordFile: text("passwordFile")
|
|
1066
|
-
});
|
|
1067
|
-
break;
|
|
1068
|
-
case "connection.remove":
|
|
1069
|
-
data = await editConnection(text("name"));
|
|
1070
|
-
break;
|
|
1071
|
-
case "connection.list":
|
|
1072
|
-
data = parsed.saved ? await oracle.savedConnections(signal) : await connections();
|
|
1073
|
-
break;
|
|
1074
|
-
case "connection.test":
|
|
1075
|
-
if (parsed.saved && (await oracle.settings()).databaseTransport === "ords")
|
|
1076
|
-
throw new Fault(
|
|
1077
|
-
"ORDS_SAVED_CONNECTION_UNSUPPORTED",
|
|
1078
|
-
"ORDS uses plugin connection references. Test the configured reference without --saved.",
|
|
1079
|
-
3,
|
|
1080
|
-
"blocked"
|
|
1081
|
-
);
|
|
1082
|
-
data = await oracle.identity(
|
|
1083
|
-
parsed.saved ? { kind: "sqlcl-store", name: text("name") } : await resolveConnection(text("name")),
|
|
1084
|
-
signal
|
|
1085
|
-
);
|
|
1086
|
-
if (parsed.saved) data = { name: text("name"), ...data };
|
|
1087
|
-
break;
|
|
1088
|
-
case "docs.search":
|
|
1089
|
-
data = await referenceSearch(text("query"), text("version"), schemas["docs.search"].parse(parsed));
|
|
1090
|
-
break;
|
|
1091
|
-
case "docs.read":
|
|
1092
|
-
data = await referenceRead(text("id"), Number(parsed.offset), Number(parsed.limit), text("project"));
|
|
1093
|
-
break;
|
|
1094
|
-
case "docs.sync":
|
|
1095
|
-
data = await referenceSync(text("version"), Boolean(parsed.dryRun));
|
|
1096
|
-
break;
|
|
1097
|
-
case "sandbox.up":
|
|
1098
|
-
case "sandbox.status":
|
|
1099
|
-
case "sandbox.down":
|
|
1100
|
-
data = await sandboxAction(operation.split(".")[1]);
|
|
1101
|
-
break;
|
|
1102
|
-
default: {
|
|
1103
|
-
const ctx = await loadProject(root);
|
|
1104
|
-
switch (operation) {
|
|
1105
|
-
case "compose.plan":
|
|
1106
|
-
data = await composePlan(ctx, schemas["compose.plan"].parse(parsed), oracle, signal);
|
|
1107
|
-
break;
|
|
1108
|
-
case "compose.materialize":
|
|
1109
|
-
data = await composeMaterialize(ctx, schemas["compose.materialize"].parse(parsed), signal);
|
|
1110
|
-
break;
|
|
1111
|
-
case "project.inspect":
|
|
1112
|
-
data = await projectInspect(ctx, parsed.detail);
|
|
1113
|
-
break;
|
|
1114
|
-
case "metadata.read": {
|
|
1115
|
-
const env2 = environment(ctx, text("env"));
|
|
1116
|
-
const { project: _p, env: _e, ...request } = parsed;
|
|
1117
|
-
data = await metadataRead(oracle, env2, await resolveConnection(env2.readConnectionRef), request);
|
|
1118
|
-
break;
|
|
1119
|
-
}
|
|
1120
|
-
case "apex.generate": {
|
|
1121
|
-
await requireTrust(ctx.root);
|
|
1122
|
-
const generated = await oracle.generate(
|
|
1123
|
-
text("name"),
|
|
1124
|
-
text("alias") ?? ctx.config.application.alias
|
|
1125
|
-
);
|
|
1126
|
-
data = {
|
|
1127
|
-
...await installSources(generated.directory, ctx.root, text("output")),
|
|
1128
|
-
compiler: generated.compiler
|
|
1129
|
-
};
|
|
1130
|
-
break;
|
|
1131
|
-
}
|
|
1132
|
-
case "apex.sync":
|
|
1133
|
-
data = await deployment.sync(
|
|
1134
|
-
ctx,
|
|
1135
|
-
text("env"),
|
|
1136
|
-
parsed.action,
|
|
1137
|
-
signal
|
|
1138
|
-
);
|
|
1139
|
-
break;
|
|
1140
|
-
case "project.adopt":
|
|
1141
|
-
case "apex.export": {
|
|
1142
|
-
await requireTrust(ctx.root);
|
|
1143
|
-
const env2 = environment(ctx, text("env"));
|
|
1144
|
-
if (operation === "project.adopt" && env2.applicationId !== parsed.appId)
|
|
1145
|
-
throw new Fault(
|
|
1146
|
-
"APPLICATION_TARGET_MISMATCH",
|
|
1147
|
-
"Requested app ID differs from the environment mapping.",
|
|
1148
|
-
5
|
|
1149
|
-
);
|
|
1150
|
-
if (operation === "project.adopt" && parsed.workingCopy) {
|
|
1151
|
-
data = await deployment.sync(ctx, text("env"), "init", signal);
|
|
1152
|
-
break;
|
|
1153
|
-
}
|
|
1154
|
-
const connection = await resolveConnection(env2.readConnectionRef);
|
|
1155
|
-
await oracle.verifyTarget(env2, connection);
|
|
1156
|
-
const exported = await oracle.exportApplication(env2, connection);
|
|
1157
|
-
data = await installSources(
|
|
1158
|
-
exported.directory,
|
|
1159
|
-
ctx.root,
|
|
1160
|
-
operation === "project.adopt" ? ctx.config.application.sourceDir : text("output")
|
|
1161
|
-
);
|
|
1162
|
-
break;
|
|
1163
|
-
}
|
|
1164
|
-
case "apex.validate":
|
|
1165
|
-
await requireTrust(ctx.root);
|
|
1166
|
-
data = await oracle.validate(await contained(ctx.root, ctx.config.application.sourceDir), signal);
|
|
1167
|
-
break;
|
|
1168
|
-
case "apex.diff": {
|
|
1169
|
-
await requireTrust(ctx.root);
|
|
1170
|
-
const env2 = environment(ctx, text("env"));
|
|
1171
|
-
const store = new SyncStore(ctx, env2, text("env"));
|
|
1172
|
-
const state = parsed.comparison === "live" ? null : await store.read();
|
|
1173
|
-
let exported, provenance;
|
|
1174
|
-
if (state && state.status !== "invalidated" && parsed.comparison !== "live") {
|
|
1175
|
-
await store.validate(state);
|
|
1176
|
-
exported = checkpoint(state);
|
|
1177
|
-
provenance = state.lastSuccessfulImport ? "last-successful-import" : "initial-baseline";
|
|
1178
|
-
} else {
|
|
1179
|
-
const connection = await resolveConnection(env2.readConnectionRef);
|
|
1180
|
-
await oracle.verifyTarget(env2, connection);
|
|
1181
|
-
exported = await oracle.exportApplication(env2, connection);
|
|
1182
|
-
provenance = "live-export";
|
|
1183
|
-
}
|
|
1184
|
-
const local = (await projectInspect(ctx)).sources.apex;
|
|
1185
|
-
data = {
|
|
1186
|
-
scope: "full-application-import",
|
|
1187
|
-
completeness: "textual-file-hashes-only",
|
|
1188
|
-
provenance,
|
|
1189
|
-
changes: [.../* @__PURE__ */ new Set([...Object.keys(exported.files), ...Object.keys(local ?? {})])].filter((f) => exported.files[f] !== local?.[f]).map((file) => ({
|
|
1190
|
-
file,
|
|
1191
|
-
before: exported.files[file] ?? null,
|
|
1192
|
-
after: local?.[file] ?? null
|
|
1193
|
-
}))
|
|
1194
|
-
};
|
|
1195
|
-
break;
|
|
1196
|
-
}
|
|
1197
|
-
case "db.plan":
|
|
1198
|
-
data = await deployment.plan(ctx, text("env"));
|
|
1199
|
-
break;
|
|
1200
|
-
case "deploy.plan": {
|
|
1201
|
-
const plan = await deployment.plan(ctx, text("env"));
|
|
1202
|
-
await writeJson(await contained(ctx.root, text("out")), plan);
|
|
1203
|
-
data = plan;
|
|
1204
|
-
break;
|
|
1205
|
-
}
|
|
1206
|
-
case "deploy.apply":
|
|
1207
|
-
data = await deployment.apply(
|
|
1208
|
-
ctx,
|
|
1209
|
-
await readJson(await contained(ctx.root, text("plan"))),
|
|
1210
|
-
signal
|
|
1211
|
-
);
|
|
1212
|
-
break;
|
|
1213
|
-
case "deploy.status":
|
|
1214
|
-
data = await deployment.reconcile(ctx, text("run"));
|
|
1215
|
-
break;
|
|
1216
|
-
case "deploy.restore-plan": {
|
|
1217
|
-
const plan = await deployment.restorePlan(ctx, text("backup"));
|
|
1218
|
-
await writeJson(await contained(ctx.root, text("out")), plan);
|
|
1219
|
-
data = plan;
|
|
1220
|
-
break;
|
|
1221
|
-
}
|
|
1222
|
-
case "test.run": {
|
|
1223
|
-
const suite = text("suite");
|
|
1224
|
-
if (suite === "all") {
|
|
1225
|
-
if (!parsed.env) throw new Fault("ENVIRONMENT_REQUIRED", "test all requires --env.", 2);
|
|
1226
|
-
const result = await tests.all(ctx, text("env"), signal);
|
|
1227
|
-
data = result.data;
|
|
1228
|
-
if (!result.ok)
|
|
1229
|
-
return {
|
|
1230
|
-
...failure(operation, new Fault("QUALITY_GATE_FAILED", "Required suites did not pass.", 1)),
|
|
1231
|
-
data
|
|
1232
|
-
};
|
|
1233
|
-
} else {
|
|
1234
|
-
const result = await tests.run(
|
|
1235
|
-
ctx,
|
|
1236
|
-
suite,
|
|
1237
|
-
text("env"),
|
|
1238
|
-
signal,
|
|
1239
|
-
Boolean(parsed.headed)
|
|
1240
|
-
);
|
|
1241
|
-
data = result;
|
|
1242
|
-
if (result.status !== "passed")
|
|
1243
|
-
return {
|
|
1244
|
-
...failure(
|
|
1245
|
-
operation,
|
|
1246
|
-
new Fault(
|
|
1247
|
-
"TEST_" + result.status.toUpperCase(),
|
|
1248
|
-
result.diagnostic ?? `Suite is ${result.status}.`,
|
|
1249
|
-
result.status === "failed" ? 1 : 3,
|
|
1250
|
-
result.status
|
|
1251
|
-
)
|
|
1252
|
-
),
|
|
1253
|
-
data
|
|
1254
|
-
};
|
|
1255
|
-
}
|
|
1256
|
-
break;
|
|
1257
|
-
}
|
|
1258
|
-
case "test.report":
|
|
1259
|
-
data = await readJson(await contained(ctx.root, ".apexrest/test-runs/" + text("run") + ".json"));
|
|
1260
|
-
break;
|
|
1261
|
-
case "test.auth":
|
|
1262
|
-
data = await tests.auth(ctx, text("env"));
|
|
1263
|
-
break;
|
|
1264
|
-
case "browser.open": {
|
|
1265
|
-
const { openVerificationBrowser } = await import("./chunk-ESDVN7DS.mjs");
|
|
1266
|
-
data = await openVerificationBrowser(
|
|
1267
|
-
ctx,
|
|
1268
|
-
text("env"),
|
|
1269
|
-
void 0,
|
|
1270
|
-
parsed.browserMode
|
|
1271
|
-
);
|
|
1272
|
-
break;
|
|
1273
|
-
}
|
|
1274
|
-
case "jobs.status":
|
|
1275
|
-
data = await new JobService(ctx).status(text("id"), Number(parsed.waitSeconds), signal);
|
|
1276
|
-
break;
|
|
1277
|
-
case "jobs.cancel":
|
|
1278
|
-
data = await new JobService(ctx).cancel(text("id"));
|
|
1279
|
-
break;
|
|
1280
|
-
case "artifacts.read":
|
|
1281
|
-
data = await new ArtifactService(ctx).read(
|
|
1282
|
-
text("id"),
|
|
1283
|
-
Number(parsed.offset),
|
|
1284
|
-
Number(parsed.limit)
|
|
1285
|
-
);
|
|
1286
|
-
break;
|
|
1287
|
-
default:
|
|
1288
|
-
throw new Fault("INVALID_INPUT", "Unknown operation.", 2);
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1292
|
-
return success(operation, data);
|
|
1293
|
-
} catch (error) {
|
|
1294
|
-
return failure(operation, error);
|
|
1295
|
-
}
|
|
1296
|
-
}
|
|
1297
|
-
|
|
1298
|
-
export {
|
|
1299
|
-
schemas,
|
|
1300
|
-
toolCatalog,
|
|
1301
|
-
dispatch
|
|
1302
|
-
};
|