@xylex-group/athena 3.0.0 → 3.0.3
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 +24 -10
- package/dist/{athena-auth-url-oLux_57a.d.cts → athena-request-headers-C7Jy-c_D.d.ts} +85 -1
- package/dist/{athena-auth-url-oLux_57a.d.ts → athena-request-headers-DujFFyMU.d.cts} +85 -1
- package/dist/billing.cjs +133 -21
- package/dist/billing.cjs.map +1 -1
- package/dist/billing.d.cts +41 -1
- package/dist/billing.d.ts +41 -1
- package/dist/billing.js +133 -21
- package/dist/billing.js.map +1 -1
- package/dist/browser.cjs +138 -45
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +9 -9
- package/dist/browser.d.ts +9 -9
- package/dist/browser.js +138 -45
- package/dist/browser.js.map +1 -1
- package/dist/cli/index.cjs +1038 -57
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +3 -3
- package/dist/cli/index.d.ts +3 -3
- package/dist/cli/index.js +1039 -58
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +977 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -9
- package/dist/index.d.ts +9 -9
- package/dist/index.js +978 -55
- package/dist/index.js.map +1 -1
- package/dist/{model-form-BKetpu6Q.d.ts → model-form-Dh0sisdL.d.ts} +1 -1
- package/dist/{model-form-BEfCGB5b.d.cts → model-form-oOAJUVd4.d.cts} +1 -1
- package/dist/{module-Bef_MAPO.d.ts → module-BruTcxe0.d.ts} +17 -5
- package/dist/{module-CrrSmpML.d.cts → module-CPG3ULxQ.d.cts} +17 -5
- package/dist/{module-8dSMcy0K.d.cts → module-C_ab-MM1.d.cts} +46 -12
- package/dist/{module-8dSMcy0K.d.ts → module-C_ab-MM1.d.ts} +46 -12
- package/dist/next/client.cjs +9817 -3
- package/dist/next/client.cjs.map +1 -1
- package/dist/next/client.d.cts +26 -1
- package/dist/next/client.d.ts +26 -1
- package/dist/next/client.js +9788 -4
- package/dist/next/client.js.map +1 -1
- package/dist/next/server.cjs +10398 -42
- package/dist/next/server.cjs.map +1 -1
- package/dist/next/server.d.cts +39 -4
- package/dist/next/server.d.ts +39 -4
- package/dist/next/server.js +10339 -43
- package/dist/next/server.js.map +1 -1
- package/dist/{pipeline-Dfsed4VD.d.cts → pipeline-CIzV9f7b.d.cts} +1 -1
- package/dist/{pipeline-BXFQbsUW.d.ts → pipeline-DNlc8Ayn.d.ts} +1 -1
- package/dist/proxy-request-headers-DGxdoyA0.d.cts +59 -0
- package/dist/proxy-request-headers-m4D2Tduy.d.ts +59 -0
- package/dist/react.cjs +7 -7
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +4 -4
- package/dist/react.d.ts +4 -4
- package/dist/react.js +7 -7
- package/dist/react.js.map +1 -1
- package/dist/social-providers.cjs +15 -11
- package/dist/social-providers.cjs.map +1 -1
- package/dist/social-providers.d.cts +17 -57
- package/dist/social-providers.d.ts +17 -57
- package/dist/social-providers.js +15 -11
- package/dist/social-providers.js.map +1 -1
- package/dist/{types-jClgDy1J.d.ts → types-B75PdABb.d.ts} +1 -1
- package/dist/{types-kO_Ut5wU.d.cts → types-CgCv5o6R.d.cts} +1 -1
- package/dist/{types-CK7cBQbC.d.ts → types-D6tZ9aoq.d.ts} +35 -2
- package/dist/{types-Z3-rsiM3.d.cts → types-DFr2cL1N.d.cts} +35 -2
- package/dist/utils.d.cts +4 -142
- package/dist/utils.d.ts +4 -142
- package/dist/{v3-client-G8JMOilK.d.cts → v3-client-CWfZHcKL.d.cts} +37 -21
- package/dist/{v3-client-CuCNy-JJ.d.ts → v3-client-DZp2NEhK.d.ts} +37 -21
- package/package.json +6 -3
package/dist/index.cjs
CHANGED
|
@@ -1941,7 +1941,7 @@ function buildRpcDebugSql(payload) {
|
|
|
1941
1941
|
}
|
|
1942
1942
|
|
|
1943
1943
|
// src/gateway/url.ts
|
|
1944
|
-
var ATHENA_DEFAULT_BASE_URL = "https://athena-
|
|
1944
|
+
var ATHENA_DEFAULT_BASE_URL = "https://mirror2.athena-cluster.com";
|
|
1945
1945
|
function describeReceivedValue(value) {
|
|
1946
1946
|
if (value === void 0) return "undefined";
|
|
1947
1947
|
if (value === null) return "null";
|
|
@@ -1964,14 +1964,14 @@ function normalizeAthenaGatewayBaseUrl(input, options = {}) {
|
|
|
1964
1964
|
if (candidate === void 0 || candidate === null) {
|
|
1965
1965
|
throw invalidBaseUrlError(
|
|
1966
1966
|
`${label} must be a non-empty absolute http(s) URL. Received ${describeReceivedValue(input)}.`,
|
|
1967
|
-
'Set ATHENA_URL in the explicit env object (or pass createClient({ url, key })) to a full URL such as "https://
|
|
1967
|
+
'Set ATHENA_URL in the explicit env object (or pass createClient({ url, key })) to a full URL such as "https://mirror2.athena-cluster.com".'
|
|
1968
1968
|
);
|
|
1969
1969
|
}
|
|
1970
1970
|
const trimmed = candidate.trim();
|
|
1971
1971
|
if (!trimmed) {
|
|
1972
1972
|
throw invalidBaseUrlError(
|
|
1973
1973
|
`${label} must be a non-empty absolute http(s) URL. Received ${describeReceivedValue(candidate)}.`,
|
|
1974
|
-
'Set ATHENA_URL in the explicit env object (or pass createClient({ url, key })) to a full URL such as "https://
|
|
1974
|
+
'Set ATHENA_URL in the explicit env object (or pass createClient({ url, key })) to a full URL such as "https://mirror2.athena-cluster.com".'
|
|
1975
1975
|
);
|
|
1976
1976
|
}
|
|
1977
1977
|
let parsed;
|
|
@@ -1980,13 +1980,13 @@ function normalizeAthenaGatewayBaseUrl(input, options = {}) {
|
|
|
1980
1980
|
} catch {
|
|
1981
1981
|
throw invalidBaseUrlError(
|
|
1982
1982
|
`${label} must be a valid absolute http(s) URL. Received ${describeReceivedValue(candidate)}.`,
|
|
1983
|
-
'Use a full URL including the protocol, for example "https://
|
|
1983
|
+
'Use a full URL including the protocol, for example "https://mirror2.athena-cluster.com".'
|
|
1984
1984
|
);
|
|
1985
1985
|
}
|
|
1986
1986
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
1987
1987
|
throw invalidBaseUrlError(
|
|
1988
1988
|
`${label} must use http or https. Received ${JSON.stringify(trimmed)}.`,
|
|
1989
|
-
'Use an Athena gateway URL such as "https://
|
|
1989
|
+
'Use an Athena gateway URL such as "https://mirror2.athena-cluster.com".'
|
|
1990
1990
|
);
|
|
1991
1991
|
}
|
|
1992
1992
|
if (parsed.search || parsed.hash) {
|
|
@@ -2009,7 +2009,7 @@ function buildAthenaGatewayUrl(baseUrl, path) {
|
|
|
2009
2009
|
|
|
2010
2010
|
// package.json
|
|
2011
2011
|
var package_default = {
|
|
2012
|
-
version: "3.0.
|
|
2012
|
+
version: "3.0.3"
|
|
2013
2013
|
};
|
|
2014
2014
|
|
|
2015
2015
|
// src/sdk-version.ts
|
|
@@ -3057,7 +3057,7 @@ function createAthenaRequest(config, resolveContext) {
|
|
|
3057
3057
|
}
|
|
3058
3058
|
|
|
3059
3059
|
// src/gateway/client.ts
|
|
3060
|
-
var DEFAULT_CLIENT = "
|
|
3060
|
+
var DEFAULT_CLIENT = "DEFAULT_CLIENT";
|
|
3061
3061
|
var SDK_NAME2 = "xylex-group/athena";
|
|
3062
3062
|
var SDK_HEADER_VALUE = buildSdkHeaderValue(SDK_NAME2);
|
|
3063
3063
|
function parseResponseBody(rawText, contentType) {
|
|
@@ -9886,6 +9886,8 @@ var billingSdkManifest = {
|
|
|
9886
9886
|
methods: [
|
|
9887
9887
|
{ name: "getCapabilities", method: "GET", path: "/billing/v1/capabilities" },
|
|
9888
9888
|
{ name: "createCheckout", method: "POST", path: "/billing/v1/checkouts" },
|
|
9889
|
+
{ name: "listProducts", method: "GET", path: "/billing/v1/products" },
|
|
9890
|
+
{ name: "listPrices", method: "GET", path: "/billing/v1/prices" },
|
|
9889
9891
|
{ name: "listCustomers", method: "GET", path: "/billing/v1/customers" },
|
|
9890
9892
|
{ name: "createCustomer", method: "POST", path: "/billing/v1/customers" },
|
|
9891
9893
|
{ name: "getCustomer", method: "GET", path: "/billing/v1/customers/{id}" },
|
|
@@ -9911,6 +9913,12 @@ var billingSdkManifest = {
|
|
|
9911
9913
|
{ name: "cancelSubscription", method: "POST", path: "/billing/v1/subscriptions/{id}/cancel" },
|
|
9912
9914
|
{ name: "listInvoices", method: "GET", path: "/billing/v1/invoices" },
|
|
9913
9915
|
{ name: "getInvoice", method: "GET", path: "/billing/v1/invoices/{id}" },
|
|
9916
|
+
{ name: "listWebhooks", method: "GET", path: "/billing/v1/webhooks" },
|
|
9917
|
+
{ name: "createWebhook", method: "POST", path: "/billing/v1/webhooks" },
|
|
9918
|
+
{ name: "getWebhook", method: "GET", path: "/billing/v1/webhooks/{id}" },
|
|
9919
|
+
{ name: "updateWebhook", method: "PATCH", path: "/billing/v1/webhooks/{id}" },
|
|
9920
|
+
{ name: "deleteWebhook", method: "DELETE", path: "/billing/v1/webhooks/{id}" },
|
|
9921
|
+
{ name: "testWebhook", method: "POST", path: "/billing/v1/webhooks/{id}/test" },
|
|
9914
9922
|
{
|
|
9915
9923
|
name: "listConnections",
|
|
9916
9924
|
method: "GET",
|
|
@@ -10079,6 +10087,25 @@ function createBillingModule(config) {
|
|
|
10079
10087
|
createCheckout(body, options) {
|
|
10080
10088
|
return call("POST", "/billing/v1/checkouts", body, options);
|
|
10081
10089
|
},
|
|
10090
|
+
listProducts(input, options) {
|
|
10091
|
+
return call(
|
|
10092
|
+
"GET",
|
|
10093
|
+
appendQuery3("/billing/v1/products", connectionQuery(input)),
|
|
10094
|
+
void 0,
|
|
10095
|
+
options
|
|
10096
|
+
);
|
|
10097
|
+
},
|
|
10098
|
+
listPrices(input, options) {
|
|
10099
|
+
return call(
|
|
10100
|
+
"GET",
|
|
10101
|
+
appendQuery3("/billing/v1/prices", {
|
|
10102
|
+
...connectionQuery(input),
|
|
10103
|
+
...input.productId ? { productId: input.productId } : {}
|
|
10104
|
+
}),
|
|
10105
|
+
void 0,
|
|
10106
|
+
options
|
|
10107
|
+
);
|
|
10108
|
+
},
|
|
10082
10109
|
listCustomers(input, options) {
|
|
10083
10110
|
return call(
|
|
10084
10111
|
"GET",
|
|
@@ -10225,10 +10252,7 @@ function createBillingModule(config) {
|
|
|
10225
10252
|
getRefund(id, input, options) {
|
|
10226
10253
|
return call(
|
|
10227
10254
|
"GET",
|
|
10228
|
-
appendQuery3(withPathParam2("/billing/v1/refunds/{id}", "id", id),
|
|
10229
|
-
...connectionQuery(input),
|
|
10230
|
-
...input.paymentId ? { paymentId: input.paymentId } : {}
|
|
10231
|
-
}),
|
|
10255
|
+
appendQuery3(withPathParam2("/billing/v1/refunds/{id}", "id", id), connectionQuery(input)),
|
|
10232
10256
|
void 0,
|
|
10233
10257
|
options
|
|
10234
10258
|
);
|
|
@@ -10236,10 +10260,7 @@ function createBillingModule(config) {
|
|
|
10236
10260
|
cancelRefund(id, input, options) {
|
|
10237
10261
|
return call(
|
|
10238
10262
|
"POST",
|
|
10239
|
-
appendQuery3(withPathParam2("/billing/v1/refunds/{id}/cancel", "id", id),
|
|
10240
|
-
...connectionQuery(input),
|
|
10241
|
-
...input.paymentId ? { paymentId: input.paymentId } : {}
|
|
10242
|
-
}),
|
|
10263
|
+
appendQuery3(withPathParam2("/billing/v1/refunds/{id}/cancel", "id", id), connectionQuery(input)),
|
|
10243
10264
|
{},
|
|
10244
10265
|
options
|
|
10245
10266
|
);
|
|
@@ -10258,10 +10279,10 @@ function createBillingModule(config) {
|
|
|
10258
10279
|
getSubscription(id, input, options) {
|
|
10259
10280
|
return call(
|
|
10260
10281
|
"GET",
|
|
10261
|
-
appendQuery3(
|
|
10262
|
-
|
|
10263
|
-
|
|
10264
|
-
|
|
10282
|
+
appendQuery3(
|
|
10283
|
+
withPathParam2("/billing/v1/subscriptions/{id}", "id", id),
|
|
10284
|
+
connectionQuery(input)
|
|
10285
|
+
),
|
|
10265
10286
|
void 0,
|
|
10266
10287
|
options
|
|
10267
10288
|
);
|
|
@@ -10277,10 +10298,10 @@ function createBillingModule(config) {
|
|
|
10277
10298
|
cancelSubscription(id, input, options) {
|
|
10278
10299
|
return call(
|
|
10279
10300
|
"POST",
|
|
10280
|
-
appendQuery3(
|
|
10281
|
-
|
|
10282
|
-
|
|
10283
|
-
|
|
10301
|
+
appendQuery3(
|
|
10302
|
+
withPathParam2("/billing/v1/subscriptions/{id}/cancel", "id", id),
|
|
10303
|
+
connectionQuery(input)
|
|
10304
|
+
),
|
|
10284
10305
|
{},
|
|
10285
10306
|
options
|
|
10286
10307
|
);
|
|
@@ -10304,6 +10325,57 @@ function createBillingModule(config) {
|
|
|
10304
10325
|
options
|
|
10305
10326
|
);
|
|
10306
10327
|
},
|
|
10328
|
+
listWebhooks(input, options) {
|
|
10329
|
+
return call(
|
|
10330
|
+
"GET",
|
|
10331
|
+
appendQuery3("/billing/v1/webhooks", connectionQuery(input)),
|
|
10332
|
+
void 0,
|
|
10333
|
+
options
|
|
10334
|
+
);
|
|
10335
|
+
},
|
|
10336
|
+
createWebhook(input, body, options) {
|
|
10337
|
+
return call(
|
|
10338
|
+
"POST",
|
|
10339
|
+
appendQuery3("/billing/v1/webhooks", connectionQuery(input)),
|
|
10340
|
+
body,
|
|
10341
|
+
options
|
|
10342
|
+
);
|
|
10343
|
+
},
|
|
10344
|
+
getWebhook(id, input, options) {
|
|
10345
|
+
return call(
|
|
10346
|
+
"GET",
|
|
10347
|
+
appendQuery3(withPathParam2("/billing/v1/webhooks/{id}", "id", id), connectionQuery(input)),
|
|
10348
|
+
void 0,
|
|
10349
|
+
options
|
|
10350
|
+
);
|
|
10351
|
+
},
|
|
10352
|
+
updateWebhook(id, input, body, options) {
|
|
10353
|
+
return call(
|
|
10354
|
+
"PATCH",
|
|
10355
|
+
appendQuery3(withPathParam2("/billing/v1/webhooks/{id}", "id", id), connectionQuery(input)),
|
|
10356
|
+
body,
|
|
10357
|
+
options
|
|
10358
|
+
);
|
|
10359
|
+
},
|
|
10360
|
+
deleteWebhook(id, input, options) {
|
|
10361
|
+
return call(
|
|
10362
|
+
"DELETE",
|
|
10363
|
+
appendQuery3(withPathParam2("/billing/v1/webhooks/{id}", "id", id), connectionQuery(input)),
|
|
10364
|
+
void 0,
|
|
10365
|
+
options
|
|
10366
|
+
);
|
|
10367
|
+
},
|
|
10368
|
+
testWebhook(id, input, options) {
|
|
10369
|
+
return call(
|
|
10370
|
+
"POST",
|
|
10371
|
+
appendQuery3(
|
|
10372
|
+
withPathParam2("/billing/v1/webhooks/{id}/test", "id", id),
|
|
10373
|
+
connectionQuery(input)
|
|
10374
|
+
),
|
|
10375
|
+
{},
|
|
10376
|
+
options
|
|
10377
|
+
);
|
|
10378
|
+
},
|
|
10307
10379
|
listConnections(clientName, options) {
|
|
10308
10380
|
return call(
|
|
10309
10381
|
"GET",
|
|
@@ -10481,6 +10553,31 @@ function createBillingModule(config) {
|
|
|
10481
10553
|
};
|
|
10482
10554
|
}
|
|
10483
10555
|
|
|
10556
|
+
// src/config/errors.ts
|
|
10557
|
+
var AthenaConfigurationError = class extends Error {
|
|
10558
|
+
code;
|
|
10559
|
+
service;
|
|
10560
|
+
constructor(code, message, service) {
|
|
10561
|
+
super(message);
|
|
10562
|
+
this.name = "AthenaConfigurationError";
|
|
10563
|
+
this.code = code;
|
|
10564
|
+
this.service = service;
|
|
10565
|
+
}
|
|
10566
|
+
};
|
|
10567
|
+
|
|
10568
|
+
// src/context/merge.ts
|
|
10569
|
+
function mergeAthenaRequestContexts(base, override) {
|
|
10570
|
+
if (!base && !override) return void 0;
|
|
10571
|
+
return {
|
|
10572
|
+
...base,
|
|
10573
|
+
...override,
|
|
10574
|
+
headers: base?.headers || override?.headers ? {
|
|
10575
|
+
...base?.headers ?? {},
|
|
10576
|
+
...override?.headers ?? {}
|
|
10577
|
+
} : void 0
|
|
10578
|
+
};
|
|
10579
|
+
}
|
|
10580
|
+
|
|
10484
10581
|
// src/v3-client.ts
|
|
10485
10582
|
var ENV_URL_KEYS = ["ATHENA_URL", "NEXT_PUBLIC_ATHENA_URL"];
|
|
10486
10583
|
var ENV_DB_URL_KEYS = ["ATHENA_DB_URL", "ATHENA_GATEWAY_URL", "NEXT_PUBLIC_ATHENA_DB_API_URL"];
|
|
@@ -10491,15 +10588,6 @@ var ENV_STORAGE_URL_KEYS = ["ATHENA_STORAGE_URL", "NEXT_PUBLIC_ATHENA_STORAGE_UR
|
|
|
10491
10588
|
var ENV_KEY_KEYS = ["ATHENA_API_KEY", "NEXT_PUBLIC_ATHENA_API_KEY", "ATHENA_GATEWAY_API_KEY", "X_API_KEY"];
|
|
10492
10589
|
var ENV_CLIENT_KEYS = ["ATHENA_CLIENT", "NEXT_PUBLIC_ATHENA_CLIENT"];
|
|
10493
10590
|
var MISSING_DB_SENTINEL = "https://athena.invalid/db";
|
|
10494
|
-
var AthenaConfigurationError = class extends Error {
|
|
10495
|
-
code = "ATHENA_SERVICE_NOT_CONFIGURED";
|
|
10496
|
-
service;
|
|
10497
|
-
constructor(service, message = `Athena ${service} is not configured.`) {
|
|
10498
|
-
super(message);
|
|
10499
|
-
this.name = "AthenaConfigurationError";
|
|
10500
|
-
this.service = service;
|
|
10501
|
-
}
|
|
10502
|
-
};
|
|
10503
10591
|
function readFirstEnv(env, keys) {
|
|
10504
10592
|
for (const key of keys) {
|
|
10505
10593
|
const value = env?.[key]?.trim();
|
|
@@ -10540,11 +10628,18 @@ function resolveCore(config) {
|
|
|
10540
10628
|
chatWs: normalizeOptional(config.chat?.wsUrl) ?? (explicitRootWinsOverEnvServices && root ? toWebSocketUrl(root) : void 0) ?? readFirstEnv(env, ENV_CHAT_WS_URL_KEYS) ?? (root ? toWebSocketUrl(root) : void 0)
|
|
10541
10629
|
};
|
|
10542
10630
|
if (!urls.db && !urls.auth && !urls.chat && !urls.storage && !urls.billing) {
|
|
10543
|
-
throw new AthenaConfigurationError(
|
|
10631
|
+
throw new AthenaConfigurationError(
|
|
10632
|
+
"ATHENA_NO_SERVICE_CONFIGURED",
|
|
10633
|
+
"Athena requires a unified URL or at least one configured service URL.",
|
|
10634
|
+
"db"
|
|
10635
|
+
);
|
|
10544
10636
|
}
|
|
10545
10637
|
const key = normalizeOptional(config.key) ?? readFirstEnv(env, ENV_KEY_KEYS);
|
|
10546
10638
|
if (!key) {
|
|
10547
|
-
throw new
|
|
10639
|
+
throw new AthenaConfigurationError(
|
|
10640
|
+
"ATHENA_API_KEY_REQUIRED",
|
|
10641
|
+
"Athena API key is required. Pass key or provide it through the explicit env object."
|
|
10642
|
+
);
|
|
10548
10643
|
}
|
|
10549
10644
|
const base = {
|
|
10550
10645
|
config,
|
|
@@ -10557,18 +10652,10 @@ function resolveCore(config) {
|
|
|
10557
10652
|
internalCore: createInternalClientCore(createInternalConfig(base))
|
|
10558
10653
|
};
|
|
10559
10654
|
}
|
|
10560
|
-
function mergeContexts(base, override) {
|
|
10561
|
-
if (!base && !override) return void 0;
|
|
10562
|
-
return {
|
|
10563
|
-
...base,
|
|
10564
|
-
...override,
|
|
10565
|
-
headers: base?.headers || override?.headers ? { ...base?.headers ?? {}, ...override?.headers ?? {} } : void 0
|
|
10566
|
-
};
|
|
10567
|
-
}
|
|
10568
10655
|
async function resolveConfiguredContext(core, viewContext) {
|
|
10569
10656
|
const configured = core.config.context;
|
|
10570
10657
|
const base = typeof configured === "function" ? await configured() : configured;
|
|
10571
|
-
return
|
|
10658
|
+
return mergeAthenaRequestContexts(base, viewContext);
|
|
10572
10659
|
}
|
|
10573
10660
|
function createInternalConfig(core) {
|
|
10574
10661
|
const { config, urls } = core;
|
|
@@ -10601,7 +10688,13 @@ function createInternalConfig(core) {
|
|
|
10601
10688
|
};
|
|
10602
10689
|
}
|
|
10603
10690
|
function serviceGuard(urls, service) {
|
|
10604
|
-
if (!urls[service])
|
|
10691
|
+
if (!urls[service]) {
|
|
10692
|
+
throw new AthenaConfigurationError(
|
|
10693
|
+
"ATHENA_SERVICE_NOT_CONFIGURED",
|
|
10694
|
+
`Athena ${service} is not configured.`,
|
|
10695
|
+
service
|
|
10696
|
+
);
|
|
10697
|
+
}
|
|
10605
10698
|
}
|
|
10606
10699
|
function createUnavailableNamespace(service, urls, path = []) {
|
|
10607
10700
|
return new Proxy(() => void 0, {
|
|
@@ -10660,7 +10753,7 @@ function createClientView(core, viewContext) {
|
|
|
10660
10753
|
return resolved.verifyConnection(options);
|
|
10661
10754
|
},
|
|
10662
10755
|
withContext(context) {
|
|
10663
|
-
return createClientView(core,
|
|
10756
|
+
return createClientView(core, mergeAthenaRequestContexts(viewContext, context));
|
|
10664
10757
|
}
|
|
10665
10758
|
};
|
|
10666
10759
|
return Object.freeze(client);
|
|
@@ -11626,6 +11719,12 @@ var ATHENA_DIRECT_TARGETS = {
|
|
|
11626
11719
|
};
|
|
11627
11720
|
var DEFAULT_OUTPUT_FORMAT = "table-builder";
|
|
11628
11721
|
var DEFAULT_OUTPUT_PRESET = "athena-direct";
|
|
11722
|
+
var DEFAULT_ARTIFACT_WRITE_POLICY = "merge";
|
|
11723
|
+
var ARTIFACT_WRITE_POLICIES = /* @__PURE__ */ new Set([
|
|
11724
|
+
"merge",
|
|
11725
|
+
"skip",
|
|
11726
|
+
"overwrite"
|
|
11727
|
+
]);
|
|
11629
11728
|
var DEFAULT_NAMING = {
|
|
11630
11729
|
modelType: "pascal",
|
|
11631
11730
|
modelConst: "camel",
|
|
@@ -11905,6 +12004,23 @@ function normalizeFilterConfig(input) {
|
|
|
11905
12004
|
excludeTables: normalizeTableSelection(input?.excludeTables)
|
|
11906
12005
|
};
|
|
11907
12006
|
}
|
|
12007
|
+
function normalizeArtifactWritePolicy(value, fieldName) {
|
|
12008
|
+
if (value === void 0 || value === null || value === "") {
|
|
12009
|
+
return DEFAULT_ARTIFACT_WRITE_POLICY;
|
|
12010
|
+
}
|
|
12011
|
+
if (typeof value === "string" && ARTIFACT_WRITE_POLICIES.has(value)) {
|
|
12012
|
+
return value;
|
|
12013
|
+
}
|
|
12014
|
+
throw new Error(
|
|
12015
|
+
`Invalid output.artifactWrite.${fieldName}: expected one of merge | skip | overwrite, received ${JSON.stringify(value)}.`
|
|
12016
|
+
);
|
|
12017
|
+
}
|
|
12018
|
+
function normalizeArtifactWriteConfig(input) {
|
|
12019
|
+
return {
|
|
12020
|
+
database: normalizeArtifactWritePolicy(input?.database, "database"),
|
|
12021
|
+
registry: normalizeArtifactWritePolicy(input?.registry, "registry")
|
|
12022
|
+
};
|
|
12023
|
+
}
|
|
11908
12024
|
function normalizeOutputConfig(output) {
|
|
11909
12025
|
const preset = output?.preset ?? DEFAULT_OUTPUT_PRESET;
|
|
11910
12026
|
return {
|
|
@@ -11916,7 +12032,8 @@ function normalizeOutputConfig(output) {
|
|
|
11916
12032
|
},
|
|
11917
12033
|
placeholderMap: {
|
|
11918
12034
|
...output?.placeholderMap ?? {}
|
|
11919
|
-
}
|
|
12035
|
+
},
|
|
12036
|
+
artifactWrite: normalizeArtifactWriteConfig(output?.artifactWrite)
|
|
11920
12037
|
};
|
|
11921
12038
|
}
|
|
11922
12039
|
function normalizeProviderConfig(provider) {
|
|
@@ -13177,9 +13294,764 @@ function resolveGeneratorProvider(providerConfig, experimentalFlags) {
|
|
|
13177
13294
|
}
|
|
13178
13295
|
throw new Error(`Unsupported generator provider kind: ${providerConfig.kind ?? "unknown"}`);
|
|
13179
13296
|
}
|
|
13180
|
-
|
|
13181
|
-
|
|
13297
|
+
|
|
13298
|
+
// src/generator/artifact-merge.ts
|
|
13299
|
+
var IMPORT_RE = /^import\s+(?:type\s+)?(?:\{([^}]*)\}|([A-Za-z_$][\w$]*))\s+from\s+(['"])([^'"]+)\3\s*;?\s*$/gm;
|
|
13300
|
+
var DEFINE_EXPORT_RE = /export\s+const\s+([A-Za-z_$][\w$]*)\s*=\s*(define(?:Database|Registry))\s*\(\s*\{/g;
|
|
13301
|
+
var META_EXPORT_RE = /export\s+const\s+__athena_schema_meta\s*=\s*\{/g;
|
|
13302
|
+
var KNOWN_META_KEYS = /* @__PURE__ */ new Set([
|
|
13303
|
+
"schemaVersion",
|
|
13304
|
+
"generatedAt",
|
|
13305
|
+
"database",
|
|
13306
|
+
"outputPreset",
|
|
13307
|
+
"outputFormat"
|
|
13308
|
+
]);
|
|
13309
|
+
function detectNewline(source) {
|
|
13310
|
+
return source.includes("\r\n") ? "\r\n" : "\n";
|
|
13311
|
+
}
|
|
13312
|
+
function detectStyle(source) {
|
|
13313
|
+
const newline = detectNewline(source);
|
|
13314
|
+
const single = (source.match(/'/g) ?? []).length;
|
|
13315
|
+
const double = (source.match(/"/g) ?? []).length;
|
|
13316
|
+
const quote = double > single ? '"' : "'";
|
|
13317
|
+
const importLines = source.split(/\r?\n/).filter((line) => line.trimStart().startsWith("import "));
|
|
13318
|
+
const semicolons = importLines.length > 0 ? importLines.filter((line) => line.trimEnd().endsWith(";")).length >= importLines.length / 2 : false;
|
|
13319
|
+
const objectLines = source.split(/\r?\n/).map((line) => line.trim()).filter((line) => /^[A-Za-z0-9_'"]+\s*:\s*.+/.test(line));
|
|
13320
|
+
const trailingComma = objectLines.length > 0 ? objectLines.filter((line) => line.endsWith(",")).length >= Math.ceil(objectLines.length / 2) : true;
|
|
13321
|
+
const indentMatch = source.match(/\n([ \t]+)\S/);
|
|
13322
|
+
const indent = indentMatch?.[1] ?? " ";
|
|
13323
|
+
return { quote, semicolons, trailingComma, indent, newline };
|
|
13324
|
+
}
|
|
13325
|
+
function quoteString(value, quote) {
|
|
13326
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(new RegExp(quote, "g"), `\\${quote}`);
|
|
13327
|
+
return `${quote}${escaped}${quote}`;
|
|
13328
|
+
}
|
|
13329
|
+
function parseNamedImports(source) {
|
|
13330
|
+
const imports = [];
|
|
13331
|
+
IMPORT_RE.lastIndex = 0;
|
|
13332
|
+
let match;
|
|
13333
|
+
while ((match = IMPORT_RE.exec(source)) !== null) {
|
|
13334
|
+
const named = match[1];
|
|
13335
|
+
const defaultName = match[2];
|
|
13336
|
+
const module = match[4];
|
|
13337
|
+
const names = named ? named.split(",").map((part) => part.trim()).filter(Boolean).map((part) => {
|
|
13338
|
+
const alias = part.split(/\s+as\s+/);
|
|
13339
|
+
return (alias[1] ?? alias[0]).trim();
|
|
13340
|
+
}) : defaultName ? [defaultName] : [];
|
|
13341
|
+
imports.push({
|
|
13342
|
+
names,
|
|
13343
|
+
module,
|
|
13344
|
+
raw: match[0],
|
|
13345
|
+
start: match.index,
|
|
13346
|
+
end: match.index + match[0].length
|
|
13347
|
+
});
|
|
13348
|
+
}
|
|
13349
|
+
return imports;
|
|
13350
|
+
}
|
|
13351
|
+
function findMatchingBrace(source, openIndex) {
|
|
13352
|
+
let depth = 0;
|
|
13353
|
+
let inSingle = false;
|
|
13354
|
+
let inDouble = false;
|
|
13355
|
+
let inTemplate = false;
|
|
13356
|
+
let escaped = false;
|
|
13357
|
+
for (let i = openIndex; i < source.length; i += 1) {
|
|
13358
|
+
const ch = source[i];
|
|
13359
|
+
if (escaped) {
|
|
13360
|
+
escaped = false;
|
|
13361
|
+
continue;
|
|
13362
|
+
}
|
|
13363
|
+
if (ch === "\\" && (inSingle || inDouble || inTemplate)) {
|
|
13364
|
+
escaped = true;
|
|
13365
|
+
continue;
|
|
13366
|
+
}
|
|
13367
|
+
if (!inDouble && !inTemplate && ch === "'") {
|
|
13368
|
+
inSingle = !inSingle;
|
|
13369
|
+
continue;
|
|
13370
|
+
}
|
|
13371
|
+
if (!inSingle && !inTemplate && ch === '"') {
|
|
13372
|
+
inDouble = !inDouble;
|
|
13373
|
+
continue;
|
|
13374
|
+
}
|
|
13375
|
+
if (!inSingle && !inDouble && ch === "`") {
|
|
13376
|
+
inTemplate = !inTemplate;
|
|
13377
|
+
continue;
|
|
13378
|
+
}
|
|
13379
|
+
if (inSingle || inDouble || inTemplate) {
|
|
13380
|
+
continue;
|
|
13381
|
+
}
|
|
13382
|
+
if (ch === "{") {
|
|
13383
|
+
depth += 1;
|
|
13384
|
+
} else if (ch === "}") {
|
|
13385
|
+
depth -= 1;
|
|
13386
|
+
if (depth === 0) {
|
|
13387
|
+
return i;
|
|
13388
|
+
}
|
|
13389
|
+
}
|
|
13390
|
+
}
|
|
13391
|
+
return -1;
|
|
13392
|
+
}
|
|
13393
|
+
function parseObjectEntries(body) {
|
|
13394
|
+
const entries = [];
|
|
13395
|
+
const lines = body.split(/\r?\n/);
|
|
13396
|
+
for (const line of lines) {
|
|
13397
|
+
const trimmed = line.trim();
|
|
13398
|
+
if (!trimmed || trimmed.startsWith("//") || trimmed.startsWith("/*")) {
|
|
13399
|
+
continue;
|
|
13400
|
+
}
|
|
13401
|
+
const withoutComma = trimmed.endsWith(",") ? trimmed.slice(0, -1).trimEnd() : trimmed;
|
|
13402
|
+
const match = withoutComma.match(/^([A-Za-z_$][\w$]*|['"][^'"]+['"])\s*:\s*(.+)$/);
|
|
13403
|
+
if (!match) {
|
|
13404
|
+
continue;
|
|
13405
|
+
}
|
|
13406
|
+
const keyRaw = match[1];
|
|
13407
|
+
const key = keyRaw.startsWith("'") || keyRaw.startsWith('"') ? keyRaw.slice(1, -1) : keyRaw;
|
|
13408
|
+
entries.push({
|
|
13409
|
+
key,
|
|
13410
|
+
value: match[2].trim(),
|
|
13411
|
+
raw: trimmed
|
|
13412
|
+
});
|
|
13413
|
+
}
|
|
13414
|
+
return entries;
|
|
13415
|
+
}
|
|
13416
|
+
function parseDefineBlocks(source) {
|
|
13417
|
+
const blocks = [];
|
|
13418
|
+
DEFINE_EXPORT_RE.lastIndex = 0;
|
|
13419
|
+
let match;
|
|
13420
|
+
while ((match = DEFINE_EXPORT_RE.exec(source)) !== null) {
|
|
13421
|
+
const exportName = match[1];
|
|
13422
|
+
const callName = match[2];
|
|
13423
|
+
const openBrace = match.index + match[0].lastIndexOf("{");
|
|
13424
|
+
const closeBrace = findMatchingBrace(source, openBrace);
|
|
13425
|
+
if (closeBrace < 0) {
|
|
13426
|
+
continue;
|
|
13427
|
+
}
|
|
13428
|
+
const body = source.slice(openBrace + 1, closeBrace);
|
|
13429
|
+
const fullEnd = (() => {
|
|
13430
|
+
let i = closeBrace + 1;
|
|
13431
|
+
while (i < source.length && /\s/.test(source[i])) i += 1;
|
|
13432
|
+
if (source[i] === ")") i += 1;
|
|
13433
|
+
while (i < source.length && /\s/.test(source[i])) i += 1;
|
|
13434
|
+
if (source[i] === ";") i += 1;
|
|
13435
|
+
return i;
|
|
13436
|
+
})();
|
|
13437
|
+
blocks.push({
|
|
13438
|
+
kind: callName === "defineDatabase" ? "database" : "registry",
|
|
13439
|
+
exportName,
|
|
13440
|
+
callName,
|
|
13441
|
+
entries: parseObjectEntries(body),
|
|
13442
|
+
bodyStart: openBrace + 1,
|
|
13443
|
+
bodyEnd: closeBrace,
|
|
13444
|
+
fullStart: match.index,
|
|
13445
|
+
fullEnd,
|
|
13446
|
+
raw: source.slice(match.index, fullEnd)
|
|
13447
|
+
});
|
|
13448
|
+
}
|
|
13449
|
+
return blocks;
|
|
13450
|
+
}
|
|
13451
|
+
function parseMetaBlock(source) {
|
|
13452
|
+
META_EXPORT_RE.lastIndex = 0;
|
|
13453
|
+
const match = META_EXPORT_RE.exec(source);
|
|
13454
|
+
if (!match) {
|
|
13455
|
+
return void 0;
|
|
13456
|
+
}
|
|
13457
|
+
const openBrace = match.index + match[0].lastIndexOf("{");
|
|
13458
|
+
const closeBrace = findMatchingBrace(source, openBrace);
|
|
13459
|
+
if (closeBrace < 0) {
|
|
13460
|
+
return void 0;
|
|
13461
|
+
}
|
|
13462
|
+
let fullEnd = closeBrace + 1;
|
|
13463
|
+
const after = source.slice(fullEnd);
|
|
13464
|
+
const asConst = after.match(/^\s*as\s+const\s*;?/);
|
|
13465
|
+
if (asConst) {
|
|
13466
|
+
fullEnd += asConst[0].length;
|
|
13467
|
+
} else if (source[fullEnd] === ";") {
|
|
13468
|
+
fullEnd += 1;
|
|
13469
|
+
}
|
|
13470
|
+
return {
|
|
13471
|
+
entries: parseObjectEntries(source.slice(openBrace + 1, closeBrace)),
|
|
13472
|
+
bodyStart: openBrace + 1,
|
|
13473
|
+
bodyEnd: closeBrace,
|
|
13474
|
+
fullStart: match.index,
|
|
13475
|
+
fullEnd,
|
|
13476
|
+
raw: source.slice(match.index, fullEnd)
|
|
13477
|
+
};
|
|
13478
|
+
}
|
|
13479
|
+
function hasImportBinding(imports, name, module) {
|
|
13480
|
+
return imports.some(
|
|
13481
|
+
(item) => item.names.includes(name) && (module === void 0)
|
|
13482
|
+
);
|
|
13483
|
+
}
|
|
13484
|
+
function findImportForName(imports, name) {
|
|
13485
|
+
return imports.find((item) => item.names.includes(name));
|
|
13486
|
+
}
|
|
13487
|
+
function normalizeModulePath(modulePath) {
|
|
13488
|
+
return modulePath.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\.ts$/, "");
|
|
13489
|
+
}
|
|
13490
|
+
function formatImport(names, modulePath, style) {
|
|
13491
|
+
const body = `import { ${names.join(", ")} } from ${quoteString(modulePath, style.quote)}`;
|
|
13492
|
+
return style.semicolons ? `${body};` : body;
|
|
13493
|
+
}
|
|
13494
|
+
function formatObjectEntry(key, value, style, isLast) {
|
|
13495
|
+
const needsQuote = !/^[A-Za-z_$][\w$]*$/.test(key);
|
|
13496
|
+
const renderedKey = needsQuote ? quoteString(key, style.quote) : key;
|
|
13497
|
+
const comma = !isLast || style.trailingComma ? "," : "";
|
|
13498
|
+
return `${style.indent}${renderedKey}: ${value}${comma}`;
|
|
13499
|
+
}
|
|
13500
|
+
function replaceRange(source, start, end, insertion) {
|
|
13501
|
+
return source.slice(0, start) + insertion + source.slice(end);
|
|
13502
|
+
}
|
|
13503
|
+
function collectDuplicateKeys(entries) {
|
|
13504
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13505
|
+
const dupes = [];
|
|
13506
|
+
for (const entry of entries) {
|
|
13507
|
+
if (seen.has(entry.key)) {
|
|
13508
|
+
dupes.push(entry.key);
|
|
13509
|
+
}
|
|
13510
|
+
seen.add(entry.key);
|
|
13511
|
+
}
|
|
13512
|
+
return dupes;
|
|
13513
|
+
}
|
|
13514
|
+
function collectDuplicateImportBindings(imports) {
|
|
13515
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13516
|
+
const dupes = [];
|
|
13517
|
+
for (const item of imports) {
|
|
13518
|
+
for (const name of item.names) {
|
|
13519
|
+
if (seen.has(name)) {
|
|
13520
|
+
dupes.push(name);
|
|
13521
|
+
}
|
|
13522
|
+
seen.add(name);
|
|
13523
|
+
}
|
|
13524
|
+
}
|
|
13525
|
+
return dupes;
|
|
13526
|
+
}
|
|
13527
|
+
function lintArtifactSource(source, kind) {
|
|
13528
|
+
const errors = [];
|
|
13529
|
+
const imports = parseNamedImports(source);
|
|
13530
|
+
const dupImports = collectDuplicateImportBindings(imports);
|
|
13531
|
+
if (dupImports.length > 0) {
|
|
13532
|
+
errors.push(`duplicate import bindings: ${dupImports.join(", ")}`);
|
|
13533
|
+
}
|
|
13534
|
+
const blocks = parseDefineBlocks(source).filter((block2) => block2.kind === kind);
|
|
13535
|
+
if (blocks.length === 0) {
|
|
13536
|
+
errors.push(`missing export const \u2026 = define${kind === "database" ? "Database" : "Registry"}({\u2026})`);
|
|
13537
|
+
return errors;
|
|
13538
|
+
}
|
|
13539
|
+
if (blocks.length > 1) {
|
|
13540
|
+
errors.push(`multiple define${kind === "database" ? "Database" : "Registry"} exports found`);
|
|
13541
|
+
}
|
|
13542
|
+
const block = blocks[0];
|
|
13543
|
+
const dupKeys = collectDuplicateKeys(block.entries);
|
|
13544
|
+
if (dupKeys.length > 0) {
|
|
13545
|
+
errors.push(`duplicate object keys: ${dupKeys.join(", ")}`);
|
|
13546
|
+
}
|
|
13547
|
+
for (const entry of block.entries) {
|
|
13548
|
+
const valueId = entry.value.match(/^[A-Za-z_$][\w$]*$/)?.[0];
|
|
13549
|
+
if (valueId && !hasImportBinding(imports, valueId) && valueId !== block.exportName) {
|
|
13550
|
+
if (!source.includes(`const ${valueId}`) && !source.includes(`function ${valueId}`)) {
|
|
13551
|
+
errors.push(`value "${valueId}" for key "${entry.key}" is not imported`);
|
|
13552
|
+
}
|
|
13553
|
+
}
|
|
13554
|
+
}
|
|
13555
|
+
if (kind === "database" && !hasImportBinding(imports, "defineDatabase")) {
|
|
13556
|
+
errors.push("missing defineDatabase import");
|
|
13557
|
+
}
|
|
13558
|
+
if (kind === "registry" && !hasImportBinding(imports, "defineRegistry")) {
|
|
13559
|
+
errors.push("missing defineRegistry import");
|
|
13560
|
+
}
|
|
13561
|
+
return errors;
|
|
13562
|
+
}
|
|
13563
|
+
function preservedCustomUnits(existing, generated, kind) {
|
|
13564
|
+
const custom = [];
|
|
13565
|
+
const existingImports = parseNamedImports(existing);
|
|
13566
|
+
const generatedImports = parseNamedImports(generated);
|
|
13567
|
+
const generatedModules = new Set(generatedImports.map((item) => normalizeModulePath(item.module)));
|
|
13568
|
+
const generatedNames = new Set(generatedImports.flatMap((item) => item.names));
|
|
13569
|
+
for (const item of existingImports) {
|
|
13570
|
+
const moduleNorm = normalizeModulePath(item.module);
|
|
13571
|
+
if (moduleNorm.includes("@xylex-group/athena")) {
|
|
13572
|
+
continue;
|
|
13573
|
+
}
|
|
13574
|
+
const unexpectedNames = item.names.filter((name) => !generatedNames.has(name));
|
|
13575
|
+
if (unexpectedNames.length > 0 && !generatedModules.has(moduleNorm)) {
|
|
13576
|
+
custom.push(`import { ${unexpectedNames.join(", ")} } from '${item.module}'`);
|
|
13577
|
+
} else if (unexpectedNames.length > 0) {
|
|
13578
|
+
custom.push(`import binding(s): ${unexpectedNames.join(", ")}`);
|
|
13579
|
+
}
|
|
13580
|
+
}
|
|
13581
|
+
const existingBlocks = parseDefineBlocks(existing).filter((block) => block.kind === kind);
|
|
13582
|
+
const generatedBlocks = parseDefineBlocks(generated).filter((block) => block.kind === kind);
|
|
13583
|
+
const generatedKeys = new Set(generatedBlocks[0]?.entries.map((entry) => entry.key) ?? []);
|
|
13584
|
+
for (const entry of existingBlocks[0]?.entries ?? []) {
|
|
13585
|
+
if (!generatedKeys.has(entry.key)) {
|
|
13586
|
+
custom.push(`${kind} entry: ${entry.key}: ${entry.value}`);
|
|
13587
|
+
}
|
|
13588
|
+
}
|
|
13589
|
+
if (kind === "registry") {
|
|
13590
|
+
const existingMeta = parseMetaBlock(existing);
|
|
13591
|
+
const generatedMeta = parseMetaBlock(generated);
|
|
13592
|
+
const generatedMetaKeys = new Set(generatedMeta?.entries.map((entry) => entry.key) ?? []);
|
|
13593
|
+
for (const entry of existingMeta?.entries ?? []) {
|
|
13594
|
+
if (!generatedMetaKeys.has(entry.key) && !KNOWN_META_KEYS.has(entry.key)) {
|
|
13595
|
+
custom.push(`meta entry: ${entry.key}: ${entry.value}`);
|
|
13596
|
+
}
|
|
13597
|
+
}
|
|
13598
|
+
}
|
|
13599
|
+
const exportConstRe = /^export\s+const\s+([A-Za-z_$][\w$]*)\b/gm;
|
|
13600
|
+
const generatedExports = /* @__PURE__ */ new Set();
|
|
13601
|
+
let match;
|
|
13602
|
+
exportConstRe.lastIndex = 0;
|
|
13603
|
+
while ((match = exportConstRe.exec(generated)) !== null) {
|
|
13604
|
+
generatedExports.add(match[1]);
|
|
13605
|
+
}
|
|
13606
|
+
exportConstRe.lastIndex = 0;
|
|
13607
|
+
while ((match = exportConstRe.exec(existing)) !== null) {
|
|
13608
|
+
if (!generatedExports.has(match[1]) && match[1] !== "__athena_schema_meta") {
|
|
13609
|
+
custom.push(`export const ${match[1]}`);
|
|
13610
|
+
}
|
|
13611
|
+
}
|
|
13612
|
+
return custom;
|
|
13613
|
+
}
|
|
13614
|
+
function insertImportAfterPackageImports(source, importLine, style) {
|
|
13615
|
+
const imports = parseNamedImports(source);
|
|
13616
|
+
if (imports.length === 0) {
|
|
13617
|
+
return `${importLine}${style.newline}${source}`;
|
|
13618
|
+
}
|
|
13619
|
+
let anchor = imports[imports.length - 1];
|
|
13620
|
+
for (let i = imports.length - 1; i >= 0; i -= 1) {
|
|
13621
|
+
if (imports[i].module.startsWith(".")) {
|
|
13622
|
+
anchor = imports[i];
|
|
13623
|
+
break;
|
|
13624
|
+
}
|
|
13625
|
+
}
|
|
13626
|
+
const insertAt = anchor.end;
|
|
13627
|
+
const before = source.slice(0, insertAt);
|
|
13628
|
+
const after = source.slice(insertAt);
|
|
13629
|
+
const needsLeadingNl = !before.endsWith("\n");
|
|
13630
|
+
const prefix = needsLeadingNl ? style.newline : "";
|
|
13631
|
+
return `${before}${prefix}${importLine}${after.startsWith("\n") || after.startsWith("\r\n") ? "" : style.newline}${after}`;
|
|
13182
13632
|
}
|
|
13633
|
+
function rewriteObjectBody(entries, style) {
|
|
13634
|
+
if (entries.length === 0) {
|
|
13635
|
+
return style.newline;
|
|
13636
|
+
}
|
|
13637
|
+
const lines = entries.map(
|
|
13638
|
+
(entry, index) => formatObjectEntry(entry.key, entry.value, style, index === entries.length - 1)
|
|
13639
|
+
);
|
|
13640
|
+
return `${style.newline}${lines.join(style.newline)}${style.newline}`;
|
|
13641
|
+
}
|
|
13642
|
+
function mergeDatabaseArtifact(existing, generated) {
|
|
13643
|
+
const style = detectStyle(existing);
|
|
13644
|
+
const generatedStyle = detectStyle(generated);
|
|
13645
|
+
const effectiveStyle = {
|
|
13646
|
+
...style,
|
|
13647
|
+
// Prefer existing fingerprint; fall back to generated if existing is empty-ish
|
|
13648
|
+
quote: existing.includes('"') || existing.includes("'") ? style.quote : generatedStyle.quote
|
|
13649
|
+
};
|
|
13650
|
+
const generatedImports = parseNamedImports(generated);
|
|
13651
|
+
const existingBlocks = parseDefineBlocks(existing).filter((block) => block.kind === "database");
|
|
13652
|
+
const generatedBlocks = parseDefineBlocks(generated).filter((block) => block.kind === "database");
|
|
13653
|
+
if (existingBlocks.length === 0 || generatedBlocks.length === 0) {
|
|
13654
|
+
return {
|
|
13655
|
+
action: "skip",
|
|
13656
|
+
skipReason: "merge-unparseable",
|
|
13657
|
+
added: [],
|
|
13658
|
+
preservedCustom: [],
|
|
13659
|
+
conflicts: [],
|
|
13660
|
+
lintErrors: [],
|
|
13661
|
+
detail: "could not locate defineDatabase({\u2026}) export for merge"
|
|
13662
|
+
};
|
|
13663
|
+
}
|
|
13664
|
+
const generatedBlock = generatedBlocks[0];
|
|
13665
|
+
const conflicts = [];
|
|
13666
|
+
const added = [];
|
|
13667
|
+
let next = existing;
|
|
13668
|
+
if (!hasImportBinding(parseNamedImports(next), "defineDatabase")) {
|
|
13669
|
+
const pkgImport = generatedImports.find((item) => item.names.includes("defineDatabase"));
|
|
13670
|
+
if (pkgImport) {
|
|
13671
|
+
const line = formatImport(["defineDatabase"], pkgImport.module, effectiveStyle);
|
|
13672
|
+
next = insertImportAfterPackageImports(next, line, effectiveStyle);
|
|
13673
|
+
added.push("import defineDatabase");
|
|
13674
|
+
}
|
|
13675
|
+
}
|
|
13676
|
+
let workingImports = parseNamedImports(next);
|
|
13677
|
+
let workingBlocks = parseDefineBlocks(next).filter((block) => block.kind === "database");
|
|
13678
|
+
let workingBlock = workingBlocks[0];
|
|
13679
|
+
const entryMap = new Map(workingBlock.entries.map((entry) => [entry.key, entry]));
|
|
13680
|
+
for (const desired of generatedBlock.entries) {
|
|
13681
|
+
const existingEntry = entryMap.get(desired.key);
|
|
13682
|
+
if (existingEntry) {
|
|
13683
|
+
if (existingEntry.value !== desired.value) {
|
|
13684
|
+
conflicts.push(
|
|
13685
|
+
`key "${desired.key}" maps to ${existingEntry.value} (existing) vs ${desired.value} (generated)`
|
|
13686
|
+
);
|
|
13687
|
+
}
|
|
13688
|
+
continue;
|
|
13689
|
+
}
|
|
13690
|
+
const desiredImport = generatedImports.find((item) => item.names.includes(desired.value));
|
|
13691
|
+
if (desiredImport) {
|
|
13692
|
+
const existingForName = findImportForName(workingImports, desired.value);
|
|
13693
|
+
if (existingForName) {
|
|
13694
|
+
if (normalizeModulePath(existingForName.module) !== normalizeModulePath(desiredImport.module)) {
|
|
13695
|
+
conflicts.push(
|
|
13696
|
+
`binding "${desired.value}" imported from '${existingForName.module}' vs '${desiredImport.module}'`
|
|
13697
|
+
);
|
|
13698
|
+
continue;
|
|
13699
|
+
}
|
|
13700
|
+
} else {
|
|
13701
|
+
const line = formatImport([desired.value], desiredImport.module, effectiveStyle);
|
|
13702
|
+
next = insertImportAfterPackageImports(next, line, effectiveStyle);
|
|
13703
|
+
added.push(`import ${desired.value}`);
|
|
13704
|
+
workingImports = parseNamedImports(next);
|
|
13705
|
+
}
|
|
13706
|
+
}
|
|
13707
|
+
workingBlocks = parseDefineBlocks(next).filter((block) => block.kind === "database");
|
|
13708
|
+
workingBlock = workingBlocks[0];
|
|
13709
|
+
const nextEntries = [...workingBlock.entries, { key: desired.key, value: desired.value, raw: "" }];
|
|
13710
|
+
const body = rewriteObjectBody(nextEntries, effectiveStyle);
|
|
13711
|
+
next = replaceRange(next, workingBlock.bodyStart, workingBlock.bodyEnd, body);
|
|
13712
|
+
entryMap.set(desired.key, { key: desired.key, value: desired.value, raw: "" });
|
|
13713
|
+
added.push(`database entry: ${desired.key}`);
|
|
13714
|
+
}
|
|
13715
|
+
if (conflicts.length > 0 && added.length === 0) {
|
|
13716
|
+
return {
|
|
13717
|
+
action: "skip",
|
|
13718
|
+
skipReason: "merge-conflict",
|
|
13719
|
+
added: [],
|
|
13720
|
+
preservedCustom: preservedCustomUnits(existing, generated, "database"),
|
|
13721
|
+
conflicts,
|
|
13722
|
+
lintErrors: [],
|
|
13723
|
+
detail: conflicts.join("; ")
|
|
13724
|
+
};
|
|
13725
|
+
}
|
|
13726
|
+
const lintErrors = lintArtifactSource(next, "database");
|
|
13727
|
+
if (lintErrors.length > 0) {
|
|
13728
|
+
return {
|
|
13729
|
+
action: "skip",
|
|
13730
|
+
skipReason: "merge-lint-failed",
|
|
13731
|
+
added,
|
|
13732
|
+
preservedCustom: preservedCustomUnits(existing, generated, "database"),
|
|
13733
|
+
conflicts,
|
|
13734
|
+
lintErrors,
|
|
13735
|
+
detail: lintErrors.join("; ")
|
|
13736
|
+
};
|
|
13737
|
+
}
|
|
13738
|
+
const preservedCustom = preservedCustomUnits(next, generated, "database");
|
|
13739
|
+
if (next === existing || next.replace(/\r\n/g, "\n") === existing.replace(/\r\n/g, "\n")) {
|
|
13740
|
+
return {
|
|
13741
|
+
action: "unchanged",
|
|
13742
|
+
content: existing,
|
|
13743
|
+
skipReason: "already-current",
|
|
13744
|
+
added: [],
|
|
13745
|
+
preservedCustom,
|
|
13746
|
+
conflicts,
|
|
13747
|
+
lintErrors: [],
|
|
13748
|
+
detail: conflicts.length > 0 ? conflicts.join("; ") : void 0
|
|
13749
|
+
};
|
|
13750
|
+
}
|
|
13751
|
+
return {
|
|
13752
|
+
action: "write",
|
|
13753
|
+
content: next.endsWith("\n") ? next : `${next}${effectiveStyle.newline}`,
|
|
13754
|
+
writeReason: "merged",
|
|
13755
|
+
added,
|
|
13756
|
+
preservedCustom,
|
|
13757
|
+
conflicts,
|
|
13758
|
+
lintErrors: []
|
|
13759
|
+
};
|
|
13760
|
+
}
|
|
13761
|
+
function mergeMetaFields(existingMeta, generatedMeta) {
|
|
13762
|
+
const added = [];
|
|
13763
|
+
if (!generatedMeta) {
|
|
13764
|
+
return { entries: existingMeta?.entries ?? [], changed: false, added };
|
|
13765
|
+
}
|
|
13766
|
+
if (!existingMeta) {
|
|
13767
|
+
return {
|
|
13768
|
+
entries: generatedMeta.entries,
|
|
13769
|
+
changed: true,
|
|
13770
|
+
added: generatedMeta.entries.map((entry) => `meta entry: ${entry.key}`)
|
|
13771
|
+
};
|
|
13772
|
+
}
|
|
13773
|
+
const map = new Map(existingMeta.entries.map((entry) => [entry.key, entry]));
|
|
13774
|
+
let changed = false;
|
|
13775
|
+
for (const desired of generatedMeta.entries) {
|
|
13776
|
+
const current = map.get(desired.key);
|
|
13777
|
+
if (!current) {
|
|
13778
|
+
map.set(desired.key, desired);
|
|
13779
|
+
added.push(`meta entry: ${desired.key}`);
|
|
13780
|
+
changed = true;
|
|
13781
|
+
continue;
|
|
13782
|
+
}
|
|
13783
|
+
if (KNOWN_META_KEYS.has(desired.key) && current.value !== desired.value) {
|
|
13784
|
+
map.set(desired.key, desired);
|
|
13785
|
+
added.push(`meta refresh: ${desired.key}`);
|
|
13786
|
+
changed = true;
|
|
13787
|
+
}
|
|
13788
|
+
}
|
|
13789
|
+
const ordered = [];
|
|
13790
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13791
|
+
for (const entry of existingMeta.entries) {
|
|
13792
|
+
const next = map.get(entry.key);
|
|
13793
|
+
if (next) {
|
|
13794
|
+
ordered.push(next);
|
|
13795
|
+
seen.add(entry.key);
|
|
13796
|
+
}
|
|
13797
|
+
}
|
|
13798
|
+
for (const entry of generatedMeta.entries) {
|
|
13799
|
+
if (!seen.has(entry.key)) {
|
|
13800
|
+
const next = map.get(entry.key);
|
|
13801
|
+
if (next) {
|
|
13802
|
+
ordered.push(next);
|
|
13803
|
+
seen.add(entry.key);
|
|
13804
|
+
}
|
|
13805
|
+
}
|
|
13806
|
+
}
|
|
13807
|
+
for (const [key, entry] of map) {
|
|
13808
|
+
if (!seen.has(key)) {
|
|
13809
|
+
ordered.push(entry);
|
|
13810
|
+
}
|
|
13811
|
+
}
|
|
13812
|
+
return { entries: ordered, changed, added };
|
|
13813
|
+
}
|
|
13814
|
+
function mergeRegistryArtifact(existing, generated) {
|
|
13815
|
+
const style = detectStyle(existing);
|
|
13816
|
+
const effectiveStyle = style;
|
|
13817
|
+
const generatedImports = parseNamedImports(generated);
|
|
13818
|
+
const existingBlocks = parseDefineBlocks(existing).filter((block) => block.kind === "registry");
|
|
13819
|
+
const generatedBlocks = parseDefineBlocks(generated).filter((block) => block.kind === "registry");
|
|
13820
|
+
if (existingBlocks.length === 0 || generatedBlocks.length === 0) {
|
|
13821
|
+
return {
|
|
13822
|
+
action: "skip",
|
|
13823
|
+
skipReason: "merge-unparseable",
|
|
13824
|
+
added: [],
|
|
13825
|
+
preservedCustom: [],
|
|
13826
|
+
conflicts: [],
|
|
13827
|
+
lintErrors: [],
|
|
13828
|
+
detail: "could not locate defineRegistry({\u2026}) export for merge"
|
|
13829
|
+
};
|
|
13830
|
+
}
|
|
13831
|
+
const existingBlock = existingBlocks[0];
|
|
13832
|
+
const generatedBlock = generatedBlocks[0];
|
|
13833
|
+
const conflicts = [];
|
|
13834
|
+
const added = [];
|
|
13835
|
+
let next = existing;
|
|
13836
|
+
if (!hasImportBinding(parseNamedImports(next), "defineRegistry")) {
|
|
13837
|
+
const pkgImport = generatedImports.find((item) => item.names.includes("defineRegistry"));
|
|
13838
|
+
if (pkgImport) {
|
|
13839
|
+
next = insertImportAfterPackageImports(
|
|
13840
|
+
next,
|
|
13841
|
+
formatImport(["defineRegistry"], pkgImport.module, effectiveStyle),
|
|
13842
|
+
effectiveStyle
|
|
13843
|
+
);
|
|
13844
|
+
added.push("import defineRegistry");
|
|
13845
|
+
}
|
|
13846
|
+
}
|
|
13847
|
+
const preferredDbValue = existingBlock.entries[0]?.value ?? generatedBlock.entries[0]?.value;
|
|
13848
|
+
const generatedDbImport = generatedImports.find((item) => item.names.includes(generatedBlock.entries[0]?.value ?? "")) ?? generatedImports.find((item) => item.module.startsWith("."));
|
|
13849
|
+
if (preferredDbValue && generatedDbImport) {
|
|
13850
|
+
const existingForName = findImportForName(parseNamedImports(next), preferredDbValue);
|
|
13851
|
+
if (!existingForName) {
|
|
13852
|
+
const modulePath = generatedDbImport.module;
|
|
13853
|
+
const importName = findImportForName(generatedImports, preferredDbValue)?.names[0] ?? generatedBlock.entries[0]?.value ?? preferredDbValue;
|
|
13854
|
+
if (!hasImportBinding(parseNamedImports(next), importName)) {
|
|
13855
|
+
next = insertImportAfterPackageImports(
|
|
13856
|
+
next,
|
|
13857
|
+
formatImport([importName], modulePath, effectiveStyle),
|
|
13858
|
+
effectiveStyle
|
|
13859
|
+
);
|
|
13860
|
+
added.push(`import ${importName}`);
|
|
13861
|
+
}
|
|
13862
|
+
} else if (normalizeModulePath(existingForName.module) !== normalizeModulePath(generatedDbImport.module)) {
|
|
13863
|
+
conflicts.push(
|
|
13864
|
+
`binding "${preferredDbValue}" imported from '${existingForName.module}' vs '${generatedDbImport.module}'`
|
|
13865
|
+
);
|
|
13866
|
+
}
|
|
13867
|
+
}
|
|
13868
|
+
let workingBlocks = parseDefineBlocks(next).filter((block) => block.kind === "registry");
|
|
13869
|
+
let workingBlock = workingBlocks[0];
|
|
13870
|
+
const entryMap = new Map(workingBlock.entries.map((entry) => [entry.key, entry]));
|
|
13871
|
+
for (const desired of generatedBlock.entries) {
|
|
13872
|
+
const existingEntry = entryMap.get(desired.key);
|
|
13873
|
+
if (existingEntry) {
|
|
13874
|
+
continue;
|
|
13875
|
+
}
|
|
13876
|
+
const dbImport = parseNamedImports(next).find(
|
|
13877
|
+
(item) => item.module.startsWith(".") && item.names.some((name) => name !== "defineRegistry")
|
|
13878
|
+
);
|
|
13879
|
+
const value = dbImport?.names[0] ?? desired.value;
|
|
13880
|
+
const nextEntries = [...workingBlock.entries, { key: desired.key, value, raw: "" }];
|
|
13881
|
+
const body = rewriteObjectBody(nextEntries, effectiveStyle);
|
|
13882
|
+
next = replaceRange(next, workingBlock.bodyStart, workingBlock.bodyEnd, body);
|
|
13883
|
+
entryMap.set(desired.key, { key: desired.key, value, raw: "" });
|
|
13884
|
+
added.push(`registry entry: ${desired.key}`);
|
|
13885
|
+
workingBlocks = parseDefineBlocks(next).filter((block) => block.kind === "registry");
|
|
13886
|
+
workingBlock = workingBlocks[0];
|
|
13887
|
+
}
|
|
13888
|
+
const existingMeta = parseMetaBlock(next);
|
|
13889
|
+
const generatedMeta = parseMetaBlock(generated);
|
|
13890
|
+
const structuralAdded = added.length > 0;
|
|
13891
|
+
if (generatedMeta) {
|
|
13892
|
+
if (!existingMeta) {
|
|
13893
|
+
const blocks = parseDefineBlocks(next).filter((block) => block.kind === "registry");
|
|
13894
|
+
const insertAt = blocks[0]?.fullStart ?? next.length;
|
|
13895
|
+
const metaBody = rewriteObjectBody(generatedMeta.entries, effectiveStyle);
|
|
13896
|
+
const metaBlock = `export const __athena_schema_meta = {${metaBody}} as const${effectiveStyle.semicolons ? ";" : ""}${effectiveStyle.newline}${effectiveStyle.newline}`;
|
|
13897
|
+
next = replaceRange(next, insertAt, insertAt, metaBlock);
|
|
13898
|
+
added.push("__athena_schema_meta");
|
|
13899
|
+
} else {
|
|
13900
|
+
const desiredEntries = structuralAdded ? generatedMeta.entries : generatedMeta.entries.filter((entry) => {
|
|
13901
|
+
return !existingMeta.entries.some((current) => current.key === entry.key);
|
|
13902
|
+
});
|
|
13903
|
+
if (structuralAdded) {
|
|
13904
|
+
const merged = mergeMetaFields(existingMeta, generatedMeta);
|
|
13905
|
+
if (merged.changed) {
|
|
13906
|
+
const metaNow = parseMetaBlock(next);
|
|
13907
|
+
if (metaNow) {
|
|
13908
|
+
const body = rewriteObjectBody(merged.entries, effectiveStyle);
|
|
13909
|
+
next = replaceRange(next, metaNow.bodyStart, metaNow.bodyEnd, body);
|
|
13910
|
+
added.push(...merged.added);
|
|
13911
|
+
}
|
|
13912
|
+
}
|
|
13913
|
+
} else if (desiredEntries.length > 0) {
|
|
13914
|
+
const map = new Map(existingMeta.entries.map((entry) => [entry.key, entry]));
|
|
13915
|
+
for (const entry of desiredEntries) {
|
|
13916
|
+
map.set(entry.key, entry);
|
|
13917
|
+
added.push(`meta entry: ${entry.key}`);
|
|
13918
|
+
}
|
|
13919
|
+
const ordered = [
|
|
13920
|
+
...existingMeta.entries.map((entry) => map.get(entry.key)),
|
|
13921
|
+
...desiredEntries.filter((entry) => !existingMeta.entries.some((e) => e.key === entry.key))
|
|
13922
|
+
];
|
|
13923
|
+
const metaNow = parseMetaBlock(next);
|
|
13924
|
+
if (metaNow) {
|
|
13925
|
+
const body = rewriteObjectBody(ordered, effectiveStyle);
|
|
13926
|
+
next = replaceRange(next, metaNow.bodyStart, metaNow.bodyEnd, body);
|
|
13927
|
+
}
|
|
13928
|
+
}
|
|
13929
|
+
}
|
|
13930
|
+
}
|
|
13931
|
+
if (conflicts.length > 0 && added.length === 0) {
|
|
13932
|
+
return {
|
|
13933
|
+
action: "skip",
|
|
13934
|
+
skipReason: "merge-conflict",
|
|
13935
|
+
added: [],
|
|
13936
|
+
preservedCustom: preservedCustomUnits(existing, generated, "registry"),
|
|
13937
|
+
conflicts,
|
|
13938
|
+
lintErrors: [],
|
|
13939
|
+
detail: conflicts.join("; ")
|
|
13940
|
+
};
|
|
13941
|
+
}
|
|
13942
|
+
const lintErrors = lintArtifactSource(next, "registry");
|
|
13943
|
+
if (lintErrors.length > 0) {
|
|
13944
|
+
return {
|
|
13945
|
+
action: "skip",
|
|
13946
|
+
skipReason: "merge-lint-failed",
|
|
13947
|
+
added,
|
|
13948
|
+
preservedCustom: preservedCustomUnits(existing, generated, "registry"),
|
|
13949
|
+
conflicts,
|
|
13950
|
+
lintErrors,
|
|
13951
|
+
detail: lintErrors.join("; ")
|
|
13952
|
+
};
|
|
13953
|
+
}
|
|
13954
|
+
const preservedCustom = preservedCustomUnits(next, generated, "registry");
|
|
13955
|
+
if (next.replace(/\r\n/g, "\n") === existing.replace(/\r\n/g, "\n")) {
|
|
13956
|
+
return {
|
|
13957
|
+
action: "unchanged",
|
|
13958
|
+
content: existing,
|
|
13959
|
+
skipReason: "already-current",
|
|
13960
|
+
added: [],
|
|
13961
|
+
preservedCustom,
|
|
13962
|
+
conflicts,
|
|
13963
|
+
lintErrors: []
|
|
13964
|
+
};
|
|
13965
|
+
}
|
|
13966
|
+
return {
|
|
13967
|
+
action: "write",
|
|
13968
|
+
content: next.endsWith("\n") ? next : `${next}${effectiveStyle.newline}`,
|
|
13969
|
+
writeReason: "merged",
|
|
13970
|
+
added,
|
|
13971
|
+
preservedCustom,
|
|
13972
|
+
conflicts,
|
|
13973
|
+
lintErrors: []
|
|
13974
|
+
};
|
|
13975
|
+
}
|
|
13976
|
+
function mergeProtectedArtifact(kind, existing, generated, policy) {
|
|
13977
|
+
if (policy === "overwrite") {
|
|
13978
|
+
if (existing.replace(/\r\n/g, "\n") === generated.replace(/\r\n/g, "\n")) {
|
|
13979
|
+
return {
|
|
13980
|
+
action: "unchanged",
|
|
13981
|
+
content: existing,
|
|
13982
|
+
skipReason: "already-current",
|
|
13983
|
+
added: [],
|
|
13984
|
+
preservedCustom: [],
|
|
13985
|
+
conflicts: [],
|
|
13986
|
+
lintErrors: []
|
|
13987
|
+
};
|
|
13988
|
+
}
|
|
13989
|
+
return {
|
|
13990
|
+
action: "write",
|
|
13991
|
+
content: generated,
|
|
13992
|
+
writeReason: "overwritten",
|
|
13993
|
+
added: ["full overwrite"],
|
|
13994
|
+
preservedCustom: [],
|
|
13995
|
+
conflicts: [],
|
|
13996
|
+
lintErrors: []
|
|
13997
|
+
};
|
|
13998
|
+
}
|
|
13999
|
+
if (policy === "skip") {
|
|
14000
|
+
return {
|
|
14001
|
+
action: "skip",
|
|
14002
|
+
skipReason: "protected-existing-file",
|
|
14003
|
+
added: [],
|
|
14004
|
+
preservedCustom: preservedCustomUnits(existing, generated, kind),
|
|
14005
|
+
conflicts: [],
|
|
14006
|
+
lintErrors: [],
|
|
14007
|
+
detail: "artifactWrite policy is skip"
|
|
14008
|
+
};
|
|
14009
|
+
}
|
|
14010
|
+
return kind === "database" ? mergeDatabaseArtifact(existing, generated) : mergeRegistryArtifact(existing, generated);
|
|
14011
|
+
}
|
|
14012
|
+
function resolveArtifactWritePlan(file, existingContent, policy) {
|
|
14013
|
+
if (existingContent === null) {
|
|
14014
|
+
return {
|
|
14015
|
+
action: "write",
|
|
14016
|
+
content: file.content,
|
|
14017
|
+
writeReason: "created",
|
|
14018
|
+
added: ["created"],
|
|
14019
|
+
preservedCustom: [],
|
|
14020
|
+
conflicts: [],
|
|
14021
|
+
lintErrors: []
|
|
14022
|
+
};
|
|
14023
|
+
}
|
|
14024
|
+
if (file.kind === "model" || file.kind === "schema" || policy === "always") {
|
|
14025
|
+
if (existingContent.replace(/\r\n/g, "\n") === file.content.replace(/\r\n/g, "\n")) {
|
|
14026
|
+
return {
|
|
14027
|
+
action: "unchanged",
|
|
14028
|
+
content: existingContent,
|
|
14029
|
+
skipReason: "already-current",
|
|
14030
|
+
added: [],
|
|
14031
|
+
preservedCustom: [],
|
|
14032
|
+
conflicts: [],
|
|
14033
|
+
lintErrors: []
|
|
14034
|
+
};
|
|
14035
|
+
}
|
|
14036
|
+
return {
|
|
14037
|
+
action: "write",
|
|
14038
|
+
content: file.content,
|
|
14039
|
+
writeReason: existingContent ? "overwritten" : "created",
|
|
14040
|
+
added: ["overwritten"],
|
|
14041
|
+
preservedCustom: [],
|
|
14042
|
+
conflicts: [],
|
|
14043
|
+
lintErrors: []
|
|
14044
|
+
};
|
|
14045
|
+
}
|
|
14046
|
+
return mergeProtectedArtifact(
|
|
14047
|
+
file.kind,
|
|
14048
|
+
existingContent,
|
|
14049
|
+
file.content,
|
|
14050
|
+
policy
|
|
14051
|
+
);
|
|
14052
|
+
}
|
|
14053
|
+
|
|
14054
|
+
// src/generator/pipeline.ts
|
|
13183
14055
|
async function fileExists(path) {
|
|
13184
14056
|
try {
|
|
13185
14057
|
await promises.stat(path);
|
|
@@ -13188,25 +14060,70 @@ async function fileExists(path) {
|
|
|
13188
14060
|
return false;
|
|
13189
14061
|
}
|
|
13190
14062
|
}
|
|
13191
|
-
async function
|
|
14063
|
+
async function readExisting(path) {
|
|
14064
|
+
try {
|
|
14065
|
+
return await promises.readFile(path, "utf8");
|
|
14066
|
+
} catch {
|
|
14067
|
+
return null;
|
|
14068
|
+
}
|
|
14069
|
+
}
|
|
14070
|
+
function policyForArtifact(file, config) {
|
|
14071
|
+
if (file.kind === "model" || file.kind === "schema") {
|
|
14072
|
+
return "always";
|
|
14073
|
+
}
|
|
14074
|
+
if (file.kind === "database") {
|
|
14075
|
+
return config.output.artifactWrite.database;
|
|
14076
|
+
}
|
|
14077
|
+
return config.output.artifactWrite.registry;
|
|
14078
|
+
}
|
|
14079
|
+
async function writeArtifacts(files, cwd, config, dryRun) {
|
|
13192
14080
|
const writtenFiles = [];
|
|
14081
|
+
const writtenDetails = [];
|
|
13193
14082
|
const skippedFiles = [];
|
|
13194
14083
|
for (const file of files) {
|
|
13195
14084
|
const absolutePath = path.resolve(cwd, file.path);
|
|
13196
|
-
|
|
14085
|
+
const exists = await fileExists(absolutePath);
|
|
14086
|
+
const existingContent = exists ? await readExisting(absolutePath) : null;
|
|
14087
|
+
const policy = policyForArtifact(file, config);
|
|
14088
|
+
const plan = resolveArtifactWritePlan(file, existingContent, policy);
|
|
14089
|
+
if (plan.action === "skip" || plan.action === "unchanged") {
|
|
14090
|
+
skippedFiles.push({
|
|
14091
|
+
kind: file.kind,
|
|
14092
|
+
path: file.path,
|
|
14093
|
+
reason: plan.skipReason ?? "already-current",
|
|
14094
|
+
detail: plan.detail,
|
|
14095
|
+
preservedCustom: plan.preservedCustom.length > 0 ? plan.preservedCustom : void 0,
|
|
14096
|
+
conflicts: plan.conflicts.length > 0 ? plan.conflicts : void 0,
|
|
14097
|
+
lintErrors: plan.lintErrors.length > 0 ? plan.lintErrors : void 0
|
|
14098
|
+
});
|
|
14099
|
+
continue;
|
|
14100
|
+
}
|
|
14101
|
+
if (!plan.content || !plan.writeReason) {
|
|
13197
14102
|
skippedFiles.push({
|
|
13198
14103
|
kind: file.kind,
|
|
13199
14104
|
path: file.path,
|
|
13200
|
-
reason: "
|
|
14105
|
+
reason: "merge-lint-failed",
|
|
14106
|
+
detail: "merge produced no content",
|
|
14107
|
+
lintErrors: plan.lintErrors
|
|
13201
14108
|
});
|
|
13202
14109
|
continue;
|
|
13203
14110
|
}
|
|
13204
|
-
|
|
13205
|
-
|
|
14111
|
+
if (!dryRun) {
|
|
14112
|
+
await promises.mkdir(path.dirname(absolutePath), { recursive: true });
|
|
14113
|
+
await promises.writeFile(absolutePath, plan.content, "utf8");
|
|
14114
|
+
}
|
|
13206
14115
|
writtenFiles.push(file.path);
|
|
14116
|
+
writtenDetails.push({
|
|
14117
|
+
kind: file.kind,
|
|
14118
|
+
path: file.path,
|
|
14119
|
+
reason: plan.writeReason,
|
|
14120
|
+
added: plan.added.length > 0 ? plan.added : void 0,
|
|
14121
|
+
preservedCustom: plan.preservedCustom.length > 0 ? plan.preservedCustom : void 0
|
|
14122
|
+
});
|
|
13207
14123
|
}
|
|
13208
14124
|
return {
|
|
13209
14125
|
writtenFiles,
|
|
14126
|
+
writtenDetails,
|
|
13210
14127
|
skippedFiles
|
|
13211
14128
|
};
|
|
13212
14129
|
}
|
|
@@ -13222,12 +14139,18 @@ async function runSchemaGenerator(options = {}) {
|
|
|
13222
14139
|
schemas: resolveProviderSchemas(config.provider)
|
|
13223
14140
|
});
|
|
13224
14141
|
const generated = generateArtifactsFromSnapshot(snapshot, config);
|
|
13225
|
-
const writeResult =
|
|
14142
|
+
const writeResult = await writeArtifacts(
|
|
14143
|
+
generated.files,
|
|
14144
|
+
cwd,
|
|
14145
|
+
config,
|
|
14146
|
+
options.dryRun === true
|
|
14147
|
+
);
|
|
13226
14148
|
return {
|
|
13227
14149
|
...generated,
|
|
13228
14150
|
configPath,
|
|
13229
14151
|
config,
|
|
13230
14152
|
writtenFiles: writeResult.writtenFiles,
|
|
14153
|
+
writtenDetails: writeResult.writtenDetails,
|
|
13231
14154
|
skippedFiles: writeResult.skippedFiles
|
|
13232
14155
|
};
|
|
13233
14156
|
}
|