@lukoweb/apitogo 0.1.126 → 0.1.127
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/dist/cli/cli.js +54 -7
- package/dist/declarations/cli/platform/client/platform-api.d.ts +6 -0
- package/dist/declarations/cli/platform/helpers/dev-portal-manifest.d.ts +2 -0
- package/dist/declarations/cli/platform/helpers/publish-preflight.d.ts +2 -0
- package/dist/declarations/cli/platform/tools/gateway.d.ts +6 -0
- package/dist/declarations/config/local-manifest.d.ts +20 -0
- package/dist/declarations/config/validators/ModulesSchema.d.ts +20 -0
- package/dist/declarations/config/validators/ZudokuConfig.d.ts +5 -0
- package/dist/flat-config.d.ts +32 -24
- package/docs/configuration/plans.md +26 -0
- package/package.json +155 -10
- package/src/config/apitogo-config-core.ts +2 -0
- package/src/config/local-manifest.ts +17 -0
- package/src/config/validators/ModulesSchema.ts +11 -0
- package/LICENSE.md +0 -18
package/dist/cli/cli.js
CHANGED
|
@@ -736,6 +736,8 @@ var init_apitogo_config_core = __esm({
|
|
|
736
736
|
DEMOMODE: "demoMode",
|
|
737
737
|
DISPLAYNAME: "displayName",
|
|
738
738
|
PRICEAMOUNT: "priceAmount",
|
|
739
|
+
PRICINGMODEL: "pricingModel",
|
|
740
|
+
PRICELABEL: "priceLabel",
|
|
739
741
|
PRICECURRENCY: "priceCurrency",
|
|
740
742
|
BILLINGPERIOD: "billingPeriod",
|
|
741
743
|
LIMITSJSON: "limitsJson",
|
|
@@ -1020,6 +1022,10 @@ var init_ModulesSchema = __esm({
|
|
|
1020
1022
|
sku: z3.string(),
|
|
1021
1023
|
displayName: z3.string(),
|
|
1022
1024
|
priceAmount: z3.number().default(0),
|
|
1025
|
+
pricingModel: z3.enum(["fixed", "custom"]).optional().describe(
|
|
1026
|
+
'"custom" shows a contact-sales form instead of checkout; priceAmount must be 0.'
|
|
1027
|
+
),
|
|
1028
|
+
priceLabel: z3.string().max(64).optional().describe('Text shown instead of the price, e.g. "Custom".'),
|
|
1023
1029
|
priceCurrency: z3.string().trim().toLowerCase().regex(
|
|
1024
1030
|
/^[a-z]{3}$/,
|
|
1025
1031
|
"priceCurrency must be a 3-letter ISO 4217 code (lowercase)"
|
|
@@ -1127,6 +1133,8 @@ function plansToPreviewCatalog(plans) {
|
|
|
1127
1133
|
sku: plan.sku,
|
|
1128
1134
|
displayName: plan.displayName,
|
|
1129
1135
|
priceAmount: plan.priceAmount ?? 0,
|
|
1136
|
+
pricingModel: plan.pricingModel ?? "fixed",
|
|
1137
|
+
...plan.priceLabel ? { priceLabel: plan.priceLabel } : {},
|
|
1130
1138
|
priceCurrency: plan.priceCurrency ?? "usd",
|
|
1131
1139
|
billingPeriod: normalizeBillingPeriod(plan.billingPeriod),
|
|
1132
1140
|
limits: coerceGatewayLimits(plan) ?? null,
|
|
@@ -1175,13 +1183,14 @@ async function readEffectiveManifest(rootDir, _env) {
|
|
|
1175
1183
|
return null;
|
|
1176
1184
|
}
|
|
1177
1185
|
}
|
|
1178
|
-
var BillingPeriodSchema, GatewayLimitsSchema, PriceCurrencySchema, ALLOWED_RUNTIME_VERSIONS, ManifestPlanInputSchema, DevPortalLocalManifestSchema;
|
|
1186
|
+
var BillingPeriodSchema, PlanPricingModelSchema, GatewayLimitsSchema, PriceCurrencySchema, ALLOWED_RUNTIME_VERSIONS, ManifestPlanInputSchema, DevPortalLocalManifestSchema;
|
|
1179
1187
|
var init_local_manifest = __esm({
|
|
1180
1188
|
"src/config/local-manifest.ts"() {
|
|
1181
1189
|
init_apitogo_config_loader();
|
|
1182
1190
|
init_gateway_limits();
|
|
1183
1191
|
init_landing_manifest();
|
|
1184
1192
|
BillingPeriodSchema = z4.enum(["month", "year", "monthly", "annual"]);
|
|
1193
|
+
PlanPricingModelSchema = z4.enum(["fixed", "custom"]);
|
|
1185
1194
|
GatewayLimitsSchema = z4.object({
|
|
1186
1195
|
rateLimit: z4.object({
|
|
1187
1196
|
calls: z4.number(),
|
|
@@ -1212,6 +1221,9 @@ var init_local_manifest = __esm({
|
|
|
1212
1221
|
sku: z4.string().min(1),
|
|
1213
1222
|
displayName: z4.string().min(1),
|
|
1214
1223
|
priceAmount: z4.number().default(0),
|
|
1224
|
+
/** `custom` plans show a contact-sales form instead of checkout. */
|
|
1225
|
+
pricingModel: PlanPricingModelSchema.optional(),
|
|
1226
|
+
priceLabel: z4.string().max(64).optional(),
|
|
1215
1227
|
priceCurrency: PriceCurrencySchema.optional(),
|
|
1216
1228
|
billingPeriod: BillingPeriodSchema.optional(),
|
|
1217
1229
|
limits: GatewayLimitsSchema.optional(),
|
|
@@ -5797,7 +5809,7 @@ import {
|
|
|
5797
5809
|
// package.json
|
|
5798
5810
|
var package_default = {
|
|
5799
5811
|
name: "@lukoweb/apitogo",
|
|
5800
|
-
version: "0.1.
|
|
5812
|
+
version: "0.1.127",
|
|
5801
5813
|
type: "module",
|
|
5802
5814
|
sideEffects: [
|
|
5803
5815
|
"**/*.css",
|
|
@@ -13134,7 +13146,25 @@ function validateManifestForPlatformPublish(manifest) {
|
|
|
13134
13146
|
if (plan.priceAmount !== void 0 && plan.priceAmount < 0) {
|
|
13135
13147
|
issues.push({
|
|
13136
13148
|
field: `plans[${index}].priceAmount`,
|
|
13137
|
-
message:
|
|
13149
|
+
message: 'priceAmount must be >= 0. For negotiated pricing use pricingModel: "custom".'
|
|
13150
|
+
});
|
|
13151
|
+
}
|
|
13152
|
+
if (plan.pricingModel !== void 0 && plan.pricingModel !== "fixed" && plan.pricingModel !== "custom") {
|
|
13153
|
+
issues.push({
|
|
13154
|
+
field: `plans[${index}].pricingModel`,
|
|
13155
|
+
message: "pricingModel must be 'fixed' or 'custom'."
|
|
13156
|
+
});
|
|
13157
|
+
}
|
|
13158
|
+
if (plan.pricingModel === "custom" && (plan.priceAmount ?? 0) !== 0) {
|
|
13159
|
+
issues.push({
|
|
13160
|
+
field: `plans[${index}].priceAmount`,
|
|
13161
|
+
message: "priceAmount must be 0 (or omitted) for custom-priced plans."
|
|
13162
|
+
});
|
|
13163
|
+
}
|
|
13164
|
+
if (plan.priceLabel !== void 0 && plan.priceLabel.length > 64) {
|
|
13165
|
+
issues.push({
|
|
13166
|
+
field: `plans[${index}].priceLabel`,
|
|
13167
|
+
message: "priceLabel must be at most 64 characters."
|
|
13138
13168
|
});
|
|
13139
13169
|
}
|
|
13140
13170
|
const currencyResult = tryNormalizePriceCurrency(plan.priceCurrency);
|
|
@@ -15582,6 +15612,11 @@ function buildPlanItemFromWizard(input5) {
|
|
|
15582
15612
|
priceAmount: input5.priceAmount,
|
|
15583
15613
|
limits: buildLimits(input5.rateLimitCalls, input5.monthlyQuota)
|
|
15584
15614
|
};
|
|
15615
|
+
if (input5.pricingModel === "custom") {
|
|
15616
|
+
item.priceAmount = 0;
|
|
15617
|
+
item.pricingModel = "custom";
|
|
15618
|
+
return item;
|
|
15619
|
+
}
|
|
15585
15620
|
if (input5.priceAmount > 0) {
|
|
15586
15621
|
item.priceCurrency = "usd";
|
|
15587
15622
|
item.billingPeriod = "month";
|
|
@@ -15946,11 +15981,13 @@ async function promptMakeConfigInteractive(options) {
|
|
|
15946
15981
|
printDiagnosticsToConsole("Plan title is required.");
|
|
15947
15982
|
continue;
|
|
15948
15983
|
}
|
|
15949
|
-
const
|
|
15984
|
+
const pricingAnswer = (await ask(
|
|
15950
15985
|
rl,
|
|
15951
|
-
"
|
|
15952
|
-
|
|
15953
|
-
);
|
|
15986
|
+
"Pricing: fixed price or custom (contact sales)? (fixed/custom)",
|
|
15987
|
+
"fixed"
|
|
15988
|
+
)).toLowerCase();
|
|
15989
|
+
const pricingModel = pricingAnswer.startsWith("c") ? "custom" : "fixed";
|
|
15990
|
+
const priceAmount = pricingModel === "custom" ? 0 : await askNonNegativeNumber(rl, "Price (USD/month, 0 for free)", 0);
|
|
15954
15991
|
const rateLimitCalls = await askNonNegativeNumber(
|
|
15955
15992
|
rl,
|
|
15956
15993
|
"Rate limit (calls per minute)",
|
|
@@ -15964,6 +16001,7 @@ async function promptMakeConfigInteractive(options) {
|
|
|
15964
16001
|
const planItem = buildPlanItemFromWizard({
|
|
15965
16002
|
displayName: displayName.trim(),
|
|
15966
16003
|
priceAmount,
|
|
16004
|
+
pricingModel,
|
|
15967
16005
|
rateLimitCalls,
|
|
15968
16006
|
monthlyQuota
|
|
15969
16007
|
});
|
|
@@ -17203,6 +17241,8 @@ async function handleCreateGatewayPlan(client, config2, args) {
|
|
|
17203
17241
|
limitsJson: args.limitsJson ?? null,
|
|
17204
17242
|
includedActionKeys,
|
|
17205
17243
|
priceAmount: args.priceAmount,
|
|
17244
|
+
pricingModel: args.pricingModel,
|
|
17245
|
+
priceLabel: args.priceLabel,
|
|
17206
17246
|
priceCurrency: args.priceCurrency,
|
|
17207
17247
|
billingPeriod: args.billingPeriod,
|
|
17208
17248
|
sortOrder: args.sortOrder
|
|
@@ -17229,6 +17269,8 @@ function buildUpdateGatewayPlanBody(existing, patch) {
|
|
|
17229
17269
|
limitsJson: patch.limitsJson !== void 0 ? patch.limitsJson : existing.limitsJson ?? null,
|
|
17230
17270
|
includedActionKeys: patch.includedActionKeys !== void 0 ? patch.includedActionKeys : existingActionKeys(existing),
|
|
17231
17271
|
priceAmount: patch.priceAmount ?? existing.priceAmount,
|
|
17272
|
+
pricingModel: patch.pricingModel ?? existing.pricingModel,
|
|
17273
|
+
priceLabel: patch.priceLabel ?? existing.priceLabel ?? void 0,
|
|
17232
17274
|
priceCurrency: patch.priceCurrency ?? existing.priceCurrency,
|
|
17233
17275
|
billingPeriod: patch.billingPeriod ?? existing.billingPeriod,
|
|
17234
17276
|
sortOrder: patch.sortOrder ?? existing.sortOrder
|
|
@@ -17509,6 +17551,9 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
|
|
|
17509
17551
|
isActive: true,
|
|
17510
17552
|
limitsJson: planLimitsForPlatform(input5),
|
|
17511
17553
|
priceAmount: input5.priceAmount,
|
|
17554
|
+
// Config is the source of truth: dropping pricingModel/priceLabel reverts to fixed / no label.
|
|
17555
|
+
pricingModel: input5.pricingModel ?? "fixed",
|
|
17556
|
+
priceLabel: input5.priceLabel ?? "",
|
|
17512
17557
|
priceCurrency: input5.priceCurrency,
|
|
17513
17558
|
billingPeriod: input5.billingPeriod ? normalizeBillingPeriod2(input5.billingPeriod) : void 0
|
|
17514
17559
|
};
|
|
@@ -17536,6 +17581,8 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
|
|
|
17536
17581
|
sku: input5.sku,
|
|
17537
17582
|
displayName: input5.displayName,
|
|
17538
17583
|
priceAmount: input5.priceAmount,
|
|
17584
|
+
pricingModel: input5.pricingModel,
|
|
17585
|
+
priceLabel: input5.priceLabel,
|
|
17539
17586
|
priceCurrency: input5.priceCurrency ?? "usd",
|
|
17540
17587
|
billingPeriod: normalizeBillingPeriod2(input5.billingPeriod),
|
|
17541
17588
|
limitsJson: planLimitsForPlatform(input5),
|
|
@@ -106,6 +106,8 @@ export interface GatewayPlanDto {
|
|
|
106
106
|
displayName: string;
|
|
107
107
|
isActive: boolean;
|
|
108
108
|
priceAmount?: number;
|
|
109
|
+
pricingModel?: "fixed" | "custom";
|
|
110
|
+
priceLabel?: string | null;
|
|
109
111
|
priceCurrency?: string;
|
|
110
112
|
billingPeriod?: string;
|
|
111
113
|
limitsJson?: string | null;
|
|
@@ -120,6 +122,8 @@ export interface CreateGatewayPlanRequest {
|
|
|
120
122
|
limitsJson?: string | null;
|
|
121
123
|
includedActionKeys: string[];
|
|
122
124
|
priceAmount?: number;
|
|
125
|
+
pricingModel?: "fixed" | "custom";
|
|
126
|
+
priceLabel?: string;
|
|
123
127
|
priceCurrency?: string;
|
|
124
128
|
billingPeriod?: string;
|
|
125
129
|
sortOrder?: number;
|
|
@@ -325,6 +329,8 @@ export interface UpdateGatewayPlanRequest {
|
|
|
325
329
|
limitsJson?: string | null;
|
|
326
330
|
includedActionKeys: string[];
|
|
327
331
|
priceAmount?: number;
|
|
332
|
+
pricingModel?: "fixed" | "custom";
|
|
333
|
+
priceLabel?: string;
|
|
328
334
|
priceCurrency?: string;
|
|
329
335
|
billingPeriod?: string;
|
|
330
336
|
sortOrder?: number;
|
|
@@ -7,6 +7,8 @@ export interface ManifestPlanInput {
|
|
|
7
7
|
sku: string;
|
|
8
8
|
displayName: string;
|
|
9
9
|
priceAmount?: number;
|
|
10
|
+
pricingModel?: "fixed" | "custom";
|
|
11
|
+
priceLabel?: string;
|
|
10
12
|
priceCurrency?: string;
|
|
11
13
|
billingPeriod?: "month" | "year" | "monthly" | "annual";
|
|
12
14
|
limits?: GatewayLimits;
|
|
@@ -42,6 +42,8 @@ export declare function handleCreateGatewayPlan(client: PlatformApiClient, confi
|
|
|
42
42
|
limitsJson?: string;
|
|
43
43
|
includedActionKeys?: string[];
|
|
44
44
|
priceAmount?: number;
|
|
45
|
+
pricingModel?: "fixed" | "custom";
|
|
46
|
+
priceLabel?: string;
|
|
45
47
|
priceCurrency?: string;
|
|
46
48
|
billingPeriod?: string;
|
|
47
49
|
sortOrder?: number;
|
|
@@ -59,6 +61,8 @@ export declare function handleUpdateGatewayPlan(client: PlatformApiClient, confi
|
|
|
59
61
|
limitsJson?: string;
|
|
60
62
|
includedActionKeys?: string[];
|
|
61
63
|
priceAmount?: number;
|
|
64
|
+
pricingModel?: "fixed" | "custom";
|
|
65
|
+
priceLabel?: string;
|
|
62
66
|
priceCurrency?: string;
|
|
63
67
|
billingPeriod?: string;
|
|
64
68
|
sortOrder?: number;
|
|
@@ -71,6 +75,8 @@ export declare function handlePatchGatewayPlan(client: PlatformApiClient, config
|
|
|
71
75
|
limitsJson?: string | null;
|
|
72
76
|
includedActionKeys?: string[];
|
|
73
77
|
priceAmount?: number;
|
|
78
|
+
pricingModel?: "fixed" | "custom";
|
|
79
|
+
priceLabel?: string;
|
|
74
80
|
priceCurrency?: string;
|
|
75
81
|
billingPeriod?: string;
|
|
76
82
|
sortOrder?: number;
|
|
@@ -9,11 +9,21 @@ export declare const APITOGO_MANIFEST_ENV_FILES: {
|
|
|
9
9
|
};
|
|
10
10
|
export { APITOGO_CONFIG_FILENAME };
|
|
11
11
|
export type ApitogoManifestEnv = keyof typeof APITOGO_MANIFEST_ENV_FILES;
|
|
12
|
+
export declare const PlanPricingModelSchema: z.ZodEnum<{
|
|
13
|
+
fixed: "fixed";
|
|
14
|
+
custom: "custom";
|
|
15
|
+
}>;
|
|
16
|
+
export type PlanPricingModel = z.infer<typeof PlanPricingModelSchema>;
|
|
12
17
|
export declare const ALLOWED_RUNTIME_VERSIONS: readonly ["DOTNET_10", "DOTNET_9", "DOTNET_8", "NODE_24_LTS", "NODE_22_LTS", "PYTHON_314", "PYTHON_313", "PYTHON_312", "PYTHON_311", "PYTHON_310"];
|
|
13
18
|
export declare const ManifestPlanInputSchema: z.ZodObject<{
|
|
14
19
|
sku: z.ZodString;
|
|
15
20
|
displayName: z.ZodString;
|
|
16
21
|
priceAmount: z.ZodDefault<z.ZodNumber>;
|
|
22
|
+
pricingModel: z.ZodOptional<z.ZodEnum<{
|
|
23
|
+
fixed: "fixed";
|
|
24
|
+
custom: "custom";
|
|
25
|
+
}>>;
|
|
26
|
+
priceLabel: z.ZodOptional<z.ZodString>;
|
|
17
27
|
priceCurrency: z.ZodOptional<z.ZodString>;
|
|
18
28
|
billingPeriod: z.ZodOptional<z.ZodEnum<{
|
|
19
29
|
month: "month";
|
|
@@ -34,6 +44,9 @@ export declare const ManifestPlanInputSchema: z.ZodObject<{
|
|
|
34
44
|
limitsJson: z.ZodOptional<z.ZodString>;
|
|
35
45
|
includedActionKeys: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
36
46
|
}, z.core.$strip>;
|
|
47
|
+
export declare function isPlanCustomPriced(plan: {
|
|
48
|
+
pricingModel?: string | null;
|
|
49
|
+
}): boolean;
|
|
37
50
|
export declare function isPlanFree(plan: {
|
|
38
51
|
priceAmount?: number;
|
|
39
52
|
}): boolean;
|
|
@@ -68,6 +81,11 @@ export declare const DevPortalLocalManifestSchema: z.ZodObject<{
|
|
|
68
81
|
sku: z.ZodString;
|
|
69
82
|
displayName: z.ZodString;
|
|
70
83
|
priceAmount: z.ZodDefault<z.ZodNumber>;
|
|
84
|
+
pricingModel: z.ZodOptional<z.ZodEnum<{
|
|
85
|
+
fixed: "fixed";
|
|
86
|
+
custom: "custom";
|
|
87
|
+
}>>;
|
|
88
|
+
priceLabel: z.ZodOptional<z.ZodString>;
|
|
71
89
|
priceCurrency: z.ZodOptional<z.ZodString>;
|
|
72
90
|
billingPeriod: z.ZodOptional<z.ZodEnum<{
|
|
73
91
|
month: "month";
|
|
@@ -230,6 +248,8 @@ export type DevPortalPreviewPlan = {
|
|
|
230
248
|
sku: string;
|
|
231
249
|
displayName: string;
|
|
232
250
|
priceAmount: number;
|
|
251
|
+
pricingModel: PlanPricingModel;
|
|
252
|
+
priceLabel?: string;
|
|
233
253
|
priceCurrency: string;
|
|
234
254
|
billingPeriod: string;
|
|
235
255
|
limits: GatewayLimits | null;
|
|
@@ -388,6 +388,11 @@ declare const PlanCatalogItemSchema: z.ZodObject<{
|
|
|
388
388
|
sku: z.ZodString;
|
|
389
389
|
displayName: z.ZodString;
|
|
390
390
|
priceAmount: z.ZodDefault<z.ZodNumber>;
|
|
391
|
+
pricingModel: z.ZodOptional<z.ZodEnum<{
|
|
392
|
+
fixed: "fixed";
|
|
393
|
+
custom: "custom";
|
|
394
|
+
}>>;
|
|
395
|
+
priceLabel: z.ZodOptional<z.ZodString>;
|
|
391
396
|
priceCurrency: z.ZodOptional<z.ZodString>;
|
|
392
397
|
billingPeriod: z.ZodOptional<z.ZodString>;
|
|
393
398
|
limits: z.ZodOptional<z.ZodObject<{
|
|
@@ -421,6 +426,11 @@ export declare const PlansModuleSchema: z.ZodObject<{
|
|
|
421
426
|
sku: z.ZodString;
|
|
422
427
|
displayName: z.ZodString;
|
|
423
428
|
priceAmount: z.ZodDefault<z.ZodNumber>;
|
|
429
|
+
pricingModel: z.ZodOptional<z.ZodEnum<{
|
|
430
|
+
fixed: "fixed";
|
|
431
|
+
custom: "custom";
|
|
432
|
+
}>>;
|
|
433
|
+
priceLabel: z.ZodOptional<z.ZodString>;
|
|
424
434
|
priceCurrency: z.ZodOptional<z.ZodString>;
|
|
425
435
|
billingPeriod: z.ZodOptional<z.ZodString>;
|
|
426
436
|
limits: z.ZodOptional<z.ZodObject<{
|
|
@@ -507,6 +517,11 @@ export declare const UserPanelModuleSchema: z.ZodObject<{
|
|
|
507
517
|
sku: z.ZodString;
|
|
508
518
|
displayName: z.ZodString;
|
|
509
519
|
priceAmount: z.ZodDefault<z.ZodNumber>;
|
|
520
|
+
pricingModel: z.ZodOptional<z.ZodEnum<{
|
|
521
|
+
fixed: "fixed";
|
|
522
|
+
custom: "custom";
|
|
523
|
+
}>>;
|
|
524
|
+
priceLabel: z.ZodOptional<z.ZodString>;
|
|
510
525
|
priceCurrency: z.ZodOptional<z.ZodString>;
|
|
511
526
|
billingPeriod: z.ZodOptional<z.ZodString>;
|
|
512
527
|
limits: z.ZodOptional<z.ZodObject<{
|
|
@@ -705,6 +720,11 @@ export declare const ModulesSchema: z.ZodOptional<z.ZodObject<{
|
|
|
705
720
|
sku: z.ZodString;
|
|
706
721
|
displayName: z.ZodString;
|
|
707
722
|
priceAmount: z.ZodDefault<z.ZodNumber>;
|
|
723
|
+
pricingModel: z.ZodOptional<z.ZodEnum<{
|
|
724
|
+
fixed: "fixed";
|
|
725
|
+
custom: "custom";
|
|
726
|
+
}>>;
|
|
727
|
+
priceLabel: z.ZodOptional<z.ZodString>;
|
|
708
728
|
priceCurrency: z.ZodOptional<z.ZodString>;
|
|
709
729
|
billingPeriod: z.ZodOptional<z.ZodString>;
|
|
710
730
|
limits: z.ZodOptional<z.ZodObject<{
|
|
@@ -7039,6 +7039,11 @@ export declare const ZudokuConfig: z.ZodObject<{
|
|
|
7039
7039
|
sku: z.ZodString;
|
|
7040
7040
|
displayName: z.ZodString;
|
|
7041
7041
|
priceAmount: z.ZodDefault<z.ZodNumber>;
|
|
7042
|
+
pricingModel: z.ZodOptional<z.ZodEnum<{
|
|
7043
|
+
fixed: "fixed";
|
|
7044
|
+
custom: "custom";
|
|
7045
|
+
}>>;
|
|
7046
|
+
priceLabel: z.ZodOptional<z.ZodString>;
|
|
7042
7047
|
priceCurrency: z.ZodOptional<z.ZodString>;
|
|
7043
7048
|
billingPeriod: z.ZodOptional<z.ZodString>;
|
|
7044
7049
|
limits: z.ZodOptional<z.ZodObject<{
|
package/dist/flat-config.d.ts
CHANGED
|
@@ -68,6 +68,14 @@ export type _Schema37 = {
|
|
|
68
68
|
sku: string
|
|
69
69
|
displayName: string
|
|
70
70
|
priceAmount?: number
|
|
71
|
+
/**
|
|
72
|
+
* "custom" shows a contact-sales form instead of checkout; priceAmount must be 0.
|
|
73
|
+
*/
|
|
74
|
+
pricingModel?: ("fixed" | "custom")
|
|
75
|
+
/**
|
|
76
|
+
* Text shown instead of the price, e.g. "Custom".
|
|
77
|
+
*/
|
|
78
|
+
priceLabel?: string
|
|
71
79
|
priceCurrency?: string
|
|
72
80
|
billingPeriod?: string
|
|
73
81
|
limits?: {
|
|
@@ -86,31 +94,31 @@ export type _Schema37 = {
|
|
|
86
94
|
limitsJson?: string
|
|
87
95
|
includedActionKeys?: string[]
|
|
88
96
|
}[]
|
|
89
|
-
export type
|
|
97
|
+
export type _Schema40 = ({
|
|
90
98
|
type: "url"
|
|
91
|
-
input: (string |
|
|
92
|
-
server?:
|
|
93
|
-
path?:
|
|
94
|
-
categories?:
|
|
95
|
-
options?:
|
|
99
|
+
input: (string | _Schema41[])
|
|
100
|
+
server?: _Schema42
|
|
101
|
+
path?: _Schema43
|
|
102
|
+
categories?: _Schema44
|
|
103
|
+
options?: _Schema46
|
|
96
104
|
} | {
|
|
97
105
|
type: "file"
|
|
98
|
-
input: (string | (string |
|
|
99
|
-
server?:
|
|
100
|
-
path?:
|
|
101
|
-
categories?:
|
|
102
|
-
options?:
|
|
106
|
+
input: (string | (string | _Schema41)[])
|
|
107
|
+
server?: _Schema42
|
|
108
|
+
path?: _Schema43
|
|
109
|
+
categories?: _Schema44
|
|
110
|
+
options?: _Schema46
|
|
103
111
|
} | {
|
|
104
112
|
type: "raw"
|
|
105
113
|
input: string
|
|
106
|
-
server?:
|
|
107
|
-
path?:
|
|
108
|
-
categories?:
|
|
109
|
-
options?:
|
|
114
|
+
server?: _Schema42
|
|
115
|
+
path?: _Schema43
|
|
116
|
+
categories?: _Schema44
|
|
117
|
+
options?: _Schema46
|
|
110
118
|
})
|
|
111
|
-
export type
|
|
112
|
-
export type
|
|
113
|
-
export type
|
|
119
|
+
export type _Schema42 = string
|
|
120
|
+
export type _Schema43 = string
|
|
121
|
+
export type _Schema44 = {
|
|
114
122
|
label: string
|
|
115
123
|
tags: string[]
|
|
116
124
|
}[]
|
|
@@ -412,8 +420,8 @@ export interface FlatZudokuConfig {
|
|
|
412
420
|
landing?: _Schema16
|
|
413
421
|
userPanel?: _Schema25
|
|
414
422
|
}
|
|
415
|
-
apis?: (
|
|
416
|
-
catalogs?: (
|
|
423
|
+
apis?: (_Schema40 | _Schema40[])
|
|
424
|
+
catalogs?: (_Schema47 | _Schema47[])
|
|
417
425
|
apiKeys?: {
|
|
418
426
|
enabled: boolean
|
|
419
427
|
getConsumers?: unknown
|
|
@@ -441,7 +449,7 @@ export interface FlatZudokuConfig {
|
|
|
441
449
|
}
|
|
442
450
|
enableStatusPages?: boolean
|
|
443
451
|
defaults?: {
|
|
444
|
-
apis:
|
|
452
|
+
apis: _Schema46
|
|
445
453
|
examplesLanguage?: string
|
|
446
454
|
}
|
|
447
455
|
__pluginDirs?: string[]
|
|
@@ -731,12 +739,12 @@ export interface _Schema36 {
|
|
|
731
739
|
description?: string
|
|
732
740
|
}[]
|
|
733
741
|
}
|
|
734
|
-
export interface
|
|
742
|
+
export interface _Schema41 {
|
|
735
743
|
path: string
|
|
736
744
|
input: string
|
|
737
745
|
label?: string
|
|
738
746
|
}
|
|
739
|
-
export interface
|
|
747
|
+
export interface _Schema46 {
|
|
740
748
|
examplesLanguage?: string
|
|
741
749
|
supportedLanguages?: {
|
|
742
750
|
value: string
|
|
@@ -753,7 +761,7 @@ export interface _Schema44 {
|
|
|
753
761
|
transformExamples?: unknown
|
|
754
762
|
generateCodeSnippet?: unknown
|
|
755
763
|
}
|
|
756
|
-
export interface
|
|
764
|
+
export interface _Schema47 {
|
|
757
765
|
path: string
|
|
758
766
|
label: string
|
|
759
767
|
items?: string[]
|
|
@@ -67,6 +67,10 @@ npx apitogo config
|
|
|
67
67
|
- **`sku`** — stable identifier (used in checkout URLs and gateway sync).
|
|
68
68
|
- **`displayName`** — label on `/pricing`.
|
|
69
69
|
- **`priceAmount`** — `0` for free tiers; greater than zero for paid plans (USD by default).
|
|
70
|
+
- **`pricingModel`** — `fixed` (default) or `custom`. See
|
|
71
|
+
[Custom pricing](#custom-pricing-contact-sales).
|
|
72
|
+
- **`priceLabel`** — optional text shown instead of the price, such as `"Let's talk"` (max 64
|
|
73
|
+
characters).
|
|
70
74
|
- **`limits`** — rate limit and quota policies (see below). Encoded `limitsJson` strings are still
|
|
71
75
|
accepted on load.
|
|
72
76
|
|
|
@@ -90,6 +94,28 @@ OpenAPI is deployed, you can scope a plan to specific operations with `includedA
|
|
|
90
94
|
example `get:/orders/{id}`). Edit those fields in `apitogo.config.json` — see
|
|
91
95
|
[Manifest](./manifest.md).
|
|
92
96
|
|
|
97
|
+
## Custom pricing (contact sales)
|
|
98
|
+
|
|
99
|
+
Set `pricingModel: "custom"` for plans with negotiated prices, such as an Enterprise tier. Leave
|
|
100
|
+
`priceAmount` at `0` or omit it.
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"sku": "enterprise",
|
|
105
|
+
"displayName": "Enterprise",
|
|
106
|
+
"pricingModel": "custom",
|
|
107
|
+
"priceLabel": "Let's talk"
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
On `/pricing`, custom plans show `priceLabel` (or **Custom**) and a **Contact sales** button. The
|
|
112
|
+
button opens a public `/contact-sales` form instead of Stripe checkout or registration. Visitors
|
|
113
|
+
don't need an account.
|
|
114
|
+
|
|
115
|
+
Each submission is emailed to the project's **sales contact email**, or to the project owner's email
|
|
116
|
+
when none is set. Custom plans can't be subscribed to through checkout. Custom plans are available
|
|
117
|
+
on every platform plan, including Free.
|
|
118
|
+
|
|
93
119
|
## Publish
|
|
94
120
|
|
|
95
121
|
Gateway plans are applied when you run:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lukoweb/apitogo",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.127",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"**/*.css",
|
|
@@ -167,6 +167,16 @@
|
|
|
167
167
|
"default": "./src/cli/platform/apply/index.ts"
|
|
168
168
|
}
|
|
169
169
|
},
|
|
170
|
+
"scripts": {
|
|
171
|
+
"build": "esbuild src/cli/cli.ts src/vite/prerender/worker.ts --outdir=dist/cli --entry-names=[name] --bundle --format=esm --packages=external --target=node20 --platform=node --log-level=error",
|
|
172
|
+
"postbuild": "tsx scripts/check-external-deps.ts",
|
|
173
|
+
"typecheck": "tsc --project tsconfig.app.json --noEmit",
|
|
174
|
+
"generate:types": "tsx scripts/generate-types.js && tsx scripts/generate-flat-config.js",
|
|
175
|
+
"build:standalone": "vite build --mode standalone --config vite.standalone.config.ts --log-level=error",
|
|
176
|
+
"prepack": "npm run build && tsx scripts/generate-publish-exports.ts",
|
|
177
|
+
"clean": "rm -rf dist",
|
|
178
|
+
"codegen": "graphql-codegen --config ./src/codegen.ts"
|
|
179
|
+
},
|
|
170
180
|
"dependencies": {
|
|
171
181
|
"@apidevtools/json-schema-ref-parser": "15.3.1",
|
|
172
182
|
"@apidevtools/swagger-parser": "^12.1.0",
|
|
@@ -346,13 +356,148 @@
|
|
|
346
356
|
"optional": true
|
|
347
357
|
}
|
|
348
358
|
},
|
|
349
|
-
"
|
|
350
|
-
"
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
359
|
+
"publishConfig": {
|
|
360
|
+
"exports": {
|
|
361
|
+
".": {
|
|
362
|
+
"types": "./dist/declarations/index.d.ts",
|
|
363
|
+
"default": "./src/index.ts"
|
|
364
|
+
},
|
|
365
|
+
"./package.json": "./package.json",
|
|
366
|
+
"./ui/*": {
|
|
367
|
+
"types": "./dist/declarations/lib/ui/*.d.ts",
|
|
368
|
+
"default": "./src/lib/ui/*.tsx"
|
|
369
|
+
},
|
|
370
|
+
"./ui/*.js": {
|
|
371
|
+
"types": "./dist/declarations/lib/ui/*.d.ts",
|
|
372
|
+
"default": "./src/lib/ui/*.tsx"
|
|
373
|
+
},
|
|
374
|
+
"./client": {
|
|
375
|
+
"types": "./client.d.ts"
|
|
376
|
+
},
|
|
377
|
+
"./auth/clerk": {
|
|
378
|
+
"types": "./dist/declarations/lib/authentication/providers/clerk.d.ts",
|
|
379
|
+
"default": "./src/lib/authentication/providers/clerk.tsx"
|
|
380
|
+
},
|
|
381
|
+
"./auth/auth0": {
|
|
382
|
+
"types": "./dist/declarations/lib/authentication/providers/auth0.d.ts",
|
|
383
|
+
"default": "./src/lib/authentication/providers/auth0.tsx"
|
|
384
|
+
},
|
|
385
|
+
"./auth/openid": {
|
|
386
|
+
"types": "./dist/declarations/lib/authentication/providers/openid.d.ts",
|
|
387
|
+
"default": "./src/lib/authentication/providers/openid.tsx"
|
|
388
|
+
},
|
|
389
|
+
"./auth/supabase": {
|
|
390
|
+
"types": "./dist/declarations/lib/authentication/providers/supabase.d.ts",
|
|
391
|
+
"default": "./src/lib/authentication/providers/supabase.tsx"
|
|
392
|
+
},
|
|
393
|
+
"./auth/azureb2c": {
|
|
394
|
+
"types": "./dist/declarations/lib/authentication/providers/azureb2c.d.ts",
|
|
395
|
+
"default": "./src/lib/authentication/providers/azureb2c.tsx"
|
|
396
|
+
},
|
|
397
|
+
"./auth/firebase": {
|
|
398
|
+
"types": "./dist/declarations/lib/authentication/providers/firebase.d.ts",
|
|
399
|
+
"default": "./src/lib/authentication/providers/firebase.tsx"
|
|
400
|
+
},
|
|
401
|
+
"./auth/dev-portal": {
|
|
402
|
+
"types": "./dist/declarations/lib/authentication/providers/dev-portal.d.ts",
|
|
403
|
+
"default": "./src/lib/authentication/providers/dev-portal.tsx"
|
|
404
|
+
},
|
|
405
|
+
"./plugins": {
|
|
406
|
+
"types": "./dist/declarations/lib/core/plugins.d.ts",
|
|
407
|
+
"default": "./src/lib/core/plugins.ts"
|
|
408
|
+
},
|
|
409
|
+
"./plugins/api-keys": {
|
|
410
|
+
"types": "./dist/declarations/lib/plugins/api-keys/index.d.ts",
|
|
411
|
+
"default": "./src/lib/plugins/api-keys/index.tsx"
|
|
412
|
+
},
|
|
413
|
+
"./plugins/markdown": {
|
|
414
|
+
"types": "./dist/declarations/lib/plugins/markdown/index.d.ts",
|
|
415
|
+
"default": "./src/lib/plugins/markdown/index.tsx"
|
|
416
|
+
},
|
|
417
|
+
"./plugins/openapi": {
|
|
418
|
+
"types": "./dist/declarations/lib/plugins/openapi/index.d.ts",
|
|
419
|
+
"default": "./src/lib/plugins/openapi/index.tsx"
|
|
420
|
+
},
|
|
421
|
+
"./plugins/custom-pages": {
|
|
422
|
+
"types": "./dist/declarations/lib/plugins/custom-pages/index.d.ts",
|
|
423
|
+
"default": "./src/lib/plugins/custom-pages/index.tsx"
|
|
424
|
+
},
|
|
425
|
+
"./plugins/search-inkeep": {
|
|
426
|
+
"types": "./dist/declarations/lib/plugins/search-inkeep/index.d.ts",
|
|
427
|
+
"default": "./src/lib/plugins/search-inkeep/index.tsx"
|
|
428
|
+
},
|
|
429
|
+
"./plugins/search-pagefind": {
|
|
430
|
+
"types": "./dist/declarations/lib/plugins/search-pagefind/index.d.ts",
|
|
431
|
+
"default": "./src/lib/plugins/search-pagefind/index.tsx"
|
|
432
|
+
},
|
|
433
|
+
"./plugins/api-catalog": {
|
|
434
|
+
"types": "./dist/declarations/lib/plugins/api-catalog/index.d.ts",
|
|
435
|
+
"default": "./src/lib/plugins/api-catalog/index.tsx"
|
|
436
|
+
},
|
|
437
|
+
"./modules/landing": "@lukoweb/apitogo-module-landing",
|
|
438
|
+
"./modules/user-panel": "@lukoweb/apitogo-module-user-panel",
|
|
439
|
+
"./components": {
|
|
440
|
+
"types": "./dist/declarations/lib/components/index.d.ts",
|
|
441
|
+
"default": "./src/lib/components/index.ts"
|
|
442
|
+
},
|
|
443
|
+
"./mermaid": {
|
|
444
|
+
"types": "./dist/declarations/lib/components/Mermaid.d.ts",
|
|
445
|
+
"default": "./src/lib/components/Mermaid.tsx"
|
|
446
|
+
},
|
|
447
|
+
"./router": {
|
|
448
|
+
"types": "./dist/declarations/lib/core/router.d.ts",
|
|
449
|
+
"default": "./src/lib/core/router.ts"
|
|
450
|
+
},
|
|
451
|
+
"./react-query": {
|
|
452
|
+
"types": "./dist/declarations/lib/core/react-query.d.ts",
|
|
453
|
+
"default": "./src/lib/core/react-query.ts"
|
|
454
|
+
},
|
|
455
|
+
"./icons": {
|
|
456
|
+
"types": "./dist/declarations/lib/icons.d.ts",
|
|
457
|
+
"default": "./src/lib/icons.ts"
|
|
458
|
+
},
|
|
459
|
+
"./vite": {
|
|
460
|
+
"types": "./dist/declarations/vite/index.d.ts",
|
|
461
|
+
"default": "./src/vite/index.ts"
|
|
462
|
+
},
|
|
463
|
+
"./app/*": {
|
|
464
|
+
"types": "./dist/declarations/app/*.d.ts",
|
|
465
|
+
"default": "./src/app/*"
|
|
466
|
+
},
|
|
467
|
+
"./hooks": {
|
|
468
|
+
"types": "./dist/declarations/lib/hooks/index.d.ts",
|
|
469
|
+
"default": "./src/lib/hooks/index.ts"
|
|
470
|
+
},
|
|
471
|
+
"./main.css": "./src/app/main.css",
|
|
472
|
+
"./processors/*": {
|
|
473
|
+
"types": "./dist/declarations/lib/plugins/openapi/processors/*.d.ts",
|
|
474
|
+
"default": "./src/lib/plugins/openapi/processors/*.ts"
|
|
475
|
+
},
|
|
476
|
+
"./with-zuplo": {
|
|
477
|
+
"types": "./dist/declarations/zuplo/with-zuplo.d.ts",
|
|
478
|
+
"default": "./src/zuplo/with-zuplo.ts"
|
|
479
|
+
},
|
|
480
|
+
"./testing": {
|
|
481
|
+
"types": "./dist/declarations/lib/testing/index.d.ts",
|
|
482
|
+
"default": "./src/lib/testing/index.tsx"
|
|
483
|
+
},
|
|
484
|
+
"./local-manifest": {
|
|
485
|
+
"types": "./dist/declarations/config/local-manifest.d.ts",
|
|
486
|
+
"default": "./src/config/local-manifest.ts"
|
|
487
|
+
},
|
|
488
|
+
"./build-config": {
|
|
489
|
+
"types": "./dist/declarations/config/build-apitogo-config.d.ts",
|
|
490
|
+
"default": "./src/config/build-apitogo-config.ts"
|
|
491
|
+
},
|
|
492
|
+
"./config-loader": {
|
|
493
|
+
"types": "./dist/declarations/config/apitogo-config-loader.d.ts",
|
|
494
|
+
"default": "./src/config/apitogo-config-loader.ts"
|
|
495
|
+
},
|
|
496
|
+
"./apply": {
|
|
497
|
+
"types": "./dist/declarations/cli/platform/apply/index.d.ts",
|
|
498
|
+
"default": "./src/cli/platform/apply/index.ts"
|
|
499
|
+
}
|
|
500
|
+
},
|
|
501
|
+
"access": "public"
|
|
357
502
|
}
|
|
358
|
-
}
|
|
503
|
+
}
|
|
@@ -106,6 +106,8 @@ const COLLAPSED_UPPERCASE_ALIASES: Record<string, string> = {
|
|
|
106
106
|
DEMOMODE: "demoMode",
|
|
107
107
|
DISPLAYNAME: "displayName",
|
|
108
108
|
PRICEAMOUNT: "priceAmount",
|
|
109
|
+
PRICINGMODEL: "pricingModel",
|
|
110
|
+
PRICELABEL: "priceLabel",
|
|
109
111
|
PRICECURRENCY: "priceCurrency",
|
|
110
112
|
BILLINGPERIOD: "billingPeriod",
|
|
111
113
|
LIMITSJSON: "limitsJson",
|
|
@@ -36,6 +36,10 @@ export type ApitogoManifestEnv = keyof typeof APITOGO_MANIFEST_ENV_FILES;
|
|
|
36
36
|
|
|
37
37
|
const BillingPeriodSchema = z.enum(["month", "year", "monthly", "annual"]);
|
|
38
38
|
|
|
39
|
+
export const PlanPricingModelSchema = z.enum(["fixed", "custom"]);
|
|
40
|
+
|
|
41
|
+
export type PlanPricingModel = z.infer<typeof PlanPricingModelSchema>;
|
|
42
|
+
|
|
39
43
|
const GatewayLimitsSchema = z
|
|
40
44
|
.object({
|
|
41
45
|
rateLimit: z
|
|
@@ -81,6 +85,9 @@ export const ManifestPlanInputSchema = z.object({
|
|
|
81
85
|
sku: z.string().min(1),
|
|
82
86
|
displayName: z.string().min(1),
|
|
83
87
|
priceAmount: z.number().default(0),
|
|
88
|
+
/** `custom` plans show a contact-sales form instead of checkout. */
|
|
89
|
+
pricingModel: PlanPricingModelSchema.optional(),
|
|
90
|
+
priceLabel: z.string().max(64).optional(),
|
|
84
91
|
priceCurrency: PriceCurrencySchema.optional(),
|
|
85
92
|
billingPeriod: BillingPeriodSchema.optional(),
|
|
86
93
|
limits: GatewayLimitsSchema.optional(),
|
|
@@ -89,6 +96,12 @@ export const ManifestPlanInputSchema = z.object({
|
|
|
89
96
|
includedActionKeys: z.array(z.string()).optional(),
|
|
90
97
|
});
|
|
91
98
|
|
|
99
|
+
export function isPlanCustomPriced(plan: {
|
|
100
|
+
pricingModel?: string | null;
|
|
101
|
+
}): boolean {
|
|
102
|
+
return plan.pricingModel === "custom";
|
|
103
|
+
}
|
|
104
|
+
|
|
92
105
|
/** Free plans have zero price; paid plans have priceAmount greater than zero. */
|
|
93
106
|
export function isPlanFree(plan: { priceAmount?: number }): boolean {
|
|
94
107
|
return (plan.priceAmount ?? 0) <= 0;
|
|
@@ -198,6 +211,8 @@ export type DevPortalPreviewPlan = {
|
|
|
198
211
|
sku: string;
|
|
199
212
|
displayName: string;
|
|
200
213
|
priceAmount: number;
|
|
214
|
+
pricingModel: PlanPricingModel;
|
|
215
|
+
priceLabel?: string;
|
|
201
216
|
priceCurrency: string;
|
|
202
217
|
billingPeriod: string;
|
|
203
218
|
limits: GatewayLimits | null;
|
|
@@ -272,6 +287,8 @@ export function plansToPreviewCatalog(
|
|
|
272
287
|
sku: plan.sku,
|
|
273
288
|
displayName: plan.displayName,
|
|
274
289
|
priceAmount: plan.priceAmount ?? 0,
|
|
290
|
+
pricingModel: plan.pricingModel ?? "fixed",
|
|
291
|
+
...(plan.priceLabel ? { priceLabel: plan.priceLabel } : {}),
|
|
275
292
|
priceCurrency: plan.priceCurrency ?? "usd",
|
|
276
293
|
billingPeriod: normalizeBillingPeriod(plan.billingPeriod),
|
|
277
294
|
limits: coerceGatewayLimits(plan) ?? null,
|
|
@@ -264,6 +264,17 @@ const PlanCatalogItemSchema = z.object({
|
|
|
264
264
|
sku: z.string(),
|
|
265
265
|
displayName: z.string(),
|
|
266
266
|
priceAmount: z.number().default(0),
|
|
267
|
+
pricingModel: z
|
|
268
|
+
.enum(["fixed", "custom"])
|
|
269
|
+
.optional()
|
|
270
|
+
.describe(
|
|
271
|
+
'"custom" shows a contact-sales form instead of checkout; priceAmount must be 0.',
|
|
272
|
+
),
|
|
273
|
+
priceLabel: z
|
|
274
|
+
.string()
|
|
275
|
+
.max(64)
|
|
276
|
+
.optional()
|
|
277
|
+
.describe('Text shown instead of the price, e.g. "Custom".'),
|
|
267
278
|
priceCurrency: z
|
|
268
279
|
.string()
|
|
269
280
|
.trim()
|
package/LICENSE.md
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
The MIT License (MIT)
|
|
2
|
-
|
|
3
|
-
Copyright (c) Zuplo, Inc.
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
6
|
-
associated documentation files (the "Software"), to deal in the Software without restriction,
|
|
7
|
-
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
|
8
|
-
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
|
9
|
-
furnished to do so, subject to the following conditions:
|
|
10
|
-
|
|
11
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial
|
|
12
|
-
portions of the Software.
|
|
13
|
-
|
|
14
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
|
15
|
-
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
|
17
|
-
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
18
|
-
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|