@stripe/extensibility-dev-tools 0.23.7 → 0.24.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/dist/bin/build-custom-object-definitions.cjs +56 -21
- package/dist/bin/build-custom-object-definitions.js +56 -21
- package/dist/bin/create-upload-image.cjs +63 -25
- package/dist/bin/create-upload-image.js +63 -25
- package/dist/bin/dev-tools-rpc.cjs +8 -7
- package/dist/bin/dev-tools-rpc.js +8 -7
- package/dist/bin/gen-workspace.cjs +8 -7
- package/dist/bin/gen-workspace.js +8 -7
- package/dist/bin/template-info.cjs +8 -7
- package/dist/bin/template-info.js +8 -7
- package/dist/custom-objects/build-definitions.d.ts.map +1 -1
- package/dist/custom-objects/to-proto-json.d.ts +2 -1
- package/dist/custom-objects/to-proto-json.d.ts.map +1 -1
- package/dist/dependencies/index.d.ts +7 -7
- package/dist/index.cjs +8 -7
- package/dist/index.js +8 -7
- package/dist/manifest/manifest-v2.d.ts +8 -3
- package/dist/templates/diff-viewer/types.d.ts +2 -2
- package/dist/templates/extensions/base.d.ts +4 -2
- package/dist/templates/extensions/core.workflows.custom_action.d.ts.map +1 -1
- package/dist/templates/extensions/types.d.ts +9 -3
- package/dist/templates/file-writer.d.ts +2 -2
- package/dist/templates/index.cjs +8 -7
- package/dist/templates/index.js +8 -7
- package/dist/templates/root/index.d.ts +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/workspace/index.cjs +8 -7
- package/dist/workspace/index.d.ts +34 -30
- package/dist/workspace/index.js +8 -7
- package/package.json +3 -3
- package/templates/extensions/billing.bill.discount_calculation/index.ts +1 -1
- package/templates/extensions/billing.customer_balance_application/index.ts +1 -1
- package/templates/extensions/billing.invoice_collection_setting/index.ts +1 -1
- package/templates/extensions/billing.prorations/index.ts +1 -1
- package/templates/extensions/billing.recurring_billing_item_handling/index.ts +1 -1
- package/templates/extensions/core.workflows.custom_action/index.ts +1 -1
- package/templates/extensions/extend.workflows.custom_action/index.ts +1 -1
- package/dist/api-surface.d.ts.map +0 -1
|
@@ -328,7 +328,7 @@ describe('MyDiscountCalculation', () => {
|
|
|
328
328
|
content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
|
|
329
329
|
|
|
330
330
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
331
|
-
interface MyDiscountCalculationConfig
|
|
331
|
+
interface MyDiscountCalculationConfig {}
|
|
332
332
|
|
|
333
333
|
export default class MyDiscountCalculation implements Billing.Bill
|
|
334
334
|
.DiscountCalculation<MyDiscountCalculationConfig> {
|
|
@@ -370,7 +370,7 @@ describe('MyBalanceApp', () => {
|
|
|
370
370
|
content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
|
|
371
371
|
|
|
372
372
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
373
|
-
interface MyBalanceAppConfig
|
|
373
|
+
interface MyBalanceAppConfig {}
|
|
374
374
|
|
|
375
375
|
export default class MyBalanceApp implements Billing.CustomerBalanceApplication<MyBalanceAppConfig> {
|
|
376
376
|
computeAppliedCustomerBalance(
|
|
@@ -411,7 +411,7 @@ describe('MyInvoiceCollectionSetting', () => {
|
|
|
411
411
|
content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
|
|
412
412
|
|
|
413
413
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
414
|
-
interface MyInvoiceCollectionSettingConfig
|
|
414
|
+
interface MyInvoiceCollectionSettingConfig {}
|
|
415
415
|
|
|
416
416
|
export default class MyInvoiceCollectionSetting implements Billing.InvoiceCollectionSetting<MyInvoiceCollectionSettingConfig> {
|
|
417
417
|
collectionOverride(
|
|
@@ -450,7 +450,7 @@ describe('MyProrations', () => {
|
|
|
450
450
|
content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
|
|
451
451
|
|
|
452
452
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
453
|
-
interface MyProrationsConfig
|
|
453
|
+
interface MyProrationsConfig {}
|
|
454
454
|
|
|
455
455
|
export default class MyProrations implements Billing.Prorations<MyProrationsConfig> {
|
|
456
456
|
prorateItems(
|
|
@@ -491,7 +491,7 @@ describe('MyRecurringBillingItemHandling', () => {
|
|
|
491
491
|
content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
|
|
492
492
|
|
|
493
493
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
494
|
-
interface MyRecurringBillingItemHandlingConfig
|
|
494
|
+
interface MyRecurringBillingItemHandlingConfig {}
|
|
495
495
|
|
|
496
496
|
export default class MyRecurringBillingItemHandling implements Billing.RecurringBillingItemHandling<MyRecurringBillingItemHandlingConfig> {
|
|
497
497
|
beforeItemCreation(
|
|
@@ -741,7 +741,7 @@ describe('MyCustomAction', () => {
|
|
|
741
741
|
content: `import type { Core, Context } from '@stripe/extensibility-sdk';
|
|
742
742
|
|
|
743
743
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
744
|
-
interface MyCustomActionConfig
|
|
744
|
+
interface MyCustomActionConfig {}
|
|
745
745
|
|
|
746
746
|
export default class MyCustomAction implements Core.Workflows
|
|
747
747
|
.CustomAction<MyCustomActionConfig> {
|
|
@@ -804,7 +804,7 @@ describe('MyCustomAction', () => {
|
|
|
804
804
|
content: `import type { Extend, Context } from '@stripe/extensibility-sdk';
|
|
805
805
|
|
|
806
806
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
807
|
-
interface MyCustomActionConfig
|
|
807
|
+
interface MyCustomActionConfig {}
|
|
808
808
|
|
|
809
809
|
export default class MyCustomAction implements Extend.Workflows
|
|
810
810
|
.CustomAction<MyCustomActionConfig> {
|
|
@@ -1328,6 +1328,7 @@ function _createBaseOutput(params, context) {
|
|
|
1328
1328
|
// src/templates/extensions/core.workflows.custom_action.ts
|
|
1329
1329
|
var EXTENSION_INTERFACE_ID = "core.workflows.custom_action";
|
|
1330
1330
|
var customActionTemplate = {
|
|
1331
|
+
deprecated: true,
|
|
1331
1332
|
methods: {
|
|
1332
1333
|
execute: { implementation_types: ["script", "remote-function"] },
|
|
1333
1334
|
get_form_state: { implementation_types: ["script", "remote-function"] }
|
|
@@ -1784,10 +1785,11 @@ function mapActions(actions) {
|
|
|
1784
1785
|
}
|
|
1785
1786
|
function mapProperties(schema) {
|
|
1786
1787
|
const result = {};
|
|
1787
|
-
const
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1788
|
+
const resolvedSchema = schema === null || schema === void 0 ? schema : resolveRef(schema, schema.$defs ?? {});
|
|
1789
|
+
const requiredSet = new Set(resolvedSchema?.required ?? []);
|
|
1790
|
+
if (!resolvedSchema?.properties) return result;
|
|
1791
|
+
const defs = resolvedSchema.$defs ?? {};
|
|
1792
|
+
for (const [key, propSchema] of Object.entries(resolvedSchema.properties)) {
|
|
1791
1793
|
result[key] = toFieldSchema(resolveRef(propSchema, defs), requiredSet.has(key));
|
|
1792
1794
|
}
|
|
1793
1795
|
return result;
|
|
@@ -1831,7 +1833,13 @@ function toFieldSchema(schema, required) {
|
|
|
1831
1833
|
fieldSchema.valuesPresence = FieldPresence.PRESENT;
|
|
1832
1834
|
}
|
|
1833
1835
|
if (schema.default !== void 0) {
|
|
1834
|
-
|
|
1836
|
+
if (dataType === DataType.ENUM_TYPE && enumValues) {
|
|
1837
|
+
validateEnumDefault(schema.default, enumValues);
|
|
1838
|
+
}
|
|
1839
|
+
if (dataType === DataType.DATETIME_TYPE) {
|
|
1840
|
+
validateDatetimeDefault(schema.default);
|
|
1841
|
+
}
|
|
1842
|
+
fieldSchema.default = toDefaultValue(schema.default, dataType);
|
|
1835
1843
|
}
|
|
1836
1844
|
return fieldSchema;
|
|
1837
1845
|
}
|
|
@@ -1843,7 +1851,6 @@ function resolveDataType(schema, enumValues, refTarget) {
|
|
|
1843
1851
|
if (schema.format === "date-time") return DataType.DATETIME_TYPE;
|
|
1844
1852
|
return DataType.STRING_TYPE;
|
|
1845
1853
|
case "integer":
|
|
1846
|
-
case "number":
|
|
1847
1854
|
return DataType.INTEGER_TYPE;
|
|
1848
1855
|
case "boolean":
|
|
1849
1856
|
return DataType.BOOLEAN_TYPE;
|
|
@@ -1880,33 +1887,61 @@ function extractSingleLiteral(schema) {
|
|
|
1880
1887
|
return null;
|
|
1881
1888
|
}
|
|
1882
1889
|
function extractEnumValues(schema) {
|
|
1883
|
-
if (schema.enum) {
|
|
1890
|
+
if (Array.isArray(schema.enum) && schema.enum.every((value) => typeof value === "string")) {
|
|
1884
1891
|
return schema.enum.map(String);
|
|
1885
1892
|
}
|
|
1886
|
-
if (Array.isArray(schema.oneOf) && schema.oneOf.length > 0 && schema.oneOf.every(
|
|
1893
|
+
if (Array.isArray(schema.oneOf) && schema.oneOf.length > 0 && schema.oneOf.every(
|
|
1894
|
+
(item) => "const" in item && typeof item.const === "string"
|
|
1895
|
+
)) {
|
|
1887
1896
|
return schema.oneOf.map((item) => String(item.const));
|
|
1888
1897
|
}
|
|
1889
1898
|
return null;
|
|
1890
1899
|
}
|
|
1900
|
+
function validateEnumDefault(value, enumValues) {
|
|
1901
|
+
if (typeof value !== "string" || !enumValues.includes(value)) {
|
|
1902
|
+
throw new Error(
|
|
1903
|
+
`Default value ${JSON.stringify(value)} is not a valid enum value. Expected one of: ${enumValues.join(", ")}`
|
|
1904
|
+
);
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
var DATETIME_UTC_MS_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}(Z|\+00:00)$/;
|
|
1908
|
+
function validateDatetimeDefault(value) {
|
|
1909
|
+
if (typeof value !== "string" || !DATETIME_UTC_MS_RE.test(value)) {
|
|
1910
|
+
throw new Error(
|
|
1911
|
+
`Default value ${JSON.stringify(value)} is not a valid ISO 8601 UTC datetime with millisecond precision. Expected format: YYYY-MM-DDTHH:mm:ss.sssZ or YYYY-MM-DDTHH:mm:ss.sss+00:00`
|
|
1912
|
+
);
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1891
1915
|
function toValueBoundary(value) {
|
|
1892
1916
|
if (!Number.isInteger(value)) {
|
|
1893
1917
|
throw new Error(
|
|
1894
1918
|
`ValueBoundary only supports integers, got ${String(value)}. Custom object numeric fields are integer-only.`
|
|
1895
1919
|
);
|
|
1896
1920
|
}
|
|
1897
|
-
return {
|
|
1921
|
+
return { integerBoundary: value };
|
|
1898
1922
|
}
|
|
1899
1923
|
function toDefaultValue(value, dataType) {
|
|
1900
1924
|
if (dataType === DataType.STRING_TYPE && typeof value === "string") {
|
|
1901
|
-
return {
|
|
1925
|
+
return { stringDefault: value };
|
|
1926
|
+
}
|
|
1927
|
+
if (dataType === DataType.ENUM_TYPE && typeof value === "string") {
|
|
1928
|
+
return { stringDefault: value };
|
|
1929
|
+
}
|
|
1930
|
+
if (dataType === DataType.DATETIME_TYPE && typeof value === "string") {
|
|
1931
|
+
return { stringDefault: value };
|
|
1902
1932
|
}
|
|
1903
1933
|
if (dataType === DataType.INTEGER_TYPE && typeof value === "number") {
|
|
1904
|
-
|
|
1934
|
+
if (!Number.isInteger(value)) {
|
|
1935
|
+
throw new Error(
|
|
1936
|
+
`Integer default values must be whole numbers, got ${JSON.stringify(value)}.`
|
|
1937
|
+
);
|
|
1938
|
+
}
|
|
1939
|
+
return { integerDefault: value };
|
|
1905
1940
|
}
|
|
1906
1941
|
if (dataType === DataType.BOOLEAN_TYPE && typeof value === "boolean") {
|
|
1907
|
-
return {
|
|
1942
|
+
return { booleanDefault: value };
|
|
1908
1943
|
}
|
|
1909
|
-
return {
|
|
1944
|
+
return {};
|
|
1910
1945
|
}
|
|
1911
1946
|
|
|
1912
1947
|
// src/custom-objects/build-definitions.ts
|
|
@@ -1936,7 +1971,7 @@ async function analyzeAndInjectManifest(options) {
|
|
|
1936
1971
|
(diagnostic) => diagnostic.severity === "error"
|
|
1937
1972
|
);
|
|
1938
1973
|
if (errorDiagnostics.length > 0) {
|
|
1939
|
-
const details = errorDiagnostics.map((diagnostic) => diagnostic.message).join("
|
|
1974
|
+
const details = errorDiagnostics.map((diagnostic) => diagnostic.message).join("\n");
|
|
1940
1975
|
throw new Error(details);
|
|
1941
1976
|
}
|
|
1942
1977
|
const coPackageJsonPath = path2.join(projectRoot, "custom-objects", "package.json");
|
|
@@ -305,7 +305,7 @@ describe('MyDiscountCalculation', () => {
|
|
|
305
305
|
content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
|
|
306
306
|
|
|
307
307
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
308
|
-
interface MyDiscountCalculationConfig
|
|
308
|
+
interface MyDiscountCalculationConfig {}
|
|
309
309
|
|
|
310
310
|
export default class MyDiscountCalculation implements Billing.Bill
|
|
311
311
|
.DiscountCalculation<MyDiscountCalculationConfig> {
|
|
@@ -347,7 +347,7 @@ describe('MyBalanceApp', () => {
|
|
|
347
347
|
content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
|
|
348
348
|
|
|
349
349
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
350
|
-
interface MyBalanceAppConfig
|
|
350
|
+
interface MyBalanceAppConfig {}
|
|
351
351
|
|
|
352
352
|
export default class MyBalanceApp implements Billing.CustomerBalanceApplication<MyBalanceAppConfig> {
|
|
353
353
|
computeAppliedCustomerBalance(
|
|
@@ -388,7 +388,7 @@ describe('MyInvoiceCollectionSetting', () => {
|
|
|
388
388
|
content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
|
|
389
389
|
|
|
390
390
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
391
|
-
interface MyInvoiceCollectionSettingConfig
|
|
391
|
+
interface MyInvoiceCollectionSettingConfig {}
|
|
392
392
|
|
|
393
393
|
export default class MyInvoiceCollectionSetting implements Billing.InvoiceCollectionSetting<MyInvoiceCollectionSettingConfig> {
|
|
394
394
|
collectionOverride(
|
|
@@ -427,7 +427,7 @@ describe('MyProrations', () => {
|
|
|
427
427
|
content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
|
|
428
428
|
|
|
429
429
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
430
|
-
interface MyProrationsConfig
|
|
430
|
+
interface MyProrationsConfig {}
|
|
431
431
|
|
|
432
432
|
export default class MyProrations implements Billing.Prorations<MyProrationsConfig> {
|
|
433
433
|
prorateItems(
|
|
@@ -468,7 +468,7 @@ describe('MyRecurringBillingItemHandling', () => {
|
|
|
468
468
|
content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
|
|
469
469
|
|
|
470
470
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
471
|
-
interface MyRecurringBillingItemHandlingConfig
|
|
471
|
+
interface MyRecurringBillingItemHandlingConfig {}
|
|
472
472
|
|
|
473
473
|
export default class MyRecurringBillingItemHandling implements Billing.RecurringBillingItemHandling<MyRecurringBillingItemHandlingConfig> {
|
|
474
474
|
beforeItemCreation(
|
|
@@ -718,7 +718,7 @@ describe('MyCustomAction', () => {
|
|
|
718
718
|
content: `import type { Core, Context } from '@stripe/extensibility-sdk';
|
|
719
719
|
|
|
720
720
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
721
|
-
interface MyCustomActionConfig
|
|
721
|
+
interface MyCustomActionConfig {}
|
|
722
722
|
|
|
723
723
|
export default class MyCustomAction implements Core.Workflows
|
|
724
724
|
.CustomAction<MyCustomActionConfig> {
|
|
@@ -781,7 +781,7 @@ describe('MyCustomAction', () => {
|
|
|
781
781
|
content: `import type { Extend, Context } from '@stripe/extensibility-sdk';
|
|
782
782
|
|
|
783
783
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
784
|
-
interface MyCustomActionConfig
|
|
784
|
+
interface MyCustomActionConfig {}
|
|
785
785
|
|
|
786
786
|
export default class MyCustomAction implements Extend.Workflows
|
|
787
787
|
.CustomAction<MyCustomActionConfig> {
|
|
@@ -1305,6 +1305,7 @@ function _createBaseOutput(params, context) {
|
|
|
1305
1305
|
// src/templates/extensions/core.workflows.custom_action.ts
|
|
1306
1306
|
var EXTENSION_INTERFACE_ID = "core.workflows.custom_action";
|
|
1307
1307
|
var customActionTemplate = {
|
|
1308
|
+
deprecated: true,
|
|
1308
1309
|
methods: {
|
|
1309
1310
|
execute: { implementation_types: ["script", "remote-function"] },
|
|
1310
1311
|
get_form_state: { implementation_types: ["script", "remote-function"] }
|
|
@@ -1761,10 +1762,11 @@ function mapActions(actions) {
|
|
|
1761
1762
|
}
|
|
1762
1763
|
function mapProperties(schema) {
|
|
1763
1764
|
const result = {};
|
|
1764
|
-
const
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1765
|
+
const resolvedSchema = schema === null || schema === void 0 ? schema : resolveRef(schema, schema.$defs ?? {});
|
|
1766
|
+
const requiredSet = new Set(resolvedSchema?.required ?? []);
|
|
1767
|
+
if (!resolvedSchema?.properties) return result;
|
|
1768
|
+
const defs = resolvedSchema.$defs ?? {};
|
|
1769
|
+
for (const [key, propSchema] of Object.entries(resolvedSchema.properties)) {
|
|
1768
1770
|
result[key] = toFieldSchema(resolveRef(propSchema, defs), requiredSet.has(key));
|
|
1769
1771
|
}
|
|
1770
1772
|
return result;
|
|
@@ -1808,7 +1810,13 @@ function toFieldSchema(schema, required) {
|
|
|
1808
1810
|
fieldSchema.valuesPresence = FieldPresence.PRESENT;
|
|
1809
1811
|
}
|
|
1810
1812
|
if (schema.default !== void 0) {
|
|
1811
|
-
|
|
1813
|
+
if (dataType === DataType.ENUM_TYPE && enumValues) {
|
|
1814
|
+
validateEnumDefault(schema.default, enumValues);
|
|
1815
|
+
}
|
|
1816
|
+
if (dataType === DataType.DATETIME_TYPE) {
|
|
1817
|
+
validateDatetimeDefault(schema.default);
|
|
1818
|
+
}
|
|
1819
|
+
fieldSchema.default = toDefaultValue(schema.default, dataType);
|
|
1812
1820
|
}
|
|
1813
1821
|
return fieldSchema;
|
|
1814
1822
|
}
|
|
@@ -1820,7 +1828,6 @@ function resolveDataType(schema, enumValues, refTarget) {
|
|
|
1820
1828
|
if (schema.format === "date-time") return DataType.DATETIME_TYPE;
|
|
1821
1829
|
return DataType.STRING_TYPE;
|
|
1822
1830
|
case "integer":
|
|
1823
|
-
case "number":
|
|
1824
1831
|
return DataType.INTEGER_TYPE;
|
|
1825
1832
|
case "boolean":
|
|
1826
1833
|
return DataType.BOOLEAN_TYPE;
|
|
@@ -1857,33 +1864,61 @@ function extractSingleLiteral(schema) {
|
|
|
1857
1864
|
return null;
|
|
1858
1865
|
}
|
|
1859
1866
|
function extractEnumValues(schema) {
|
|
1860
|
-
if (schema.enum) {
|
|
1867
|
+
if (Array.isArray(schema.enum) && schema.enum.every((value) => typeof value === "string")) {
|
|
1861
1868
|
return schema.enum.map(String);
|
|
1862
1869
|
}
|
|
1863
|
-
if (Array.isArray(schema.oneOf) && schema.oneOf.length > 0 && schema.oneOf.every(
|
|
1870
|
+
if (Array.isArray(schema.oneOf) && schema.oneOf.length > 0 && schema.oneOf.every(
|
|
1871
|
+
(item) => "const" in item && typeof item.const === "string"
|
|
1872
|
+
)) {
|
|
1864
1873
|
return schema.oneOf.map((item) => String(item.const));
|
|
1865
1874
|
}
|
|
1866
1875
|
return null;
|
|
1867
1876
|
}
|
|
1877
|
+
function validateEnumDefault(value, enumValues) {
|
|
1878
|
+
if (typeof value !== "string" || !enumValues.includes(value)) {
|
|
1879
|
+
throw new Error(
|
|
1880
|
+
`Default value ${JSON.stringify(value)} is not a valid enum value. Expected one of: ${enumValues.join(", ")}`
|
|
1881
|
+
);
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
var DATETIME_UTC_MS_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}(Z|\+00:00)$/;
|
|
1885
|
+
function validateDatetimeDefault(value) {
|
|
1886
|
+
if (typeof value !== "string" || !DATETIME_UTC_MS_RE.test(value)) {
|
|
1887
|
+
throw new Error(
|
|
1888
|
+
`Default value ${JSON.stringify(value)} is not a valid ISO 8601 UTC datetime with millisecond precision. Expected format: YYYY-MM-DDTHH:mm:ss.sssZ or YYYY-MM-DDTHH:mm:ss.sss+00:00`
|
|
1889
|
+
);
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1868
1892
|
function toValueBoundary(value) {
|
|
1869
1893
|
if (!Number.isInteger(value)) {
|
|
1870
1894
|
throw new Error(
|
|
1871
1895
|
`ValueBoundary only supports integers, got ${String(value)}. Custom object numeric fields are integer-only.`
|
|
1872
1896
|
);
|
|
1873
1897
|
}
|
|
1874
|
-
return {
|
|
1898
|
+
return { integerBoundary: value };
|
|
1875
1899
|
}
|
|
1876
1900
|
function toDefaultValue(value, dataType) {
|
|
1877
1901
|
if (dataType === DataType.STRING_TYPE && typeof value === "string") {
|
|
1878
|
-
return {
|
|
1902
|
+
return { stringDefault: value };
|
|
1903
|
+
}
|
|
1904
|
+
if (dataType === DataType.ENUM_TYPE && typeof value === "string") {
|
|
1905
|
+
return { stringDefault: value };
|
|
1906
|
+
}
|
|
1907
|
+
if (dataType === DataType.DATETIME_TYPE && typeof value === "string") {
|
|
1908
|
+
return { stringDefault: value };
|
|
1879
1909
|
}
|
|
1880
1910
|
if (dataType === DataType.INTEGER_TYPE && typeof value === "number") {
|
|
1881
|
-
|
|
1911
|
+
if (!Number.isInteger(value)) {
|
|
1912
|
+
throw new Error(
|
|
1913
|
+
`Integer default values must be whole numbers, got ${JSON.stringify(value)}.`
|
|
1914
|
+
);
|
|
1915
|
+
}
|
|
1916
|
+
return { integerDefault: value };
|
|
1882
1917
|
}
|
|
1883
1918
|
if (dataType === DataType.BOOLEAN_TYPE && typeof value === "boolean") {
|
|
1884
|
-
return {
|
|
1919
|
+
return { booleanDefault: value };
|
|
1885
1920
|
}
|
|
1886
|
-
return {
|
|
1921
|
+
return {};
|
|
1887
1922
|
}
|
|
1888
1923
|
|
|
1889
1924
|
// src/custom-objects/build-definitions.ts
|
|
@@ -1913,7 +1948,7 @@ async function analyzeAndInjectManifest(options) {
|
|
|
1913
1948
|
(diagnostic) => diagnostic.severity === "error"
|
|
1914
1949
|
);
|
|
1915
1950
|
if (errorDiagnostics.length > 0) {
|
|
1916
|
-
const details = errorDiagnostics.map((diagnostic) => diagnostic.message).join("
|
|
1951
|
+
const details = errorDiagnostics.map((diagnostic) => diagnostic.message).join("\n");
|
|
1917
1952
|
throw new Error(details);
|
|
1918
1953
|
}
|
|
1919
1954
|
const coPackageJsonPath = path2.join(projectRoot, "custom-objects", "package.json");
|
|
@@ -28,6 +28,7 @@ var import_node_child_process2 = require("child_process");
|
|
|
28
28
|
var fs3 = __toESM(require("fs"), 1);
|
|
29
29
|
var os2 = __toESM(require("os"), 1);
|
|
30
30
|
var path3 = __toESM(require("path"), 1);
|
|
31
|
+
var import_extensibility_tool_utils8 = require("@stripe/extensibility-tool-utils");
|
|
31
32
|
|
|
32
33
|
// src/custom-objects/build-definitions.ts
|
|
33
34
|
var fs2 = __toESM(require("fs"), 1);
|
|
@@ -331,7 +332,7 @@ describe('MyDiscountCalculation', () => {
|
|
|
331
332
|
content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
|
|
332
333
|
|
|
333
334
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
334
|
-
interface MyDiscountCalculationConfig
|
|
335
|
+
interface MyDiscountCalculationConfig {}
|
|
335
336
|
|
|
336
337
|
export default class MyDiscountCalculation implements Billing.Bill
|
|
337
338
|
.DiscountCalculation<MyDiscountCalculationConfig> {
|
|
@@ -373,7 +374,7 @@ describe('MyBalanceApp', () => {
|
|
|
373
374
|
content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
|
|
374
375
|
|
|
375
376
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
376
|
-
interface MyBalanceAppConfig
|
|
377
|
+
interface MyBalanceAppConfig {}
|
|
377
378
|
|
|
378
379
|
export default class MyBalanceApp implements Billing.CustomerBalanceApplication<MyBalanceAppConfig> {
|
|
379
380
|
computeAppliedCustomerBalance(
|
|
@@ -414,7 +415,7 @@ describe('MyInvoiceCollectionSetting', () => {
|
|
|
414
415
|
content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
|
|
415
416
|
|
|
416
417
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
417
|
-
interface MyInvoiceCollectionSettingConfig
|
|
418
|
+
interface MyInvoiceCollectionSettingConfig {}
|
|
418
419
|
|
|
419
420
|
export default class MyInvoiceCollectionSetting implements Billing.InvoiceCollectionSetting<MyInvoiceCollectionSettingConfig> {
|
|
420
421
|
collectionOverride(
|
|
@@ -453,7 +454,7 @@ describe('MyProrations', () => {
|
|
|
453
454
|
content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
|
|
454
455
|
|
|
455
456
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
456
|
-
interface MyProrationsConfig
|
|
457
|
+
interface MyProrationsConfig {}
|
|
457
458
|
|
|
458
459
|
export default class MyProrations implements Billing.Prorations<MyProrationsConfig> {
|
|
459
460
|
prorateItems(
|
|
@@ -494,7 +495,7 @@ describe('MyRecurringBillingItemHandling', () => {
|
|
|
494
495
|
content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
|
|
495
496
|
|
|
496
497
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
497
|
-
interface MyRecurringBillingItemHandlingConfig
|
|
498
|
+
interface MyRecurringBillingItemHandlingConfig {}
|
|
498
499
|
|
|
499
500
|
export default class MyRecurringBillingItemHandling implements Billing.RecurringBillingItemHandling<MyRecurringBillingItemHandlingConfig> {
|
|
500
501
|
beforeItemCreation(
|
|
@@ -744,7 +745,7 @@ describe('MyCustomAction', () => {
|
|
|
744
745
|
content: `import type { Core, Context } from '@stripe/extensibility-sdk';
|
|
745
746
|
|
|
746
747
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
747
|
-
interface MyCustomActionConfig
|
|
748
|
+
interface MyCustomActionConfig {}
|
|
748
749
|
|
|
749
750
|
export default class MyCustomAction implements Core.Workflows
|
|
750
751
|
.CustomAction<MyCustomActionConfig> {
|
|
@@ -807,7 +808,7 @@ describe('MyCustomAction', () => {
|
|
|
807
808
|
content: `import type { Extend, Context } from '@stripe/extensibility-sdk';
|
|
808
809
|
|
|
809
810
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
810
|
-
interface MyCustomActionConfig
|
|
811
|
+
interface MyCustomActionConfig {}
|
|
811
812
|
|
|
812
813
|
export default class MyCustomAction implements Extend.Workflows
|
|
813
814
|
.CustomAction<MyCustomActionConfig> {
|
|
@@ -1331,6 +1332,7 @@ function _createBaseOutput(params, context) {
|
|
|
1331
1332
|
// src/templates/extensions/core.workflows.custom_action.ts
|
|
1332
1333
|
var EXTENSION_INTERFACE_ID = "core.workflows.custom_action";
|
|
1333
1334
|
var customActionTemplate = {
|
|
1335
|
+
deprecated: true,
|
|
1334
1336
|
methods: {
|
|
1335
1337
|
execute: { implementation_types: ["script", "remote-function"] },
|
|
1336
1338
|
get_form_state: { implementation_types: ["script", "remote-function"] }
|
|
@@ -1787,10 +1789,11 @@ function mapActions(actions) {
|
|
|
1787
1789
|
}
|
|
1788
1790
|
function mapProperties(schema) {
|
|
1789
1791
|
const result = {};
|
|
1790
|
-
const
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1792
|
+
const resolvedSchema = schema === null || schema === void 0 ? schema : resolveRef(schema, schema.$defs ?? {});
|
|
1793
|
+
const requiredSet = new Set(resolvedSchema?.required ?? []);
|
|
1794
|
+
if (!resolvedSchema?.properties) return result;
|
|
1795
|
+
const defs = resolvedSchema.$defs ?? {};
|
|
1796
|
+
for (const [key, propSchema] of Object.entries(resolvedSchema.properties)) {
|
|
1794
1797
|
result[key] = toFieldSchema(resolveRef(propSchema, defs), requiredSet.has(key));
|
|
1795
1798
|
}
|
|
1796
1799
|
return result;
|
|
@@ -1834,7 +1837,13 @@ function toFieldSchema(schema, required) {
|
|
|
1834
1837
|
fieldSchema.valuesPresence = FieldPresence.PRESENT;
|
|
1835
1838
|
}
|
|
1836
1839
|
if (schema.default !== void 0) {
|
|
1837
|
-
|
|
1840
|
+
if (dataType === DataType.ENUM_TYPE && enumValues) {
|
|
1841
|
+
validateEnumDefault(schema.default, enumValues);
|
|
1842
|
+
}
|
|
1843
|
+
if (dataType === DataType.DATETIME_TYPE) {
|
|
1844
|
+
validateDatetimeDefault(schema.default);
|
|
1845
|
+
}
|
|
1846
|
+
fieldSchema.default = toDefaultValue(schema.default, dataType);
|
|
1838
1847
|
}
|
|
1839
1848
|
return fieldSchema;
|
|
1840
1849
|
}
|
|
@@ -1846,7 +1855,6 @@ function resolveDataType(schema, enumValues, refTarget) {
|
|
|
1846
1855
|
if (schema.format === "date-time") return DataType.DATETIME_TYPE;
|
|
1847
1856
|
return DataType.STRING_TYPE;
|
|
1848
1857
|
case "integer":
|
|
1849
|
-
case "number":
|
|
1850
1858
|
return DataType.INTEGER_TYPE;
|
|
1851
1859
|
case "boolean":
|
|
1852
1860
|
return DataType.BOOLEAN_TYPE;
|
|
@@ -1883,33 +1891,61 @@ function extractSingleLiteral(schema) {
|
|
|
1883
1891
|
return null;
|
|
1884
1892
|
}
|
|
1885
1893
|
function extractEnumValues(schema) {
|
|
1886
|
-
if (schema.enum) {
|
|
1894
|
+
if (Array.isArray(schema.enum) && schema.enum.every((value) => typeof value === "string")) {
|
|
1887
1895
|
return schema.enum.map(String);
|
|
1888
1896
|
}
|
|
1889
|
-
if (Array.isArray(schema.oneOf) && schema.oneOf.length > 0 && schema.oneOf.every(
|
|
1897
|
+
if (Array.isArray(schema.oneOf) && schema.oneOf.length > 0 && schema.oneOf.every(
|
|
1898
|
+
(item) => "const" in item && typeof item.const === "string"
|
|
1899
|
+
)) {
|
|
1890
1900
|
return schema.oneOf.map((item) => String(item.const));
|
|
1891
1901
|
}
|
|
1892
1902
|
return null;
|
|
1893
1903
|
}
|
|
1904
|
+
function validateEnumDefault(value, enumValues) {
|
|
1905
|
+
if (typeof value !== "string" || !enumValues.includes(value)) {
|
|
1906
|
+
throw new Error(
|
|
1907
|
+
`Default value ${JSON.stringify(value)} is not a valid enum value. Expected one of: ${enumValues.join(", ")}`
|
|
1908
|
+
);
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
var DATETIME_UTC_MS_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}(Z|\+00:00)$/;
|
|
1912
|
+
function validateDatetimeDefault(value) {
|
|
1913
|
+
if (typeof value !== "string" || !DATETIME_UTC_MS_RE.test(value)) {
|
|
1914
|
+
throw new Error(
|
|
1915
|
+
`Default value ${JSON.stringify(value)} is not a valid ISO 8601 UTC datetime with millisecond precision. Expected format: YYYY-MM-DDTHH:mm:ss.sssZ or YYYY-MM-DDTHH:mm:ss.sss+00:00`
|
|
1916
|
+
);
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1894
1919
|
function toValueBoundary(value) {
|
|
1895
1920
|
if (!Number.isInteger(value)) {
|
|
1896
1921
|
throw new Error(
|
|
1897
1922
|
`ValueBoundary only supports integers, got ${String(value)}. Custom object numeric fields are integer-only.`
|
|
1898
1923
|
);
|
|
1899
1924
|
}
|
|
1900
|
-
return {
|
|
1925
|
+
return { integerBoundary: value };
|
|
1901
1926
|
}
|
|
1902
1927
|
function toDefaultValue(value, dataType) {
|
|
1903
1928
|
if (dataType === DataType.STRING_TYPE && typeof value === "string") {
|
|
1904
|
-
return {
|
|
1929
|
+
return { stringDefault: value };
|
|
1930
|
+
}
|
|
1931
|
+
if (dataType === DataType.ENUM_TYPE && typeof value === "string") {
|
|
1932
|
+
return { stringDefault: value };
|
|
1933
|
+
}
|
|
1934
|
+
if (dataType === DataType.DATETIME_TYPE && typeof value === "string") {
|
|
1935
|
+
return { stringDefault: value };
|
|
1905
1936
|
}
|
|
1906
1937
|
if (dataType === DataType.INTEGER_TYPE && typeof value === "number") {
|
|
1907
|
-
|
|
1938
|
+
if (!Number.isInteger(value)) {
|
|
1939
|
+
throw new Error(
|
|
1940
|
+
`Integer default values must be whole numbers, got ${JSON.stringify(value)}.`
|
|
1941
|
+
);
|
|
1942
|
+
}
|
|
1943
|
+
return { integerDefault: value };
|
|
1908
1944
|
}
|
|
1909
1945
|
if (dataType === DataType.BOOLEAN_TYPE && typeof value === "boolean") {
|
|
1910
|
-
return {
|
|
1946
|
+
return { booleanDefault: value };
|
|
1911
1947
|
}
|
|
1912
|
-
return {
|
|
1948
|
+
return {};
|
|
1913
1949
|
}
|
|
1914
1950
|
|
|
1915
1951
|
// src/custom-objects/build-definitions.ts
|
|
@@ -1939,7 +1975,7 @@ async function analyzeAndInjectManifest(options) {
|
|
|
1939
1975
|
(diagnostic) => diagnostic.severity === "error"
|
|
1940
1976
|
);
|
|
1941
1977
|
if (errorDiagnostics.length > 0) {
|
|
1942
|
-
const details = errorDiagnostics.map((diagnostic) => diagnostic.message).join("
|
|
1978
|
+
const details = errorDiagnostics.map((diagnostic) => diagnostic.message).join("\n");
|
|
1943
1979
|
throw new Error(details);
|
|
1944
1980
|
}
|
|
1945
1981
|
const coPackageJsonPath = path2.join(projectRoot, "custom-objects", "package.json");
|
|
@@ -2076,16 +2112,18 @@ function readPackageDependencies(packageJsonPath) {
|
|
|
2076
2112
|
}
|
|
2077
2113
|
|
|
2078
2114
|
// src/bin/create-upload-image.ts
|
|
2115
|
+
var logger = (0, import_extensibility_tool_utils8._createLogger)({ name: "create-upload-image" });
|
|
2079
2116
|
async function main() {
|
|
2117
|
+
const ctx = (0, import_extensibility_tool_utils8._createCliContext)();
|
|
2080
2118
|
const targetPath = process.argv[2];
|
|
2081
2119
|
if (!targetPath) {
|
|
2082
|
-
|
|
2120
|
+
ctx.ux.error("Usage: create-upload-image <target-path>");
|
|
2083
2121
|
process.exit(1);
|
|
2084
2122
|
}
|
|
2085
2123
|
let state = null;
|
|
2086
2124
|
const manifestPath = "stripe-app.yaml";
|
|
2087
2125
|
if (fs3.existsSync(manifestPath)) {
|
|
2088
|
-
state = await analyzeAndInjectManifest({ manifestPath });
|
|
2126
|
+
state = await analyzeAndInjectManifest({ manifestPath, context: ctx });
|
|
2089
2127
|
}
|
|
2090
2128
|
fs3.mkdirSync(targetPath, { recursive: true });
|
|
2091
2129
|
const tarball = path3.join(os2.tmpdir(), `upload-image-${String(Date.now())}.tgz`);
|
|
@@ -2118,7 +2156,7 @@ async function main() {
|
|
|
2118
2156
|
}
|
|
2119
2157
|
}
|
|
2120
2158
|
if (state) {
|
|
2121
|
-
await writeCustomObjectArtifacts({ targetPath }, state);
|
|
2159
|
+
await writeCustomObjectArtifacts({ targetPath, context: ctx }, state);
|
|
2122
2160
|
}
|
|
2123
2161
|
const imageMetadata = JSON.stringify(
|
|
2124
2162
|
{ image: { version: "1.0", built: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
@@ -2128,6 +2166,6 @@ async function main() {
|
|
|
2128
2166
|
fs3.writeFileSync(path3.join(targetPath, ".image.json"), imageMetadata + "\n");
|
|
2129
2167
|
}
|
|
2130
2168
|
main().catch((err) => {
|
|
2131
|
-
|
|
2169
|
+
logger.error({ err }, "Unexpected error");
|
|
2132
2170
|
process.exit(1);
|
|
2133
2171
|
});
|