@yoryoboy/bi-mcp 1.1.0 → 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 +126 -9
- package/dist/.tsbuildinfo +1 -1
- package/dist/index.js +332 -2
- package/dist/index.js.map +2 -2
- package/dist/mcp-use.json +2 -2
- package/dist/scripts/_helpers.js +44 -0
- package/dist/scripts/_helpers.js.map +7 -0
- package/dist/scripts/admin-profile-delete.js +72 -0
- package/dist/scripts/admin-profile-delete.js.map +7 -0
- package/dist/scripts/admin-profile-list.js +24 -0
- package/dist/scripts/admin-profile-list.js.map +7 -0
- package/dist/scripts/admin-profile-upsert.js +25 -0
- package/dist/scripts/admin-profile-upsert.js.map +7 -0
- package/dist/scripts/admin-vtex-list.js +28 -0
- package/dist/scripts/admin-vtex-list.js.map +7 -0
- package/dist/scripts/admin-vtex-upsert.js +73 -0
- package/dist/scripts/admin-vtex-upsert.js.map +7 -0
- package/dist/scripts/admin-vtex-validate.js +55 -0
- package/dist/scripts/admin-vtex-validate.js.map +7 -0
- package/dist/scripts/run-migrations.js +50 -0
- package/dist/scripts/run-migrations.js.map +7 -0
- package/dist/scripts/test-db-connection.js +19 -0
- package/dist/scripts/test-db-connection.js.map +7 -0
- package/dist/src/config/profile-store.js +86 -0
- package/dist/src/config/profile-store.js.map +7 -0
- package/dist/src/config/vtex-crypto.js +43 -0
- package/dist/src/config/vtex-crypto.js.map +7 -0
- package/dist/src/config/vtex-profile-store.js +132 -0
- package/dist/src/config/vtex-profile-store.js.map +7 -0
- package/dist/src/config/vtex.js +27 -21
- package/dist/src/config/vtex.js.map +2 -2
- package/dist/src/db/client.js +58 -0
- package/dist/src/db/client.js.map +7 -0
- package/dist/src/services/vtex/vtex-api.js +24 -8
- package/dist/src/services/vtex/vtex-api.js.map +2 -2
- package/dist/src/services/vtex/vtex-catalog-write.js +233 -0
- package/dist/src/services/vtex/vtex-catalog-write.js.map +7 -0
- package/dist/src/services/vtex/vtex-catalog.js +5 -3
- package/dist/src/services/vtex/vtex-catalog.js.map +2 -2
- package/dist/src/services/vtex/vtex-logistics.js +18 -9
- package/dist/src/services/vtex/vtex-logistics.js.map +2 -2
- package/dist/src/services/vtex/vtex-orders-write.js +152 -0
- package/dist/src/services/vtex/vtex-orders-write.js.map +7 -0
- package/dist/src/services/vtex/vtex-orders.js +13 -7
- package/dist/src/services/vtex/vtex-orders.js.map +2 -2
- package/dist/src/services/vtex/vtex-pricing-write.js +24 -0
- package/dist/src/services/vtex/vtex-pricing-write.js.map +7 -0
- package/dist/src/services/vtex/vtex-pricing.js +5 -3
- package/dist/src/services/vtex/vtex-pricing.js.map +2 -2
- package/dist/src/services/vtex/vtex-write.js +38 -0
- package/dist/src/services/vtex/vtex-write.js.map +7 -0
- package/dist/src/tools/config/check-database-connection.js +59 -0
- package/dist/src/tools/config/check-database-connection.js.map +7 -0
- package/dist/src/tools/config/index.js +3 -0
- package/dist/src/tools/config/index.js.map +7 -0
- package/dist/src/tools/config/list-profiles.js +26 -0
- package/dist/src/tools/config/list-profiles.js.map +7 -0
- package/dist/src/tools/index.js +1 -0
- package/dist/src/tools/index.js.map +2 -2
- package/dist/src/tools/vtex/activate-sku.js +53 -0
- package/dist/src/tools/vtex/activate-sku.js.map +7 -0
- package/dist/src/tools/vtex/add-order-tracking.js +103 -0
- package/dist/src/tools/vtex/add-order-tracking.js.map +7 -0
- package/dist/src/tools/vtex/associate-specification.js +60 -0
- package/dist/src/tools/vtex/associate-specification.js.map +7 -0
- package/dist/src/tools/vtex/attach-catalog-image.js +63 -0
- package/dist/src/tools/vtex/attach-catalog-image.js.map +7 -0
- package/dist/src/tools/vtex/cancel-order.js +67 -0
- package/dist/src/tools/vtex/cancel-order.js.map +7 -0
- package/dist/src/tools/vtex/computed-price.js +12 -1
- package/dist/src/tools/vtex/computed-price.js.map +2 -2
- package/dist/src/tools/vtex/create-brand.js +69 -0
- package/dist/src/tools/vtex/create-brand.js.map +7 -0
- package/dist/src/tools/vtex/create-category.js +81 -0
- package/dist/src/tools/vtex/create-category.js.map +7 -0
- package/dist/src/tools/vtex/create-product-with-sku.js +120 -0
- package/dist/src/tools/vtex/create-product-with-sku.js.map +7 -0
- package/dist/src/tools/vtex/create-product.js +111 -0
- package/dist/src/tools/vtex/create-product.js.map +7 -0
- package/dist/src/tools/vtex/create-sku.js +103 -0
- package/dist/src/tools/vtex/create-sku.js.map +7 -0
- package/dist/src/tools/vtex/create-specification-value.js +53 -0
- package/dist/src/tools/vtex/create-specification-value.js.map +7 -0
- package/dist/src/tools/vtex/create-specification.js +85 -0
- package/dist/src/tools/vtex/create-specification.js.map +7 -0
- package/dist/src/tools/vtex/deactivate-sku.js +53 -0
- package/dist/src/tools/vtex/deactivate-sku.js.map +7 -0
- package/dist/src/tools/vtex/delete-fixed-price.js +53 -0
- package/dist/src/tools/vtex/delete-fixed-price.js.map +7 -0
- package/dist/src/tools/vtex/index.js +21 -0
- package/dist/src/tools/vtex/index.js.map +2 -2
- package/dist/src/tools/vtex/inventory-check.js +15 -2
- package/dist/src/tools/vtex/inventory-check.js.map +2 -2
- package/dist/src/tools/vtex/invoice-order.js +84 -0
- package/dist/src/tools/vtex/invoice-order.js.map +7 -0
- package/dist/src/tools/vtex/order-details.js +16 -2
- package/dist/src/tools/vtex/order-details.js.map +2 -2
- package/dist/src/tools/vtex/orders-summary.js +11 -1
- package/dist/src/tools/vtex/orders-summary.js.map +2 -2
- package/dist/src/tools/vtex/product-offers.js +15 -2
- package/dist/src/tools/vtex/product-offers.js.map +2 -2
- package/dist/src/tools/vtex/profile-resolution.js +57 -0
- package/dist/src/tools/vtex/profile-resolution.js.map +7 -0
- package/dist/src/tools/vtex/sku-offers.js +16 -2
- package/dist/src/tools/vtex/sku-offers.js.map +2 -2
- package/dist/src/tools/vtex/sku-price.js +12 -2
- package/dist/src/tools/vtex/sku-price.js.map +2 -2
- package/dist/src/tools/vtex/toggle-unlimited-quantity.js +65 -0
- package/dist/src/tools/vtex/toggle-unlimited-quantity.js.map +7 -0
- package/dist/src/tools/vtex/update-inventory.js +40 -14
- package/dist/src/tools/vtex/update-inventory.js.map +2 -2
- package/dist/src/tools/vtex/update-lead-time.js +40 -12
- package/dist/src/tools/vtex/update-lead-time.js.map +2 -2
- package/dist/src/tools/vtex/update-product-basic-fields.js +71 -0
- package/dist/src/tools/vtex/update-product-basic-fields.js.map +7 -0
- package/dist/src/tools/vtex/update-sku-basic-fields.js +92 -0
- package/dist/src/tools/vtex/update-sku-basic-fields.js.map +7 -0
- package/dist/src/tools/vtex/update-sku-price.js +81 -0
- package/dist/src/tools/vtex/update-sku-price.js.map +7 -0
- package/dist/src/tools/vtex/upsert-fixed-price.js +69 -0
- package/dist/src/tools/vtex/upsert-fixed-price.js.map +7 -0
- package/dist/src/tools/vtex/warehouse-inventory.js +12 -1
- package/dist/src/tools/vtex/warehouse-inventory.js.map +2 -2
- package/dist/src/tools/vtex/write-helpers.js +73 -0
- package/dist/src/tools/vtex/write-helpers.js.map +7 -0
- package/package.json +12 -2
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
function loadLocalEnv() {
|
|
3
|
+
process.loadEnvFile?.(".env");
|
|
4
|
+
}
|
|
5
|
+
function parseCliArgs(argv) {
|
|
6
|
+
const values = {};
|
|
7
|
+
const flags = /* @__PURE__ */ new Set();
|
|
8
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
9
|
+
const token = argv[index];
|
|
10
|
+
if (!token.startsWith("--")) {
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
const key = token.slice(2);
|
|
14
|
+
const next = argv[index + 1];
|
|
15
|
+
if (!next || next.startsWith("--")) {
|
|
16
|
+
flags.add(key);
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
values[key] = next;
|
|
20
|
+
index += 1;
|
|
21
|
+
}
|
|
22
|
+
return { values, flags };
|
|
23
|
+
}
|
|
24
|
+
function requireArg(args, name) {
|
|
25
|
+
const value = args.values[name]?.trim();
|
|
26
|
+
if (!value) {
|
|
27
|
+
throw new Error(`Missing required argument: --${name}`);
|
|
28
|
+
}
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
function hasFlag(args, name) {
|
|
32
|
+
return args.flags.has(name);
|
|
33
|
+
}
|
|
34
|
+
function logJson(value) {
|
|
35
|
+
console.log(JSON.stringify(value, null, 2));
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
hasFlag,
|
|
39
|
+
loadLocalEnv,
|
|
40
|
+
logJson,
|
|
41
|
+
parseCliArgs,
|
|
42
|
+
requireArg
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=_helpers.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../scripts/_helpers.ts"],
|
|
4
|
+
"sourcesContent": ["import process from \"node:process\";\n\nexport interface ParsedArgs {\n values: Record<string, string>;\n flags: Set<string>;\n}\n\nexport function loadLocalEnv() {\n process.loadEnvFile?.(\".env\");\n}\n\nexport function parseCliArgs(argv: string[]): ParsedArgs {\n const values: Record<string, string> = {};\n const flags = new Set<string>();\n\n for (let index = 0; index < argv.length; index += 1) {\n const token = argv[index];\n if (!token.startsWith(\"--\")) {\n continue;\n }\n\n const key = token.slice(2);\n const next = argv[index + 1];\n\n if (!next || next.startsWith(\"--\")) {\n flags.add(key);\n continue;\n }\n\n values[key] = next;\n index += 1;\n }\n\n return { values, flags };\n}\n\nexport function requireArg(args: ParsedArgs, name: string): string {\n const value = args.values[name]?.trim();\n if (!value) {\n throw new Error(`Missing required argument: --${name}`);\n }\n\n return value;\n}\n\nexport function hasFlag(args: ParsedArgs, name: string): boolean {\n return args.flags.has(name);\n}\n\nexport function logJson(value: unknown) {\n console.log(JSON.stringify(value, null, 2));\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,aAAa;AAOb,SAAS,eAAe;AAC7B,UAAQ,cAAc,MAAM;AAC9B;AAEO,SAAS,aAAa,MAA4B;AACvD,QAAM,SAAiC,CAAC;AACxC,QAAM,QAAQ,oBAAI,IAAY;AAE9B,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,UAAM,QAAQ,KAAK,KAAK;AACxB,QAAI,CAAC,MAAM,WAAW,IAAI,GAAG;AAC3B;AAAA,IACF;AAEA,UAAM,MAAM,MAAM,MAAM,CAAC;AACzB,UAAM,OAAO,KAAK,QAAQ,CAAC;AAE3B,QAAI,CAAC,QAAQ,KAAK,WAAW,IAAI,GAAG;AAClC,YAAM,IAAI,GAAG;AACb;AAAA,IACF;AAEA,WAAO,GAAG,IAAI;AACd,aAAS;AAAA,EACX;AAEA,SAAO,EAAE,QAAQ,MAAM;AACzB;AAEO,SAAS,WAAW,MAAkB,MAAsB;AACjE,QAAM,QAAQ,KAAK,OAAO,IAAI,GAAG,KAAK;AACtC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,gCAAgC,IAAI,EAAE;AAAA,EACxD;AAEA,SAAO;AACT;AAEO,SAAS,QAAQ,MAAkB,MAAuB;AAC/D,SAAO,KAAK,MAAM,IAAI,IAAI;AAC5B;AAEO,SAAS,QAAQ,OAAgB;AACtC,UAAQ,IAAI,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAC5C;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { loadLocalEnv, parseCliArgs, requireArg } from "./_helpers.js";
|
|
3
|
+
async function main() {
|
|
4
|
+
loadLocalEnv();
|
|
5
|
+
const args = parseCliArgs(process.argv.slice(2));
|
|
6
|
+
const profileId = requireArg(args, "profile-id");
|
|
7
|
+
const confirmDelete = requireArg(args, "confirm-delete");
|
|
8
|
+
if (confirmDelete !== profileId) {
|
|
9
|
+
throw new Error(
|
|
10
|
+
`Confirmation mismatch: --confirm-delete must exactly match --profile-id ("${profileId}")`
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
const { deleteProfile, getProfile } = await import("../src/config/profile-store.js");
|
|
14
|
+
const { getVtexConnectionRow } = await import("../src/config/vtex-profile-store.js");
|
|
15
|
+
const [profile, vtexConnection] = await Promise.all([
|
|
16
|
+
getProfile(profileId),
|
|
17
|
+
getVtexConnectionRow(profileId)
|
|
18
|
+
]);
|
|
19
|
+
if (!profile) {
|
|
20
|
+
throw new Error(`Profile not found: "${profileId}"`);
|
|
21
|
+
}
|
|
22
|
+
console.log("About to hard delete profile");
|
|
23
|
+
console.log(
|
|
24
|
+
JSON.stringify(
|
|
25
|
+
{
|
|
26
|
+
profile: {
|
|
27
|
+
profile_id: profile.id,
|
|
28
|
+
name: profile.name,
|
|
29
|
+
is_active: profile.isActive,
|
|
30
|
+
created_at: profile.createdAt.toISOString(),
|
|
31
|
+
updated_at: profile.updatedAt.toISOString()
|
|
32
|
+
},
|
|
33
|
+
vtex_connection: vtexConnection ? {
|
|
34
|
+
profile_id: vtexConnection.profileId,
|
|
35
|
+
account_name: vtexConnection.accountName,
|
|
36
|
+
is_active: vtexConnection.isActive,
|
|
37
|
+
status: vtexConnection.status,
|
|
38
|
+
last_validated_at: vtexConnection.lastValidatedAt?.toISOString() ?? null,
|
|
39
|
+
updated_at: vtexConnection.updatedAt.toISOString()
|
|
40
|
+
} : null
|
|
41
|
+
},
|
|
42
|
+
null,
|
|
43
|
+
2
|
|
44
|
+
)
|
|
45
|
+
);
|
|
46
|
+
const deletedProfile = await deleteProfile(profileId);
|
|
47
|
+
if (!deletedProfile) {
|
|
48
|
+
throw new Error(`Profile disappeared before deletion completed: "${profileId}"`);
|
|
49
|
+
}
|
|
50
|
+
console.log("Profile hard delete OK");
|
|
51
|
+
console.log(
|
|
52
|
+
JSON.stringify(
|
|
53
|
+
{
|
|
54
|
+
deleted_profile: {
|
|
55
|
+
profile_id: deletedProfile.id,
|
|
56
|
+
name: deletedProfile.name,
|
|
57
|
+
is_active: deletedProfile.isActive,
|
|
58
|
+
deleted_at: deletedProfile.deletedAt.toISOString()
|
|
59
|
+
},
|
|
60
|
+
cascade_expected: ["profile_vtex_connections"]
|
|
61
|
+
},
|
|
62
|
+
null,
|
|
63
|
+
2
|
|
64
|
+
)
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
main().catch((error) => {
|
|
68
|
+
console.error("Profile hard delete failed");
|
|
69
|
+
console.error(error);
|
|
70
|
+
process.exitCode = 1;
|
|
71
|
+
});
|
|
72
|
+
//# sourceMappingURL=admin-profile-delete.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../scripts/admin-profile-delete.ts"],
|
|
4
|
+
"sourcesContent": ["import process from \"node:process\";\n\nimport { loadLocalEnv, parseCliArgs, requireArg } from \"./_helpers.js\";\n\nasync function main() {\n loadLocalEnv();\n\n const args = parseCliArgs(process.argv.slice(2));\n const profileId = requireArg(args, \"profile-id\");\n const confirmDelete = requireArg(args, \"confirm-delete\");\n\n if (confirmDelete !== profileId) {\n throw new Error(\n `Confirmation mismatch: --confirm-delete must exactly match --profile-id (\"${profileId}\")`\n );\n }\n\n const { deleteProfile, getProfile } = await import(\"../src/config/profile-store.js\");\n const { getVtexConnectionRow } = await import(\"../src/config/vtex-profile-store.js\");\n\n const [profile, vtexConnection] = await Promise.all([\n getProfile(profileId),\n getVtexConnectionRow(profileId),\n ]);\n\n if (!profile) {\n throw new Error(`Profile not found: \"${profileId}\"`);\n }\n\n console.log(\"About to hard delete profile\");\n console.log(\n JSON.stringify(\n {\n profile: {\n profile_id: profile.id,\n name: profile.name,\n is_active: profile.isActive,\n created_at: profile.createdAt.toISOString(),\n updated_at: profile.updatedAt.toISOString(),\n },\n vtex_connection: vtexConnection\n ? {\n profile_id: vtexConnection.profileId,\n account_name: vtexConnection.accountName,\n is_active: vtexConnection.isActive,\n status: vtexConnection.status,\n last_validated_at: vtexConnection.lastValidatedAt?.toISOString() ?? null,\n updated_at: vtexConnection.updatedAt.toISOString(),\n }\n : null,\n },\n null,\n 2\n )\n );\n\n const deletedProfile = await deleteProfile(profileId);\n\n if (!deletedProfile) {\n throw new Error(`Profile disappeared before deletion completed: \"${profileId}\"`);\n }\n\n console.log(\"Profile hard delete OK\");\n console.log(\n JSON.stringify(\n {\n deleted_profile: {\n profile_id: deletedProfile.id,\n name: deletedProfile.name,\n is_active: deletedProfile.isActive,\n deleted_at: deletedProfile.deletedAt.toISOString(),\n },\n cascade_expected: [\"profile_vtex_connections\"],\n },\n null,\n 2\n )\n );\n}\n\nmain().catch((error: unknown) => {\n console.error(\"Profile hard delete failed\");\n console.error(error);\n process.exitCode = 1;\n});\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,aAAa;AAEpB,SAAS,cAAc,cAAc,kBAAkB;AAEvD,eAAe,OAAO;AACpB,eAAa;AAEb,QAAM,OAAO,aAAa,QAAQ,KAAK,MAAM,CAAC,CAAC;AAC/C,QAAM,YAAY,WAAW,MAAM,YAAY;AAC/C,QAAM,gBAAgB,WAAW,MAAM,gBAAgB;AAEvD,MAAI,kBAAkB,WAAW;AAC/B,UAAM,IAAI;AAAA,MACR,6EAA6E,SAAS;AAAA,IACxF;AAAA,EACF;AAEA,QAAM,EAAE,eAAe,WAAW,IAAI,MAAM,OAAO,gCAAgC;AACnF,QAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,qCAAqC;AAEnF,QAAM,CAAC,SAAS,cAAc,IAAI,MAAM,QAAQ,IAAI;AAAA,IAClD,WAAW,SAAS;AAAA,IACpB,qBAAqB,SAAS;AAAA,EAChC,CAAC;AAED,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,uBAAuB,SAAS,GAAG;AAAA,EACrD;AAEA,UAAQ,IAAI,8BAA8B;AAC1C,UAAQ;AAAA,IACN,KAAK;AAAA,MACH;AAAA,QACE,SAAS;AAAA,UACP,YAAY,QAAQ;AAAA,UACpB,MAAM,QAAQ;AAAA,UACd,WAAW,QAAQ;AAAA,UACnB,YAAY,QAAQ,UAAU,YAAY;AAAA,UAC1C,YAAY,QAAQ,UAAU,YAAY;AAAA,QAC5C;AAAA,QACA,iBAAiB,iBACb;AAAA,UACE,YAAY,eAAe;AAAA,UAC3B,cAAc,eAAe;AAAA,UAC7B,WAAW,eAAe;AAAA,UAC1B,QAAQ,eAAe;AAAA,UACvB,mBAAmB,eAAe,iBAAiB,YAAY,KAAK;AAAA,UACpE,YAAY,eAAe,UAAU,YAAY;AAAA,QACnD,IACA;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,iBAAiB,MAAM,cAAc,SAAS;AAEpD,MAAI,CAAC,gBAAgB;AACnB,UAAM,IAAI,MAAM,mDAAmD,SAAS,GAAG;AAAA,EACjF;AAEA,UAAQ,IAAI,wBAAwB;AACpC,UAAQ;AAAA,IACN,KAAK;AAAA,MACH;AAAA,QACE,iBAAiB;AAAA,UACf,YAAY,eAAe;AAAA,UAC3B,MAAM,eAAe;AAAA,UACrB,WAAW,eAAe;AAAA,UAC1B,YAAY,eAAe,UAAU,YAAY;AAAA,QACnD;AAAA,QACA,kBAAkB,CAAC,0BAA0B;AAAA,MAC/C;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,KAAK,EAAE,MAAM,CAAC,UAAmB;AAC/B,UAAQ,MAAM,4BAA4B;AAC1C,UAAQ,MAAM,KAAK;AACnB,UAAQ,WAAW;AACrB,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { loadLocalEnv } from "./_helpers.js";
|
|
3
|
+
async function main() {
|
|
4
|
+
loadLocalEnv();
|
|
5
|
+
const { listProfiles } = await import("../src/config/profile-store.js");
|
|
6
|
+
const profiles = await listProfiles();
|
|
7
|
+
console.log(JSON.stringify(
|
|
8
|
+
profiles.map((profile) => ({
|
|
9
|
+
profile_id: profile.id,
|
|
10
|
+
name: profile.name,
|
|
11
|
+
is_active: profile.isActive,
|
|
12
|
+
created_at: profile.createdAt.toISOString(),
|
|
13
|
+
updated_at: profile.updatedAt.toISOString()
|
|
14
|
+
})),
|
|
15
|
+
null,
|
|
16
|
+
2
|
|
17
|
+
));
|
|
18
|
+
}
|
|
19
|
+
main().catch((error) => {
|
|
20
|
+
console.error("Profile list failed");
|
|
21
|
+
console.error(error);
|
|
22
|
+
process.exitCode = 1;
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=admin-profile-list.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../scripts/admin-profile-list.ts"],
|
|
4
|
+
"sourcesContent": ["import process from \"node:process\";\n\nimport { loadLocalEnv } from \"./_helpers.js\";\n\nasync function main() {\n loadLocalEnv();\n\n const { listProfiles } = await import(\"../src/config/profile-store.js\");\n const profiles = await listProfiles();\n\n console.log(JSON.stringify(\n profiles.map((profile) => ({\n profile_id: profile.id,\n name: profile.name,\n is_active: profile.isActive,\n created_at: profile.createdAt.toISOString(),\n updated_at: profile.updatedAt.toISOString(),\n })),\n null,\n 2\n ));\n}\n\nmain().catch((error: unknown) => {\n console.error(\"Profile list failed\");\n console.error(error);\n process.exitCode = 1;\n});\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,aAAa;AAEpB,SAAS,oBAAoB;AAE7B,eAAe,OAAO;AACpB,eAAa;AAEb,QAAM,EAAE,aAAa,IAAI,MAAM,OAAO,gCAAgC;AACtE,QAAM,WAAW,MAAM,aAAa;AAEpC,UAAQ,IAAI,KAAK;AAAA,IACf,SAAS,IAAI,CAAC,aAAa;AAAA,MACzB,YAAY,QAAQ;AAAA,MACpB,MAAM,QAAQ;AAAA,MACd,WAAW,QAAQ;AAAA,MACnB,YAAY,QAAQ,UAAU,YAAY;AAAA,MAC1C,YAAY,QAAQ,UAAU,YAAY;AAAA,IAC5C,EAAE;AAAA,IACF;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAEA,KAAK,EAAE,MAAM,CAAC,UAAmB;AAC/B,UAAQ,MAAM,qBAAqB;AACnC,UAAQ,MAAM,KAAK;AACnB,UAAQ,WAAW;AACrB,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { hasFlag, loadLocalEnv, parseCliArgs, requireArg } from "./_helpers.js";
|
|
3
|
+
async function main() {
|
|
4
|
+
loadLocalEnv();
|
|
5
|
+
const args = parseCliArgs(process.argv.slice(2));
|
|
6
|
+
const id = requireArg(args, "profile-id");
|
|
7
|
+
const name = requireArg(args, "name");
|
|
8
|
+
const isActive = !hasFlag(args, "inactive");
|
|
9
|
+
const { upsertProfile } = await import("../src/config/profile-store.js");
|
|
10
|
+
const profile = await upsertProfile({ id, name, isActive });
|
|
11
|
+
console.log("Profile upsert OK");
|
|
12
|
+
console.log(JSON.stringify({
|
|
13
|
+
profile_id: profile.id,
|
|
14
|
+
name: profile.name,
|
|
15
|
+
is_active: profile.isActive,
|
|
16
|
+
created_at: profile.createdAt.toISOString(),
|
|
17
|
+
updated_at: profile.updatedAt.toISOString()
|
|
18
|
+
}, null, 2));
|
|
19
|
+
}
|
|
20
|
+
main().catch((error) => {
|
|
21
|
+
console.error("Profile upsert failed");
|
|
22
|
+
console.error(error);
|
|
23
|
+
process.exitCode = 1;
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=admin-profile-upsert.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../scripts/admin-profile-upsert.ts"],
|
|
4
|
+
"sourcesContent": ["import process from \"node:process\";\n\nimport { hasFlag, loadLocalEnv, parseCliArgs, requireArg } from \"./_helpers.js\";\n\nasync function main() {\n loadLocalEnv();\n\n const args = parseCliArgs(process.argv.slice(2));\n const id = requireArg(args, \"profile-id\");\n const name = requireArg(args, \"name\");\n const isActive = !hasFlag(args, \"inactive\");\n\n const { upsertProfile } = await import(\"../src/config/profile-store.js\");\n const profile = await upsertProfile({ id, name, isActive });\n\n console.log(\"Profile upsert OK\");\n console.log(JSON.stringify({\n profile_id: profile.id,\n name: profile.name,\n is_active: profile.isActive,\n created_at: profile.createdAt.toISOString(),\n updated_at: profile.updatedAt.toISOString(),\n }, null, 2));\n}\n\nmain().catch((error: unknown) => {\n console.error(\"Profile upsert failed\");\n console.error(error);\n process.exitCode = 1;\n});\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,aAAa;AAEpB,SAAS,SAAS,cAAc,cAAc,kBAAkB;AAEhE,eAAe,OAAO;AACpB,eAAa;AAEb,QAAM,OAAO,aAAa,QAAQ,KAAK,MAAM,CAAC,CAAC;AAC/C,QAAM,KAAK,WAAW,MAAM,YAAY;AACxC,QAAM,OAAO,WAAW,MAAM,MAAM;AACpC,QAAM,WAAW,CAAC,QAAQ,MAAM,UAAU;AAE1C,QAAM,EAAE,cAAc,IAAI,MAAM,OAAO,gCAAgC;AACvE,QAAM,UAAU,MAAM,cAAc,EAAE,IAAI,MAAM,SAAS,CAAC;AAE1D,UAAQ,IAAI,mBAAmB;AAC/B,UAAQ,IAAI,KAAK,UAAU;AAAA,IACzB,YAAY,QAAQ;AAAA,IACpB,MAAM,QAAQ;AAAA,IACd,WAAW,QAAQ;AAAA,IACnB,YAAY,QAAQ,UAAU,YAAY;AAAA,IAC1C,YAAY,QAAQ,UAAU,YAAY;AAAA,EAC5C,GAAG,MAAM,CAAC,CAAC;AACb;AAEA,KAAK,EAAE,MAAM,CAAC,UAAmB;AAC/B,UAAQ,MAAM,uBAAuB;AACrC,UAAQ,MAAM,KAAK;AACnB,UAAQ,WAAW;AACrB,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { loadLocalEnv } from "./_helpers.js";
|
|
3
|
+
async function main() {
|
|
4
|
+
loadLocalEnv();
|
|
5
|
+
const { listVtexConnections } = await import("../src/config/vtex-profile-store.js");
|
|
6
|
+
const connections = await listVtexConnections();
|
|
7
|
+
console.log(
|
|
8
|
+
JSON.stringify(
|
|
9
|
+
connections.map((connection) => ({
|
|
10
|
+
profile_id: connection.profileId,
|
|
11
|
+
profile_name: connection.profileName,
|
|
12
|
+
account_name: connection.accountName,
|
|
13
|
+
is_active: connection.isActive,
|
|
14
|
+
status: connection.status,
|
|
15
|
+
last_validated_at: connection.lastValidatedAt?.toISOString() ?? null,
|
|
16
|
+
last_error: connection.lastError
|
|
17
|
+
})),
|
|
18
|
+
null,
|
|
19
|
+
2
|
|
20
|
+
)
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
main().catch((error) => {
|
|
24
|
+
console.error("VTEX connection list failed");
|
|
25
|
+
console.error(error);
|
|
26
|
+
process.exitCode = 1;
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=admin-vtex-list.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../scripts/admin-vtex-list.ts"],
|
|
4
|
+
"sourcesContent": ["import process from \"node:process\";\n\nimport { loadLocalEnv } from \"./_helpers.js\";\n\nasync function main() {\n loadLocalEnv();\n\n const { listVtexConnections } = await import(\"../src/config/vtex-profile-store.js\");\n const connections = await listVtexConnections();\n\n console.log(\n JSON.stringify(\n connections.map((connection) => ({\n profile_id: connection.profileId,\n profile_name: connection.profileName,\n account_name: connection.accountName,\n is_active: connection.isActive,\n status: connection.status,\n last_validated_at: connection.lastValidatedAt?.toISOString() ?? null,\n last_error: connection.lastError,\n })),\n null,\n 2\n )\n );\n}\n\nmain().catch((error: unknown) => {\n console.error(\"VTEX connection list failed\");\n console.error(error);\n process.exitCode = 1;\n});\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,aAAa;AAEpB,SAAS,oBAAoB;AAE7B,eAAe,OAAO;AACpB,eAAa;AAEb,QAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,qCAAqC;AAClF,QAAM,cAAc,MAAM,oBAAoB;AAE9C,UAAQ;AAAA,IACN,KAAK;AAAA,MACH,YAAY,IAAI,CAAC,gBAAgB;AAAA,QAC/B,YAAY,WAAW;AAAA,QACvB,cAAc,WAAW;AAAA,QACzB,cAAc,WAAW;AAAA,QACzB,WAAW,WAAW;AAAA,QACtB,QAAQ,WAAW;AAAA,QACnB,mBAAmB,WAAW,iBAAiB,YAAY,KAAK;AAAA,QAChE,YAAY,WAAW;AAAA,MACzB,EAAE;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,KAAK,EAAE,MAAM,CAAC,UAAmB;AAC/B,UAAQ,MAAM,6BAA6B;AAC3C,UAAQ,MAAM,KAAK;AACnB,UAAQ,WAAW;AACrB,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { hasFlag, loadLocalEnv, parseCliArgs, requireArg } from "./_helpers.js";
|
|
3
|
+
async function main() {
|
|
4
|
+
loadLocalEnv();
|
|
5
|
+
const args = parseCliArgs(process.argv.slice(2));
|
|
6
|
+
const profileId = requireArg(args, "profile-id");
|
|
7
|
+
const accountName = requireArg(args, "account-name");
|
|
8
|
+
const apiKey = requireArg(args, "api-key");
|
|
9
|
+
const apiToken = requireArg(args, "api-token");
|
|
10
|
+
const isActive = !hasFlag(args, "inactive");
|
|
11
|
+
const [{ getProfile }, { encryptSecret }, { upsertVtexConnection }, { buildVtexUrls }, { validateVtexConfig }] = await Promise.all([
|
|
12
|
+
import("../src/config/profile-store.js"),
|
|
13
|
+
import("../src/config/vtex-crypto.js"),
|
|
14
|
+
import("../src/config/vtex-profile-store.js"),
|
|
15
|
+
import("../src/config/vtex.js"),
|
|
16
|
+
import("../src/services/vtex/vtex-api.js")
|
|
17
|
+
]);
|
|
18
|
+
const profile = await getProfile(profileId);
|
|
19
|
+
if (!profile) {
|
|
20
|
+
throw new Error(`Profile not found: "${profileId}"`);
|
|
21
|
+
}
|
|
22
|
+
const encryptedApiKey = encryptSecret(apiKey);
|
|
23
|
+
const encryptedApiToken = encryptSecret(apiToken);
|
|
24
|
+
const urls = buildVtexUrls(accountName);
|
|
25
|
+
let status = "valid";
|
|
26
|
+
let lastError = null;
|
|
27
|
+
let lastValidatedAt = null;
|
|
28
|
+
try {
|
|
29
|
+
await validateVtexConfig({
|
|
30
|
+
accountName,
|
|
31
|
+
apiKey,
|
|
32
|
+
apiToken,
|
|
33
|
+
baseUrl: urls.baseUrl,
|
|
34
|
+
pricingBaseUrl: urls.pricingBaseUrl
|
|
35
|
+
});
|
|
36
|
+
lastValidatedAt = /* @__PURE__ */ new Date();
|
|
37
|
+
} catch (error) {
|
|
38
|
+
status = "invalid";
|
|
39
|
+
lastError = error instanceof Error ? error.message : "VTEX validation failed";
|
|
40
|
+
lastValidatedAt = /* @__PURE__ */ new Date();
|
|
41
|
+
}
|
|
42
|
+
const connection = await upsertVtexConnection({
|
|
43
|
+
profileId,
|
|
44
|
+
accountName,
|
|
45
|
+
apiKeyEncrypted: encryptedApiKey,
|
|
46
|
+
apiTokenEncrypted: encryptedApiToken,
|
|
47
|
+
isActive,
|
|
48
|
+
status,
|
|
49
|
+
lastValidatedAt,
|
|
50
|
+
lastError
|
|
51
|
+
});
|
|
52
|
+
console.log("VTEX connection upsert OK");
|
|
53
|
+
console.log(
|
|
54
|
+
JSON.stringify(
|
|
55
|
+
{
|
|
56
|
+
profile_id: connection.profileId,
|
|
57
|
+
account_name: connection.accountName,
|
|
58
|
+
is_active: connection.isActive,
|
|
59
|
+
status: connection.status,
|
|
60
|
+
last_validated_at: connection.lastValidatedAt?.toISOString() ?? null,
|
|
61
|
+
last_error: connection.lastError
|
|
62
|
+
},
|
|
63
|
+
null,
|
|
64
|
+
2
|
|
65
|
+
)
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
main().catch((error) => {
|
|
69
|
+
console.error("VTEX connection upsert failed");
|
|
70
|
+
console.error(error);
|
|
71
|
+
process.exitCode = 1;
|
|
72
|
+
});
|
|
73
|
+
//# sourceMappingURL=admin-vtex-upsert.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../scripts/admin-vtex-upsert.ts"],
|
|
4
|
+
"sourcesContent": ["import process from \"node:process\";\n\nimport { hasFlag, loadLocalEnv, parseCliArgs, requireArg } from \"./_helpers.js\";\n\nasync function main() {\n loadLocalEnv();\n\n const args = parseCliArgs(process.argv.slice(2));\n const profileId = requireArg(args, \"profile-id\");\n const accountName = requireArg(args, \"account-name\");\n const apiKey = requireArg(args, \"api-key\");\n const apiToken = requireArg(args, \"api-token\");\n const isActive = !hasFlag(args, \"inactive\");\n\n const [{ getProfile }, { encryptSecret }, { upsertVtexConnection }, { buildVtexUrls }, { validateVtexConfig }] =\n await Promise.all([\n import(\"../src/config/profile-store.js\"),\n import(\"../src/config/vtex-crypto.js\"),\n import(\"../src/config/vtex-profile-store.js\"),\n import(\"../src/config/vtex.js\"),\n import(\"../src/services/vtex/vtex-api.js\"),\n ]);\n\n const profile = await getProfile(profileId);\n if (!profile) {\n throw new Error(`Profile not found: \"${profileId}\"`);\n }\n\n const encryptedApiKey = encryptSecret(apiKey);\n const encryptedApiToken = encryptSecret(apiToken);\n const urls = buildVtexUrls(accountName);\n\n let status: \"valid\" | \"invalid\" = \"valid\";\n let lastError: string | null = null;\n let lastValidatedAt: Date | null = null;\n\n try {\n await validateVtexConfig({\n accountName,\n apiKey,\n apiToken,\n baseUrl: urls.baseUrl,\n pricingBaseUrl: urls.pricingBaseUrl,\n });\n lastValidatedAt = new Date();\n } catch (error) {\n status = \"invalid\";\n lastError = error instanceof Error ? error.message : \"VTEX validation failed\";\n lastValidatedAt = new Date();\n }\n\n const connection = await upsertVtexConnection({\n profileId,\n accountName,\n apiKeyEncrypted: encryptedApiKey,\n apiTokenEncrypted: encryptedApiToken,\n isActive,\n status,\n lastValidatedAt,\n lastError,\n });\n\n console.log(\"VTEX connection upsert OK\");\n console.log(\n JSON.stringify(\n {\n profile_id: connection.profileId,\n account_name: connection.accountName,\n is_active: connection.isActive,\n status: connection.status,\n last_validated_at: connection.lastValidatedAt?.toISOString() ?? null,\n last_error: connection.lastError,\n },\n null,\n 2\n )\n );\n}\n\nmain().catch((error: unknown) => {\n console.error(\"VTEX connection upsert failed\");\n console.error(error);\n process.exitCode = 1;\n});\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,aAAa;AAEpB,SAAS,SAAS,cAAc,cAAc,kBAAkB;AAEhE,eAAe,OAAO;AACpB,eAAa;AAEb,QAAM,OAAO,aAAa,QAAQ,KAAK,MAAM,CAAC,CAAC;AAC/C,QAAM,YAAY,WAAW,MAAM,YAAY;AAC/C,QAAM,cAAc,WAAW,MAAM,cAAc;AACnD,QAAM,SAAS,WAAW,MAAM,SAAS;AACzC,QAAM,WAAW,WAAW,MAAM,WAAW;AAC7C,QAAM,WAAW,CAAC,QAAQ,MAAM,UAAU;AAE1C,QAAM,CAAC,EAAE,WAAW,GAAG,EAAE,cAAc,GAAG,EAAE,qBAAqB,GAAG,EAAE,cAAc,GAAG,EAAE,mBAAmB,CAAC,IAC3G,MAAM,QAAQ,IAAI;AAAA,IAChB,OAAO,gCAAgC;AAAA,IACvC,OAAO,8BAA8B;AAAA,IACrC,OAAO,qCAAqC;AAAA,IAC5C,OAAO,uBAAuB;AAAA,IAC9B,OAAO,kCAAkC;AAAA,EAC3C,CAAC;AAEH,QAAM,UAAU,MAAM,WAAW,SAAS;AAC1C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,uBAAuB,SAAS,GAAG;AAAA,EACrD;AAEA,QAAM,kBAAkB,cAAc,MAAM;AAC5C,QAAM,oBAAoB,cAAc,QAAQ;AAChD,QAAM,OAAO,cAAc,WAAW;AAEtC,MAAI,SAA8B;AAClC,MAAI,YAA2B;AAC/B,MAAI,kBAA+B;AAEnC,MAAI;AACF,UAAM,mBAAmB;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,KAAK;AAAA,MACd,gBAAgB,KAAK;AAAA,IACvB,CAAC;AACD,sBAAkB,oBAAI,KAAK;AAAA,EAC7B,SAAS,OAAO;AACd,aAAS;AACT,gBAAY,iBAAiB,QAAQ,MAAM,UAAU;AACrD,sBAAkB,oBAAI,KAAK;AAAA,EAC7B;AAEA,QAAM,aAAa,MAAM,qBAAqB;AAAA,IAC5C;AAAA,IACA;AAAA,IACA,iBAAiB;AAAA,IACjB,mBAAmB;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,UAAQ,IAAI,2BAA2B;AACvC,UAAQ;AAAA,IACN,KAAK;AAAA,MACH;AAAA,QACE,YAAY,WAAW;AAAA,QACvB,cAAc,WAAW;AAAA,QACzB,WAAW,WAAW;AAAA,QACtB,QAAQ,WAAW;AAAA,QACnB,mBAAmB,WAAW,iBAAiB,YAAY,KAAK;AAAA,QAChE,YAAY,WAAW;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,KAAK,EAAE,MAAM,CAAC,UAAmB;AAC/B,UAAQ,MAAM,+BAA+B;AAC7C,UAAQ,MAAM,KAAK;AACnB,UAAQ,WAAW;AACrB,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { loadLocalEnv, parseCliArgs, requireArg } from "./_helpers.js";
|
|
3
|
+
async function main() {
|
|
4
|
+
loadLocalEnv();
|
|
5
|
+
const args = parseCliArgs(process.argv.slice(2));
|
|
6
|
+
const profileId = requireArg(args, "profile-id");
|
|
7
|
+
const [{ getProfile }, { getVtexConnectionRow, markVtexConnectionValidation }, { decryptSecret }, { buildVtexUrls }, { validateVtexConfig }] = await Promise.all([
|
|
8
|
+
import("../src/config/profile-store.js"),
|
|
9
|
+
import("../src/config/vtex-profile-store.js"),
|
|
10
|
+
import("../src/config/vtex-crypto.js"),
|
|
11
|
+
import("../src/config/vtex.js"),
|
|
12
|
+
import("../src/services/vtex/vtex-api.js")
|
|
13
|
+
]);
|
|
14
|
+
const profile = await getProfile(profileId);
|
|
15
|
+
if (!profile) {
|
|
16
|
+
throw new Error(`Profile not found: "${profileId}"`);
|
|
17
|
+
}
|
|
18
|
+
const connection = await getVtexConnectionRow(profileId);
|
|
19
|
+
if (!connection) {
|
|
20
|
+
throw new Error(`VTEX connection not found for profileId "${profileId}"`);
|
|
21
|
+
}
|
|
22
|
+
const urls = buildVtexUrls(connection.accountName);
|
|
23
|
+
try {
|
|
24
|
+
await validateVtexConfig({
|
|
25
|
+
accountName: connection.accountName,
|
|
26
|
+
apiKey: decryptSecret(connection.apiKeyEncrypted),
|
|
27
|
+
apiToken: decryptSecret(connection.apiTokenEncrypted),
|
|
28
|
+
baseUrl: urls.baseUrl,
|
|
29
|
+
pricingBaseUrl: urls.pricingBaseUrl
|
|
30
|
+
});
|
|
31
|
+
await markVtexConnectionValidation(profileId, "valid", null);
|
|
32
|
+
console.log("VTEX connection validation OK");
|
|
33
|
+
console.log(
|
|
34
|
+
JSON.stringify(
|
|
35
|
+
{
|
|
36
|
+
profile_id: profileId,
|
|
37
|
+
status: "valid",
|
|
38
|
+
validated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
39
|
+
},
|
|
40
|
+
null,
|
|
41
|
+
2
|
|
42
|
+
)
|
|
43
|
+
);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
const message = error instanceof Error ? error.message : "VTEX validation failed";
|
|
46
|
+
await markVtexConnectionValidation(profileId, "invalid", message);
|
|
47
|
+
throw new Error(message);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
main().catch((error) => {
|
|
51
|
+
console.error("VTEX connection validation failed");
|
|
52
|
+
console.error(error);
|
|
53
|
+
process.exitCode = 1;
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=admin-vtex-validate.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../scripts/admin-vtex-validate.ts"],
|
|
4
|
+
"sourcesContent": ["import process from \"node:process\";\n\nimport { loadLocalEnv, parseCliArgs, requireArg } from \"./_helpers.js\";\n\nasync function main() {\n loadLocalEnv();\n\n const args = parseCliArgs(process.argv.slice(2));\n const profileId = requireArg(args, \"profile-id\");\n\n const [{ getProfile }, { getVtexConnectionRow, markVtexConnectionValidation }, { decryptSecret }, { buildVtexUrls }, { validateVtexConfig }] =\n await Promise.all([\n import(\"../src/config/profile-store.js\"),\n import(\"../src/config/vtex-profile-store.js\"),\n import(\"../src/config/vtex-crypto.js\"),\n import(\"../src/config/vtex.js\"),\n import(\"../src/services/vtex/vtex-api.js\"),\n ]);\n\n const profile = await getProfile(profileId);\n if (!profile) {\n throw new Error(`Profile not found: \"${profileId}\"`);\n }\n const connection = await getVtexConnectionRow(profileId);\n\n if (!connection) {\n throw new Error(`VTEX connection not found for profileId \"${profileId}\"`);\n }\n\n const urls = buildVtexUrls(connection.accountName);\n\n try {\n await validateVtexConfig({\n accountName: connection.accountName,\n apiKey: decryptSecret(connection.apiKeyEncrypted),\n apiToken: decryptSecret(connection.apiTokenEncrypted),\n baseUrl: urls.baseUrl,\n pricingBaseUrl: urls.pricingBaseUrl,\n });\n\n await markVtexConnectionValidation(profileId, \"valid\", null);\n\n console.log(\"VTEX connection validation OK\");\n console.log(\n JSON.stringify(\n {\n profile_id: profileId,\n status: \"valid\",\n validated_at: new Date().toISOString(),\n },\n null,\n 2\n )\n );\n } catch (error) {\n const message = error instanceof Error ? error.message : \"VTEX validation failed\";\n await markVtexConnectionValidation(profileId, \"invalid\", message);\n throw new Error(message);\n }\n}\n\nmain().catch((error: unknown) => {\n console.error(\"VTEX connection validation failed\");\n console.error(error);\n process.exitCode = 1;\n});\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,aAAa;AAEpB,SAAS,cAAc,cAAc,kBAAkB;AAEvD,eAAe,OAAO;AACpB,eAAa;AAEb,QAAM,OAAO,aAAa,QAAQ,KAAK,MAAM,CAAC,CAAC;AAC/C,QAAM,YAAY,WAAW,MAAM,YAAY;AAE/C,QAAM,CAAC,EAAE,WAAW,GAAG,EAAE,sBAAsB,6BAA6B,GAAG,EAAE,cAAc,GAAG,EAAE,cAAc,GAAG,EAAE,mBAAmB,CAAC,IACzI,MAAM,QAAQ,IAAI;AAAA,IAChB,OAAO,gCAAgC;AAAA,IACvC,OAAO,qCAAqC;AAAA,IAC5C,OAAO,8BAA8B;AAAA,IACrC,OAAO,uBAAuB;AAAA,IAC9B,OAAO,kCAAkC;AAAA,EAC3C,CAAC;AAEH,QAAM,UAAU,MAAM,WAAW,SAAS;AAC1C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,uBAAuB,SAAS,GAAG;AAAA,EACrD;AACA,QAAM,aAAa,MAAM,qBAAqB,SAAS;AAEvD,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,4CAA4C,SAAS,GAAG;AAAA,EAC1E;AAEA,QAAM,OAAO,cAAc,WAAW,WAAW;AAEjD,MAAI;AACF,UAAM,mBAAmB;AAAA,MACvB,aAAa,WAAW;AAAA,MACxB,QAAQ,cAAc,WAAW,eAAe;AAAA,MAChD,UAAU,cAAc,WAAW,iBAAiB;AAAA,MACpD,SAAS,KAAK;AAAA,MACd,gBAAgB,KAAK;AAAA,IACvB,CAAC;AAED,UAAM,6BAA6B,WAAW,SAAS,IAAI;AAE3D,YAAQ,IAAI,+BAA+B;AAC3C,YAAQ;AAAA,MACN,KAAK;AAAA,QACH;AAAA,UACE,YAAY;AAAA,UACZ,QAAQ;AAAA,UACR,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,QACvC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,UAAM,6BAA6B,WAAW,WAAW,OAAO;AAChE,UAAM,IAAI,MAAM,OAAO;AAAA,EACzB;AACF;AAEA,KAAK,EAAE,MAAM,CAAC,UAAmB;AAC/B,UAAQ,MAAM,mCAAmC;AACjD,UAAQ,MAAM,KAAK;AACnB,UAAQ,WAAW;AACrB,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { loadLocalEnv } from "./_helpers";
|
|
5
|
+
async function main() {
|
|
6
|
+
loadLocalEnv();
|
|
7
|
+
const { getDb, closeDb } = await import("../src/db/client.js");
|
|
8
|
+
const db = getDb();
|
|
9
|
+
const migrationsDir = path.resolve("db/migrations");
|
|
10
|
+
const files = (await readdir(migrationsDir)).filter((file) => file.endsWith(".sql")).sort((left, right) => left.localeCompare(right));
|
|
11
|
+
await db.query(`
|
|
12
|
+
create table if not exists schema_migrations (
|
|
13
|
+
filename text primary key,
|
|
14
|
+
applied_at timestamptz not null default now()
|
|
15
|
+
)
|
|
16
|
+
`);
|
|
17
|
+
const appliedResult = await db.query(
|
|
18
|
+
"select filename from schema_migrations"
|
|
19
|
+
);
|
|
20
|
+
const applied = new Set(appliedResult.rows.map((row) => row.filename));
|
|
21
|
+
const pending = files.filter((file) => !applied.has(file));
|
|
22
|
+
if (pending.length === 0) {
|
|
23
|
+
console.log("No pending migrations");
|
|
24
|
+
await closeDb();
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
for (const file of pending) {
|
|
28
|
+
const sql = await readFile(path.join(migrationsDir, file), "utf8");
|
|
29
|
+
const client = await db.connect();
|
|
30
|
+
try {
|
|
31
|
+
await client.query("begin");
|
|
32
|
+
await client.query(sql);
|
|
33
|
+
await client.query("insert into schema_migrations (filename) values ($1)", [file]);
|
|
34
|
+
await client.query("commit");
|
|
35
|
+
console.log(`Applied migration: ${file}`);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
await client.query("rollback");
|
|
38
|
+
throw error;
|
|
39
|
+
} finally {
|
|
40
|
+
client.release();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
await closeDb();
|
|
44
|
+
}
|
|
45
|
+
main().catch((error) => {
|
|
46
|
+
console.error("Migration run failed");
|
|
47
|
+
console.error(error);
|
|
48
|
+
process.exitCode = 1;
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=run-migrations.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../scripts/run-migrations.ts"],
|
|
4
|
+
"sourcesContent": ["import { readdir, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport process from \"node:process\";\n\nimport { loadLocalEnv } from \"./_helpers\";\n\nasync function main() {\n loadLocalEnv();\n\n const { getDb, closeDb } = await import(\"../src/db/client.js\");\n const db = getDb();\n const migrationsDir = path.resolve(\"db/migrations\");\n const files = (await readdir(migrationsDir))\n .filter((file) => file.endsWith(\".sql\"))\n .sort((left, right) => left.localeCompare(right));\n\n await db.query(`\n create table if not exists schema_migrations (\n filename text primary key,\n applied_at timestamptz not null default now()\n )\n `);\n\n const appliedResult = await db.query<{ filename: string }>(\n \"select filename from schema_migrations\"\n );\n const applied = new Set(appliedResult.rows.map((row) => row.filename));\n\n const pending = files.filter((file) => !applied.has(file));\n\n if (pending.length === 0) {\n console.log(\"No pending migrations\");\n await closeDb();\n return;\n }\n\n for (const file of pending) {\n const sql = await readFile(path.join(migrationsDir, file), \"utf8\");\n const client = await db.connect();\n\n try {\n await client.query(\"begin\");\n await client.query(sql);\n await client.query(\"insert into schema_migrations (filename) values ($1)\", [file]);\n await client.query(\"commit\");\n console.log(`Applied migration: ${file}`);\n } catch (error) {\n await client.query(\"rollback\");\n throw error;\n } finally {\n client.release();\n }\n }\n\n await closeDb();\n}\n\nmain().catch((error: unknown) => {\n console.error(\"Migration run failed\");\n console.error(error);\n process.exitCode = 1;\n});\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,SAAS,gBAAgB;AAClC,OAAO,UAAU;AACjB,OAAO,aAAa;AAEpB,SAAS,oBAAoB;AAE7B,eAAe,OAAO;AACpB,eAAa;AAEb,QAAM,EAAE,OAAO,QAAQ,IAAI,MAAM,OAAO,qBAAqB;AAC7D,QAAM,KAAK,MAAM;AACjB,QAAM,gBAAgB,KAAK,QAAQ,eAAe;AAClD,QAAM,SAAS,MAAM,QAAQ,aAAa,GACvC,OAAO,CAAC,SAAS,KAAK,SAAS,MAAM,CAAC,EACtC,KAAK,CAAC,MAAM,UAAU,KAAK,cAAc,KAAK,CAAC;AAElD,QAAM,GAAG,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,GAKd;AAED,QAAM,gBAAgB,MAAM,GAAG;AAAA,IAC7B;AAAA,EACF;AACA,QAAM,UAAU,IAAI,IAAI,cAAc,KAAK,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC;AAErE,QAAM,UAAU,MAAM,OAAO,CAAC,SAAS,CAAC,QAAQ,IAAI,IAAI,CAAC;AAEzD,MAAI,QAAQ,WAAW,GAAG;AACxB,YAAQ,IAAI,uBAAuB;AACnC,UAAM,QAAQ;AACd;AAAA,EACF;AAEA,aAAW,QAAQ,SAAS;AAC1B,UAAM,MAAM,MAAM,SAAS,KAAK,KAAK,eAAe,IAAI,GAAG,MAAM;AACjE,UAAM,SAAS,MAAM,GAAG,QAAQ;AAEhC,QAAI;AACF,YAAM,OAAO,MAAM,OAAO;AAC1B,YAAM,OAAO,MAAM,GAAG;AACtB,YAAM,OAAO,MAAM,wDAAwD,CAAC,IAAI,CAAC;AACjF,YAAM,OAAO,MAAM,QAAQ;AAC3B,cAAQ,IAAI,sBAAsB,IAAI,EAAE;AAAA,IAC1C,SAAS,OAAO;AACd,YAAM,OAAO,MAAM,UAAU;AAC7B,YAAM;AAAA,IACR,UAAE;AACA,aAAO,QAAQ;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,QAAQ;AAChB;AAEA,KAAK,EAAE,MAAM,CAAC,UAAmB;AAC/B,UAAQ,MAAM,sBAAsB;AACpC,UAAQ,MAAM,KAAK;AACnB,UAAQ,WAAW;AACrB,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
async function main() {
|
|
3
|
+
process.loadEnvFile?.(".env");
|
|
4
|
+
const { testDatabaseConnection } = await import("../src/db/client.js");
|
|
5
|
+
const result = await testDatabaseConnection();
|
|
6
|
+
console.log("Database connection OK");
|
|
7
|
+
console.log(`database: ${result.current_database}`);
|
|
8
|
+
console.log(`user: ${result.current_user}`);
|
|
9
|
+
console.log(`time: ${result.now.toISOString()}`);
|
|
10
|
+
}
|
|
11
|
+
main().catch((error) => {
|
|
12
|
+
console.error("Database connection failed");
|
|
13
|
+
console.error(error);
|
|
14
|
+
process.exitCode = 1;
|
|
15
|
+
}).finally(async () => {
|
|
16
|
+
const { closeDb } = await import("../src/db/client.js");
|
|
17
|
+
await closeDb();
|
|
18
|
+
});
|
|
19
|
+
//# sourceMappingURL=test-db-connection.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../scripts/test-db-connection.ts"],
|
|
4
|
+
"sourcesContent": ["import process from \"node:process\";\n\nasync function main() {\n // Local development helper: load values from .env when the runtime supports it.\n process.loadEnvFile?.(\".env\");\n\n const { testDatabaseConnection } = await import(\"../src/db/client.js\");\n const result = await testDatabaseConnection();\n\n console.log(\"Database connection OK\");\n console.log(`database: ${result.current_database}`);\n console.log(`user: ${result.current_user}`);\n console.log(`time: ${result.now.toISOString()}`);\n}\n\nmain()\n .catch((error: unknown) => {\n console.error(\"Database connection failed\");\n console.error(error);\n process.exitCode = 1;\n })\n .finally(async () => {\n const { closeDb } = await import(\"../src/db/client.js\");\n await closeDb();\n });\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,aAAa;AAEpB,eAAe,OAAO;AAEpB,UAAQ,cAAc,MAAM;AAE5B,QAAM,EAAE,uBAAuB,IAAI,MAAM,OAAO,qBAAqB;AACrE,QAAM,SAAS,MAAM,uBAAuB;AAE5C,UAAQ,IAAI,wBAAwB;AACpC,UAAQ,IAAI,aAAa,OAAO,gBAAgB,EAAE;AAClD,UAAQ,IAAI,SAAS,OAAO,YAAY,EAAE;AAC1C,UAAQ,IAAI,SAAS,OAAO,IAAI,YAAY,CAAC,EAAE;AACjD;AAEA,KAAK,EACF,MAAM,CAAC,UAAmB;AACzB,UAAQ,MAAM,4BAA4B;AAC1C,UAAQ,MAAM,KAAK;AACnB,UAAQ,WAAW;AACrB,CAAC,EACA,QAAQ,YAAY;AACnB,QAAM,EAAE,QAAQ,IAAI,MAAM,OAAO,qBAAqB;AACtD,QAAM,QAAQ;AAChB,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { getDb } from "../db/client.js";
|
|
2
|
+
function mapProfileRow(row) {
|
|
3
|
+
return {
|
|
4
|
+
id: row.id,
|
|
5
|
+
name: row.name,
|
|
6
|
+
isActive: row.is_active,
|
|
7
|
+
createdAt: row.created_at,
|
|
8
|
+
updatedAt: row.updated_at
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
async function getProfile(profileId) {
|
|
12
|
+
const result = await getDb().query(
|
|
13
|
+
`
|
|
14
|
+
select id, name, is_active, created_at, updated_at
|
|
15
|
+
from profiles
|
|
16
|
+
where id = $1
|
|
17
|
+
`,
|
|
18
|
+
[profileId]
|
|
19
|
+
);
|
|
20
|
+
const row = result.rows[0];
|
|
21
|
+
return row ? mapProfileRow(row) : null;
|
|
22
|
+
}
|
|
23
|
+
async function upsertProfile(input) {
|
|
24
|
+
const result = await getDb().query(
|
|
25
|
+
`
|
|
26
|
+
insert into profiles (id, name, is_active)
|
|
27
|
+
values ($1, $2, $3)
|
|
28
|
+
on conflict (id) do update
|
|
29
|
+
set
|
|
30
|
+
name = excluded.name,
|
|
31
|
+
is_active = excluded.is_active,
|
|
32
|
+
updated_at = now()
|
|
33
|
+
returning id, name, is_active, created_at, updated_at
|
|
34
|
+
`,
|
|
35
|
+
[input.id, input.name, input.isActive]
|
|
36
|
+
);
|
|
37
|
+
return mapProfileRow(result.rows[0]);
|
|
38
|
+
}
|
|
39
|
+
async function listProfiles() {
|
|
40
|
+
const result = await getDb().query(
|
|
41
|
+
`
|
|
42
|
+
select id, name, is_active, created_at, updated_at
|
|
43
|
+
from profiles
|
|
44
|
+
order by id asc
|
|
45
|
+
`
|
|
46
|
+
);
|
|
47
|
+
return result.rows.map(mapProfileRow);
|
|
48
|
+
}
|
|
49
|
+
async function deleteProfile(profileId) {
|
|
50
|
+
const result = await getDb().query(
|
|
51
|
+
`
|
|
52
|
+
delete from profiles
|
|
53
|
+
where id = $1
|
|
54
|
+
returning id, name, is_active, created_at, updated_at
|
|
55
|
+
`,
|
|
56
|
+
[profileId]
|
|
57
|
+
);
|
|
58
|
+
const row = result.rows[0];
|
|
59
|
+
if (!row) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
id: row.id,
|
|
64
|
+
name: row.name,
|
|
65
|
+
isActive: row.is_active,
|
|
66
|
+
deletedAt: /* @__PURE__ */ new Date()
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
async function assertActiveProfile(profileId) {
|
|
70
|
+
const profile = await getProfile(profileId);
|
|
71
|
+
if (!profile) {
|
|
72
|
+
throw new Error(`Profile not found: "${profileId}"`);
|
|
73
|
+
}
|
|
74
|
+
if (!profile.isActive) {
|
|
75
|
+
throw new Error(`Profile "${profileId}" is disabled`);
|
|
76
|
+
}
|
|
77
|
+
return profile;
|
|
78
|
+
}
|
|
79
|
+
export {
|
|
80
|
+
assertActiveProfile,
|
|
81
|
+
deleteProfile,
|
|
82
|
+
getProfile,
|
|
83
|
+
listProfiles,
|
|
84
|
+
upsertProfile
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=profile-store.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/config/profile-store.ts"],
|
|
4
|
+
"sourcesContent": ["import { getDb } from \"../db/client.js\";\n\nexport interface ProfileRecord {\n id: string;\n name: string;\n isActive: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface DeletedProfileRecord {\n id: string;\n name: string;\n isActive: boolean;\n deletedAt: Date;\n}\n\ninterface ProfileRow {\n id: string;\n name: string;\n is_active: boolean;\n created_at: Date;\n updated_at: Date;\n}\n\nfunction mapProfileRow(row: ProfileRow): ProfileRecord {\n return {\n id: row.id,\n name: row.name,\n isActive: row.is_active,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nexport async function getProfile(profileId: string): Promise<ProfileRecord | null> {\n const result = await getDb().query<ProfileRow>(\n `\n select id, name, is_active, created_at, updated_at\n from profiles\n where id = $1\n `,\n [profileId]\n );\n\n const row = result.rows[0];\n return row ? mapProfileRow(row) : null;\n}\n\nexport async function upsertProfile(input: {\n id: string;\n name: string;\n isActive: boolean;\n}): Promise<ProfileRecord> {\n const result = await getDb().query<ProfileRow>(\n `\n insert into profiles (id, name, is_active)\n values ($1, $2, $3)\n on conflict (id) do update\n set\n name = excluded.name,\n is_active = excluded.is_active,\n updated_at = now()\n returning id, name, is_active, created_at, updated_at\n `,\n [input.id, input.name, input.isActive]\n );\n\n return mapProfileRow(result.rows[0]);\n}\n\nexport async function listProfiles(): Promise<ProfileRecord[]> {\n const result = await getDb().query<ProfileRow>(\n `\n select id, name, is_active, created_at, updated_at\n from profiles\n order by id asc\n `\n );\n\n return result.rows.map(mapProfileRow);\n}\n\nexport async function deleteProfile(profileId: string): Promise<DeletedProfileRecord | null> {\n const result = await getDb().query<ProfileRow>(\n `\n delete from profiles\n where id = $1\n returning id, name, is_active, created_at, updated_at\n `,\n [profileId]\n );\n\n const row = result.rows[0];\n if (!row) {\n return null;\n }\n\n return {\n id: row.id,\n name: row.name,\n isActive: row.is_active,\n deletedAt: new Date(),\n };\n}\n\nexport async function assertActiveProfile(profileId: string): Promise<ProfileRecord> {\n const profile = await getProfile(profileId);\n\n if (!profile) {\n throw new Error(`Profile not found: \"${profileId}\"`);\n }\n\n if (!profile.isActive) {\n throw new Error(`Profile \"${profileId}\" is disabled`);\n }\n\n return profile;\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,aAAa;AAyBtB,SAAS,cAAc,KAAgC;AACrD,SAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,MAAM,IAAI;AAAA,IACV,UAAU,IAAI;AAAA,IACd,WAAW,IAAI;AAAA,IACf,WAAW,IAAI;AAAA,EACjB;AACF;AAEA,eAAsB,WAAW,WAAkD;AACjF,QAAM,SAAS,MAAM,MAAM,EAAE;AAAA,IAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,MAAM,OAAO,KAAK,CAAC;AACzB,SAAO,MAAM,cAAc,GAAG,IAAI;AACpC;AAEA,eAAsB,cAAc,OAIT;AACzB,QAAM,SAAS,MAAM,MAAM,EAAE;AAAA,IAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,CAAC,MAAM,IAAI,MAAM,MAAM,MAAM,QAAQ;AAAA,EACvC;AAEA,SAAO,cAAc,OAAO,KAAK,CAAC,CAAC;AACrC;AAEA,eAAsB,eAAyC;AAC7D,QAAM,SAAS,MAAM,MAAM,EAAE;AAAA,IAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,EAKF;AAEA,SAAO,OAAO,KAAK,IAAI,aAAa;AACtC;AAEA,eAAsB,cAAc,WAAyD;AAC3F,QAAM,SAAS,MAAM,MAAM,EAAE;AAAA,IAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,MAAM,OAAO,KAAK,CAAC;AACzB,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,MAAM,IAAI;AAAA,IACV,UAAU,IAAI;AAAA,IACd,WAAW,oBAAI,KAAK;AAAA,EACtB;AACF;AAEA,eAAsB,oBAAoB,WAA2C;AACnF,QAAM,UAAU,MAAM,WAAW,SAAS;AAE1C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,uBAAuB,SAAS,GAAG;AAAA,EACrD;AAEA,MAAI,CAAC,QAAQ,UAAU;AACrB,UAAM,IAAI,MAAM,YAAY,SAAS,eAAe;AAAA,EACtD;AAEA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|