@xano/cli 0.0.95 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +133 -66
- package/dist/base-command.d.ts +41 -1
- package/dist/base-command.js +92 -3
- package/dist/commands/auth/index.d.ts +1 -0
- package/dist/commands/auth/index.js +16 -11
- package/dist/commands/branch/create/index.d.ts +4 -1
- package/dist/commands/branch/create/index.js +22 -21
- package/dist/commands/branch/delete/index.d.ts +1 -0
- package/dist/commands/branch/delete/index.js +1 -4
- package/dist/commands/branch/edit/index.d.ts +1 -0
- package/dist/commands/branch/edit/index.js +1 -4
- package/dist/commands/branch/get/index.d.ts +1 -0
- package/dist/commands/branch/get/index.js +1 -4
- package/dist/commands/branch/list/index.d.ts +2 -6
- package/dist/commands/branch/list/index.js +13 -17
- package/dist/commands/branch/set_live/index.d.ts +1 -0
- package/dist/commands/branch/set_live/index.js +1 -4
- package/dist/commands/function/create/index.d.ts +1 -0
- package/dist/commands/function/create/index.js +1 -2
- package/dist/commands/function/edit/index.d.ts +1 -0
- package/dist/commands/function/edit/index.js +1 -2
- package/dist/commands/function/get/index.d.ts +1 -0
- package/dist/commands/function/get/index.js +1 -4
- package/dist/commands/function/list/index.d.ts +1 -0
- package/dist/commands/function/list/index.js +1 -4
- package/dist/commands/platform/get/index.d.ts +1 -0
- package/dist/commands/platform/get/index.js +1 -4
- package/dist/commands/platform/list/index.d.ts +1 -0
- package/dist/commands/platform/list/index.js +1 -4
- package/dist/commands/profile/create/index.d.ts +1 -0
- package/dist/commands/profile/create/index.js +12 -6
- package/dist/commands/profile/delete/index.d.ts +1 -0
- package/dist/commands/profile/delete/index.js +8 -4
- package/dist/commands/profile/edit/index.d.ts +1 -0
- package/dist/commands/profile/edit/index.js +3 -6
- package/dist/commands/profile/get/index.d.ts +3 -0
- package/dist/commands/profile/get/index.js +12 -5
- package/dist/commands/profile/list/index.d.ts +1 -0
- package/dist/commands/profile/list/index.js +8 -4
- package/dist/commands/profile/me/index.d.ts +1 -0
- package/dist/commands/profile/me/index.js +22 -6
- package/dist/commands/profile/set/index.d.ts +3 -0
- package/dist/commands/profile/set/index.js +12 -6
- package/dist/commands/profile/token/index.d.ts +3 -0
- package/dist/commands/profile/token/index.js +12 -5
- package/dist/commands/profile/wizard/index.d.ts +1 -0
- package/dist/commands/profile/wizard/index.js +16 -12
- package/dist/commands/profile/workspace/index.d.ts +3 -0
- package/dist/commands/profile/workspace/index.js +12 -5
- package/dist/commands/profile/workspace/set/index.d.ts +1 -0
- package/dist/commands/profile/workspace/set/index.js +2 -4
- package/dist/commands/release/create/index.d.ts +4 -1
- package/dist/commands/release/create/index.js +12 -14
- package/dist/commands/release/delete/index.d.ts +1 -0
- package/dist/commands/release/delete/index.js +1 -4
- package/dist/commands/release/deploy/index.d.ts +20 -0
- package/dist/commands/release/deploy/index.js +137 -0
- package/dist/commands/release/edit/index.d.ts +1 -0
- package/dist/commands/release/edit/index.js +1 -4
- package/dist/commands/release/export/index.d.ts +1 -0
- package/dist/commands/release/export/index.js +1 -3
- package/dist/commands/release/get/index.d.ts +1 -0
- package/dist/commands/release/get/index.js +1 -4
- package/dist/commands/release/import/index.d.ts +1 -0
- package/dist/commands/release/import/index.js +1 -3
- package/dist/commands/release/list/index.d.ts +1 -0
- package/dist/commands/release/list/index.js +1 -4
- package/dist/commands/release/pull/index.d.ts +2 -3
- package/dist/commands/release/pull/index.js +19 -18
- package/dist/commands/release/push/index.d.ts +2 -3
- package/dist/commands/release/push/index.js +19 -22
- package/dist/commands/sandbox/delete/index.d.ts +13 -0
- package/dist/commands/sandbox/delete/index.js +71 -0
- package/dist/commands/sandbox/env/delete/index.d.ts +15 -0
- package/dist/commands/sandbox/env/delete/index.js +89 -0
- package/dist/commands/sandbox/env/get/index.d.ts +13 -0
- package/dist/commands/sandbox/env/get/index.js +65 -0
- package/dist/commands/sandbox/env/get_all/index.d.ts +14 -0
- package/dist/commands/sandbox/env/get_all/index.js +78 -0
- package/dist/commands/sandbox/env/list/index.d.ts +12 -0
- package/dist/commands/sandbox/env/list/index.js +67 -0
- package/dist/commands/sandbox/env/set/index.d.ts +14 -0
- package/dist/commands/sandbox/env/set/index.js +74 -0
- package/dist/commands/sandbox/env/set_all/index.d.ts +14 -0
- package/dist/commands/sandbox/env/set_all/index.js +86 -0
- package/dist/commands/sandbox/get/index.d.ts +12 -0
- package/dist/commands/sandbox/get/index.js +63 -0
- package/dist/commands/sandbox/impersonate/index.d.ts +5 -0
- package/dist/commands/sandbox/impersonate/index.js +5 -0
- package/dist/commands/sandbox/license/get/index.d.ts +14 -0
- package/dist/commands/sandbox/license/get/index.js +78 -0
- package/dist/commands/sandbox/license/set/index.d.ts +15 -0
- package/dist/commands/sandbox/license/set/index.js +95 -0
- package/dist/commands/sandbox/pull/index.d.ts +16 -0
- package/dist/commands/sandbox/pull/index.js +185 -0
- package/dist/commands/sandbox/push/index.d.ts +26 -0
- package/dist/commands/sandbox/push/index.js +196 -0
- package/dist/commands/sandbox/reset/index.d.ts +13 -0
- package/dist/commands/sandbox/reset/index.js +71 -0
- package/dist/commands/sandbox/review/index.d.ts +14 -0
- package/dist/commands/sandbox/review/index.js +94 -0
- package/dist/commands/sandbox/unit_test/list/index.d.ts +14 -0
- package/dist/commands/sandbox/unit_test/list/index.js +91 -0
- package/dist/commands/sandbox/unit_test/run/index.d.ts +15 -0
- package/dist/commands/sandbox/unit_test/run/index.js +79 -0
- package/dist/commands/sandbox/unit_test/run_all/index.d.ts +14 -0
- package/dist/commands/sandbox/unit_test/run_all/index.js +171 -0
- package/dist/commands/sandbox/workflow_test/list/index.d.ts +13 -0
- package/dist/commands/sandbox/workflow_test/list/index.js +84 -0
- package/dist/commands/sandbox/workflow_test/run/index.d.ts +18 -0
- package/dist/commands/sandbox/workflow_test/run/index.js +77 -0
- package/dist/commands/sandbox/workflow_test/run_all/index.d.ts +13 -0
- package/dist/commands/sandbox/workflow_test/run_all/index.js +157 -0
- package/dist/commands/static_host/build/create/index.d.ts +1 -0
- package/dist/commands/static_host/build/create/index.js +1 -3
- package/dist/commands/static_host/build/get/index.d.ts +1 -0
- package/dist/commands/static_host/build/get/index.js +1 -4
- package/dist/commands/static_host/build/list/index.d.ts +1 -0
- package/dist/commands/static_host/build/list/index.js +1 -4
- package/dist/commands/static_host/list/index.d.ts +1 -0
- package/dist/commands/static_host/list/index.js +1 -4
- package/dist/commands/tenant/backup/create/index.d.ts +1 -0
- package/dist/commands/tenant/backup/create/index.js +1 -4
- package/dist/commands/tenant/backup/delete/index.d.ts +1 -0
- package/dist/commands/tenant/backup/delete/index.js +1 -4
- package/dist/commands/tenant/backup/export/index.d.ts +1 -0
- package/dist/commands/tenant/backup/export/index.js +1 -3
- package/dist/commands/tenant/backup/import/index.d.ts +1 -0
- package/dist/commands/tenant/backup/import/index.js +1 -3
- package/dist/commands/tenant/backup/list/index.d.ts +1 -0
- package/dist/commands/tenant/backup/list/index.js +1 -4
- package/dist/commands/tenant/backup/restore/index.d.ts +1 -0
- package/dist/commands/tenant/backup/restore/index.js +1 -4
- package/dist/commands/tenant/cluster/create/index.d.ts +1 -0
- package/dist/commands/tenant/cluster/create/index.js +1 -3
- package/dist/commands/tenant/cluster/delete/index.d.ts +1 -0
- package/dist/commands/tenant/cluster/delete/index.js +1 -4
- package/dist/commands/tenant/cluster/edit/index.d.ts +1 -0
- package/dist/commands/tenant/cluster/edit/index.js +1 -4
- package/dist/commands/tenant/cluster/get/index.d.ts +1 -0
- package/dist/commands/tenant/cluster/get/index.js +1 -4
- package/dist/commands/tenant/cluster/license/get/index.d.ts +1 -0
- package/dist/commands/tenant/cluster/license/get/index.js +1 -3
- package/dist/commands/tenant/cluster/license/set/index.d.ts +1 -0
- package/dist/commands/tenant/cluster/license/set/index.js +1 -3
- package/dist/commands/tenant/cluster/list/index.d.ts +1 -0
- package/dist/commands/tenant/cluster/list/index.js +1 -4
- package/dist/commands/tenant/create/index.d.ts +1 -1
- package/dist/commands/tenant/create/index.js +1 -8
- package/dist/commands/tenant/delete/index.d.ts +1 -0
- package/dist/commands/tenant/delete/index.js +1 -4
- package/dist/commands/tenant/deploy_platform/index.d.ts +1 -0
- package/dist/commands/tenant/deploy_platform/index.js +1 -3
- package/dist/commands/tenant/deploy_release/index.d.ts +1 -0
- package/dist/commands/tenant/deploy_release/index.js +1 -4
- package/dist/commands/tenant/edit/index.d.ts +1 -0
- package/dist/commands/tenant/edit/index.js +1 -4
- package/dist/commands/tenant/env/delete/index.d.ts +1 -0
- package/dist/commands/tenant/env/delete/index.js +1 -4
- package/dist/commands/tenant/env/get/index.d.ts +1 -0
- package/dist/commands/tenant/env/get/index.js +1 -4
- package/dist/commands/tenant/env/get_all/index.d.ts +1 -0
- package/dist/commands/tenant/env/get_all/index.js +1 -3
- package/dist/commands/tenant/env/list/index.d.ts +1 -0
- package/dist/commands/tenant/env/list/index.js +1 -4
- package/dist/commands/tenant/env/set/index.d.ts +1 -0
- package/dist/commands/tenant/env/set/index.js +1 -4
- package/dist/commands/tenant/env/set_all/index.d.ts +1 -0
- package/dist/commands/tenant/env/set_all/index.js +1 -3
- package/dist/commands/tenant/get/index.d.ts +1 -0
- package/dist/commands/tenant/get/index.js +3 -6
- package/dist/commands/tenant/impersonate/index.d.ts +1 -0
- package/dist/commands/tenant/impersonate/index.js +1 -4
- package/dist/commands/tenant/license/get/index.d.ts +1 -0
- package/dist/commands/tenant/license/get/index.js +1 -3
- package/dist/commands/tenant/license/set/index.d.ts +1 -0
- package/dist/commands/tenant/license/set/index.js +1 -3
- package/dist/commands/tenant/list/index.d.ts +1 -0
- package/dist/commands/tenant/list/index.js +3 -6
- package/dist/commands/tenant/pull/index.d.ts +2 -3
- package/dist/commands/tenant/pull/index.js +20 -21
- package/dist/commands/tenant/push/index.d.ts +2 -22
- package/dist/commands/tenant/push/index.js +7 -259
- package/dist/commands/tenant/unit_test/list/index.d.ts +16 -0
- package/dist/commands/tenant/unit_test/list/index.js +115 -0
- package/dist/commands/tenant/unit_test/run/index.d.ts +17 -0
- package/dist/commands/tenant/unit_test/run/index.js +103 -0
- package/dist/commands/tenant/unit_test/run_all/index.d.ts +16 -0
- package/dist/commands/tenant/unit_test/run_all/index.js +190 -0
- package/dist/commands/tenant/workflow_test/list/index.d.ts +15 -0
- package/dist/commands/tenant/workflow_test/list/index.js +108 -0
- package/dist/commands/tenant/workflow_test/run/index.d.ts +20 -0
- package/dist/commands/tenant/workflow_test/run/index.js +101 -0
- package/dist/commands/tenant/workflow_test/run_all/index.d.ts +15 -0
- package/dist/commands/tenant/workflow_test/run_all/index.js +176 -0
- package/dist/commands/unit_test/list/index.d.ts +1 -0
- package/dist/commands/unit_test/list/index.js +1 -4
- package/dist/commands/unit_test/run/index.d.ts +1 -0
- package/dist/commands/unit_test/run/index.js +1 -4
- package/dist/commands/unit_test/run_all/index.d.ts +1 -0
- package/dist/commands/unit_test/run_all/index.js +1 -4
- package/dist/commands/update/index.d.ts +1 -0
- package/dist/commands/workflow_test/delete/index.d.ts +1 -0
- package/dist/commands/workflow_test/delete/index.js +1 -4
- package/dist/commands/workflow_test/get/index.d.ts +1 -0
- package/dist/commands/workflow_test/get/index.js +1 -4
- package/dist/commands/workflow_test/list/index.d.ts +1 -0
- package/dist/commands/workflow_test/list/index.js +1 -4
- package/dist/commands/workflow_test/run/index.d.ts +1 -0
- package/dist/commands/workflow_test/run/index.js +1 -4
- package/dist/commands/workflow_test/run_all/index.d.ts +1 -0
- package/dist/commands/workflow_test/run_all/index.js +1 -4
- package/dist/commands/workspace/create/index.d.ts +1 -0
- package/dist/commands/workspace/create/index.js +1 -4
- package/dist/commands/workspace/delete/index.d.ts +2 -6
- package/dist/commands/workspace/delete/index.js +17 -16
- package/dist/commands/workspace/edit/index.d.ts +3 -6
- package/dist/commands/workspace/edit/index.js +31 -25
- package/dist/commands/workspace/get/index.d.ts +2 -6
- package/dist/commands/workspace/get/index.js +23 -25
- package/dist/commands/workspace/git/pull/index.d.ts +2 -3
- package/dist/commands/workspace/git/pull/index.js +18 -17
- package/dist/commands/workspace/list/index.d.ts +2 -0
- package/dist/commands/workspace/list/index.js +15 -11
- package/dist/commands/workspace/pull/index.d.ts +2 -3
- package/dist/commands/workspace/pull/index.js +21 -24
- package/dist/commands/workspace/push/index.d.ts +7 -16
- package/dist/commands/workspace/push/index.js +85 -674
- package/dist/help.d.ts +2 -1
- package/dist/help.js +39 -1
- package/dist/utils/multidoc-push.d.ts +63 -0
- package/dist/utils/multidoc-push.js +690 -0
- package/dist/utils/reference-checker.d.ts +57 -0
- package/dist/utils/reference-checker.js +232 -0
- package/oclif.manifest.json +5631 -2297
- package/package.json +17 -2
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A reference from one document to another (e.g., function.run "bad" references function "bad").
|
|
3
|
+
*/
|
|
4
|
+
export interface BadReference {
|
|
5
|
+
/** Name of the source document containing the reference */
|
|
6
|
+
source: string;
|
|
7
|
+
/** Type of the source document (e.g., "function") */
|
|
8
|
+
sourceType: string;
|
|
9
|
+
/** The statement type that creates the reference (e.g., "function.run") */
|
|
10
|
+
statementType: string;
|
|
11
|
+
/** The referenced name that doesn't exist */
|
|
12
|
+
target: string;
|
|
13
|
+
/** The target type being referenced (e.g., "function") */
|
|
14
|
+
targetType: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Build a registry of all defined object names from parsed documents.
|
|
18
|
+
* Returns a Map of type → Set of names.
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildRegistry(documents: Array<{
|
|
21
|
+
content: string;
|
|
22
|
+
}>): Map<string, Set<string>>;
|
|
23
|
+
/**
|
|
24
|
+
* Build a registry of server-known object names from dry-run operations.
|
|
25
|
+
* Any object that appears in the dry-run (create, update, unchanged, delete) exists
|
|
26
|
+
* either locally or on the server.
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildServerRegistry(operations: Array<{
|
|
29
|
+
name: string;
|
|
30
|
+
type: string;
|
|
31
|
+
}>): Map<string, Set<string>>;
|
|
32
|
+
/**
|
|
33
|
+
* Check all documents for cross-references that point to names not in the registry.
|
|
34
|
+
*
|
|
35
|
+
* When serverOperations is provided (from dry-run), references are checked against
|
|
36
|
+
* both local files AND server-known objects, eliminating false positives for objects
|
|
37
|
+
* that exist on the server but aren't in the push set.
|
|
38
|
+
*/
|
|
39
|
+
export declare function checkReferences(documents: Array<{
|
|
40
|
+
content: string;
|
|
41
|
+
filePath: string;
|
|
42
|
+
}>, serverOperations?: Array<{
|
|
43
|
+
name: string;
|
|
44
|
+
type: string;
|
|
45
|
+
}>): BadReference[];
|
|
46
|
+
export interface BadIndex {
|
|
47
|
+
field: string;
|
|
48
|
+
indexType: string;
|
|
49
|
+
table: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Check table documents for indexes that reference fields not in the schema.
|
|
53
|
+
* Parses the XanoScript table format to extract schema field names and index field names.
|
|
54
|
+
*/
|
|
55
|
+
export declare function checkTableIndexes(documents: Array<{
|
|
56
|
+
content: string;
|
|
57
|
+
}>): BadIndex[];
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { parseDocument } from './document-parser.js';
|
|
2
|
+
/**
|
|
3
|
+
* All known cross-reference patterns in XanoScript.
|
|
4
|
+
*
|
|
5
|
+
* Each pattern matches a statement keyword followed by a quoted or unquoted name.
|
|
6
|
+
* The first capture group extracts the name (stripping quotes if present).
|
|
7
|
+
*/
|
|
8
|
+
const REFERENCE_PATTERNS = [
|
|
9
|
+
{ keyword: 'function.run', regex: /^\s*function\.run\s+("(?:[^"\\]|\\.)*"|[^\s{]+)/gm, targetType: 'function' },
|
|
10
|
+
{ keyword: 'function.call', regex: /^\s*function\.call\s+("(?:[^"\\]|\\.)*"|[^\s{]+)/gm, targetType: 'function' },
|
|
11
|
+
{ keyword: 'addon.call', regex: /^\s*addon\.call\s+("(?:[^"\\]|\\.)*"|[^\s{]+)/gm, targetType: 'addon' },
|
|
12
|
+
{ keyword: 'task.call', regex: /^\s*task\.call\s+("(?:[^"\\]|\\.)*"|[^\s{]+)/gm, targetType: 'task' },
|
|
13
|
+
{ keyword: 'tool.call', regex: /^\s*tool\.call\s+("(?:[^"\\]|\\.)*"|[^\s{]+)/gm, targetType: 'tool' },
|
|
14
|
+
{ keyword: 'middleware.call', regex: /^\s*middleware\.call\s+("(?:[^"\\]|\\.)*"|[^\s{]+)/gm, targetType: 'middleware' },
|
|
15
|
+
{ keyword: 'ai.agent.run', regex: /^\s*ai\.agent\.run\s+("(?:[^"\\]|\\.)*"|[^\s{]+)/gm, targetType: 'agent' },
|
|
16
|
+
{ keyword: 'trigger.call', regex: /^\s*trigger\.call\s+("(?:[^"\\]|\\.)*"|[^\s{]+)/gm, targetType: 'trigger' },
|
|
17
|
+
{ keyword: 'action.call', regex: /^\s*action\.call\s+("(?:[^"\\]|\\.)*"|[^\s{]+)/gm, targetType: 'action' },
|
|
18
|
+
{
|
|
19
|
+
keyword: 'workflow_test.call',
|
|
20
|
+
regex: /^\s*workflow_test\.call\s+("(?:[^"\\]|\\.)*"|[^\s{]+)/gm,
|
|
21
|
+
targetType: 'workflow_test',
|
|
22
|
+
},
|
|
23
|
+
// db.* statements reference tables: db.get, db.query, db.add, db.edit, db.add_or_edit, db.delete, db.bulk_add, db.bulk_delete, db.count
|
|
24
|
+
{
|
|
25
|
+
keyword: 'db.*',
|
|
26
|
+
regex: /^\s*db\.(?:get|query|add|edit|add_or_edit|delete|bulk_add|bulk_delete|count)\s+("(?:[^"\\]|\\.)*"|[^\s{]+)/gm,
|
|
27
|
+
targetType: 'table',
|
|
28
|
+
},
|
|
29
|
+
// Schema foreign key references: table = "name" inside field definitions
|
|
30
|
+
{ keyword: 'table (FK)', regex: /\btable\s*=\s*"([^"]*)"/gm, targetType: 'table' },
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* Strip surrounding quotes from a name if present.
|
|
34
|
+
*/
|
|
35
|
+
function stripQuotes(name) {
|
|
36
|
+
if (name.startsWith('"') && name.endsWith('"')) {
|
|
37
|
+
return name.slice(1, -1);
|
|
38
|
+
}
|
|
39
|
+
return name;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Map from XanoScript document types to the canonical type used in the registry.
|
|
43
|
+
* Some types are aliases (agent, mcp_server → toolset bucket, but referenced as "agent").
|
|
44
|
+
*/
|
|
45
|
+
/* eslint-disable camelcase */
|
|
46
|
+
const TYPE_ALIASES = {
|
|
47
|
+
agent: 'agent',
|
|
48
|
+
mcp_server: 'agent',
|
|
49
|
+
toolset: 'agent',
|
|
50
|
+
};
|
|
51
|
+
/* eslint-enable camelcase */
|
|
52
|
+
/**
|
|
53
|
+
* Normalize a document type to its canonical registry type.
|
|
54
|
+
*/
|
|
55
|
+
function normalizeType(type) {
|
|
56
|
+
return TYPE_ALIASES[type] ?? type;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Build a registry of all defined object names from parsed documents.
|
|
60
|
+
* Returns a Map of type → Set of names.
|
|
61
|
+
*/
|
|
62
|
+
export function buildRegistry(documents) {
|
|
63
|
+
const registry = new Map();
|
|
64
|
+
for (const doc of documents) {
|
|
65
|
+
const parsed = parseDocument(doc.content);
|
|
66
|
+
if (!parsed)
|
|
67
|
+
continue;
|
|
68
|
+
const type = normalizeType(parsed.type);
|
|
69
|
+
if (!registry.has(type)) {
|
|
70
|
+
registry.set(type, new Set());
|
|
71
|
+
}
|
|
72
|
+
registry.get(type).add(parsed.name);
|
|
73
|
+
}
|
|
74
|
+
return registry;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Build a registry of server-known object names from dry-run operations.
|
|
78
|
+
* Any object that appears in the dry-run (create, update, unchanged, delete) exists
|
|
79
|
+
* either locally or on the server.
|
|
80
|
+
*/
|
|
81
|
+
export function buildServerRegistry(operations) {
|
|
82
|
+
const registry = new Map();
|
|
83
|
+
for (const op of operations) {
|
|
84
|
+
const type = normalizeType(op.type);
|
|
85
|
+
if (!registry.has(type)) {
|
|
86
|
+
registry.set(type, new Set());
|
|
87
|
+
}
|
|
88
|
+
// Operation names for queries include the verb (e.g., "path/{id} DELETE")
|
|
89
|
+
// but references use just the name, so strip the verb suffix
|
|
90
|
+
const name = op.name.replace(/\s+(?:GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)$/, '');
|
|
91
|
+
registry.get(type).add(name);
|
|
92
|
+
}
|
|
93
|
+
return registry;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Check all documents for cross-references that point to names not in the registry.
|
|
97
|
+
*
|
|
98
|
+
* When serverOperations is provided (from dry-run), references are checked against
|
|
99
|
+
* both local files AND server-known objects, eliminating false positives for objects
|
|
100
|
+
* that exist on the server but aren't in the push set.
|
|
101
|
+
*/
|
|
102
|
+
export function checkReferences(documents, serverOperations) {
|
|
103
|
+
const registry = buildRegistry(documents);
|
|
104
|
+
// Merge server-known names into the registry
|
|
105
|
+
if (serverOperations) {
|
|
106
|
+
const serverRegistry = buildServerRegistry(serverOperations);
|
|
107
|
+
for (const [type, names] of serverRegistry) {
|
|
108
|
+
if (!registry.has(type)) {
|
|
109
|
+
registry.set(type, new Set());
|
|
110
|
+
}
|
|
111
|
+
for (const name of names) {
|
|
112
|
+
registry.get(type).add(name);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const badRefs = [];
|
|
117
|
+
for (const doc of documents) {
|
|
118
|
+
const parsed = parseDocument(doc.content);
|
|
119
|
+
if (!parsed)
|
|
120
|
+
continue;
|
|
121
|
+
for (const pattern of REFERENCE_PATTERNS) {
|
|
122
|
+
// Reset regex state for each document
|
|
123
|
+
pattern.regex.lastIndex = 0;
|
|
124
|
+
let match;
|
|
125
|
+
while ((match = pattern.regex.exec(doc.content)) !== null) {
|
|
126
|
+
const rawName = stripQuotes(match[1]);
|
|
127
|
+
// Skip empty names only for action.call (valid for integration actions)
|
|
128
|
+
if (!rawName && pattern.keyword === 'action.call')
|
|
129
|
+
continue;
|
|
130
|
+
const { targetType } = pattern;
|
|
131
|
+
const knownNames = registry.get(targetType);
|
|
132
|
+
if (!knownNames || !knownNames.has(rawName)) {
|
|
133
|
+
badRefs.push({
|
|
134
|
+
source: parsed.name,
|
|
135
|
+
sourceType: parsed.type,
|
|
136
|
+
statementType: pattern.keyword,
|
|
137
|
+
target: rawName,
|
|
138
|
+
targetType,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return badRefs;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Check table documents for indexes that reference fields not in the schema.
|
|
148
|
+
* Parses the XanoScript table format to extract schema field names and index field names.
|
|
149
|
+
*/
|
|
150
|
+
export function checkTableIndexes(documents) {
|
|
151
|
+
const badIndexes = [];
|
|
152
|
+
for (const doc of documents) {
|
|
153
|
+
const parsed = parseDocument(doc.content);
|
|
154
|
+
if (!parsed || parsed.type !== 'table')
|
|
155
|
+
continue;
|
|
156
|
+
const schemaFields = extractSchemaFields(doc.content);
|
|
157
|
+
const indexes = extractIndexes(doc.content);
|
|
158
|
+
for (const idx of indexes) {
|
|
159
|
+
for (const field of idx.fields) {
|
|
160
|
+
if (!schemaFields.has(field)) {
|
|
161
|
+
badIndexes.push({
|
|
162
|
+
field,
|
|
163
|
+
indexType: idx.type,
|
|
164
|
+
table: parsed.name,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return badIndexes;
|
|
171
|
+
}
|
|
172
|
+
function extractSchemaFields(content) {
|
|
173
|
+
// id and created_at are auto-added during import
|
|
174
|
+
const fields = new Set(['id', 'created_at']);
|
|
175
|
+
// Find the schema block by matching braces
|
|
176
|
+
const schemaStart = content.match(/\bschema\s*\{/);
|
|
177
|
+
if (!schemaStart || schemaStart.index === undefined)
|
|
178
|
+
return fields;
|
|
179
|
+
let depth = 0;
|
|
180
|
+
let blockStart = -1;
|
|
181
|
+
let blockEnd = -1;
|
|
182
|
+
for (let i = schemaStart.index; i < content.length; i++) {
|
|
183
|
+
if (content[i] === '{') {
|
|
184
|
+
if (depth === 0)
|
|
185
|
+
blockStart = i + 1;
|
|
186
|
+
depth++;
|
|
187
|
+
}
|
|
188
|
+
else if (content[i] === '}') {
|
|
189
|
+
depth--;
|
|
190
|
+
if (depth === 0) {
|
|
191
|
+
blockEnd = i;
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (blockStart < 0 || blockEnd < 0)
|
|
197
|
+
return fields;
|
|
198
|
+
const schemaBlock = content.slice(blockStart, blockEnd);
|
|
199
|
+
// Match field declarations: "type name" or "type? name" or "type name?=default"
|
|
200
|
+
const fieldRegex = /^\s*\w+\??\s+(\w+)[?\s{]/gm;
|
|
201
|
+
let match;
|
|
202
|
+
while ((match = fieldRegex.exec(schemaBlock)) !== null) {
|
|
203
|
+
fields.add(match[1]);
|
|
204
|
+
}
|
|
205
|
+
return fields;
|
|
206
|
+
}
|
|
207
|
+
function extractIndexes(content) {
|
|
208
|
+
const indexes = [];
|
|
209
|
+
// Match the index array: index = [ ... ]
|
|
210
|
+
const indexMatch = content.match(/\bindex\s*=\s*\[([\s\S]*?)\n\s*\]/);
|
|
211
|
+
if (!indexMatch)
|
|
212
|
+
return indexes;
|
|
213
|
+
const indexBlock = indexMatch[1];
|
|
214
|
+
// Match each index object: {type: "btree", field: [{name: "col", op: "desc"}]}
|
|
215
|
+
const entryRegex = /\{([^}]+)\}/g;
|
|
216
|
+
let match;
|
|
217
|
+
while ((match = entryRegex.exec(indexBlock)) !== null) {
|
|
218
|
+
const entry = match[1];
|
|
219
|
+
const typeMatch = entry.match(/type:\s*"(\w+)"/);
|
|
220
|
+
const type = typeMatch ? typeMatch[1] : 'unknown';
|
|
221
|
+
const fieldNames = [];
|
|
222
|
+
const nameRegex = /name:\s*"(\w*)"/g;
|
|
223
|
+
let nameMatch;
|
|
224
|
+
while ((nameMatch = nameRegex.exec(entry)) !== null) {
|
|
225
|
+
fieldNames.push(nameMatch[1]);
|
|
226
|
+
}
|
|
227
|
+
if (fieldNames.length > 0) {
|
|
228
|
+
indexes.push({ fields: fieldNames, type });
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return indexes;
|
|
232
|
+
}
|