@stripe/extensibility-dev-tools 0.24.2 → 0.25.1

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.
Files changed (62) hide show
  1. package/dist/bin/build-custom-object-definitions.cjs +203 -46
  2. package/dist/bin/build-custom-object-definitions.js +194 -37
  3. package/dist/bin/create-upload-image.cjs +206 -46
  4. package/dist/bin/create-upload-image.js +201 -41
  5. package/dist/bin/dev-tools-rpc.cjs +199 -59
  6. package/dist/bin/dev-tools-rpc.js +174 -34
  7. package/dist/bin/gen-workspace.cjs +187 -47
  8. package/dist/bin/gen-workspace.js +174 -34
  9. package/dist/bin/template-info.cjs +161 -30
  10. package/dist/bin/template-info.js +156 -25
  11. package/dist/custom-objects/build-definitions.d.ts.map +1 -1
  12. package/dist/custom-objects/generated/proto/custom_objects/pub/api/app_api/object_definitions_app_service.pb.d.ts +32 -0
  13. package/dist/custom-objects/generated/proto/custom_objects/pub/api/app_api/object_definitions_app_service.pb.d.ts.map +1 -1
  14. package/dist/custom-objects/generated/proto/google/protobuf/descriptor.pb.d.ts +2 -2
  15. package/dist/custom-objects/generated/proto/google/protobuf/wrappers.pb.d.ts +168 -0
  16. package/dist/custom-objects/generated/proto/google/protobuf/wrappers.pb.d.ts.map +1 -0
  17. package/dist/custom-objects/generated/proto/proto/extensions.pb.d.ts +4 -4
  18. package/dist/custom-objects/generated/proto/proto/extensions.pb.d.ts.map +1 -1
  19. package/dist/custom-objects/generated/proto/vendor/proto/model/common/common_model.pb.d.ts +1553 -0
  20. package/dist/custom-objects/generated/proto/vendor/proto/model/common/common_model.pb.d.ts.map +1 -0
  21. package/dist/custom-objects/generated/proto/vendor/proto/model/common/kronos_model.pb.d.ts +1372 -0
  22. package/dist/custom-objects/generated/proto/vendor/proto/model/common/kronos_model.pb.d.ts.map +1 -0
  23. package/dist/custom-objects/generated/proto/vendor/publicapi/api_group_enum.pb.d.ts +2 -0
  24. package/dist/custom-objects/generated/proto/vendor/publicapi/api_group_enum.pb.d.ts.map +1 -1
  25. package/dist/custom-objects/generated/proto/vendor/publicapi/extension_interface.pb.d.ts +2 -0
  26. package/dist/custom-objects/generated/proto/vendor/publicapi/extension_interface.pb.d.ts.map +1 -1
  27. package/dist/custom-objects/generated/proto/vendor/publicapi/feature_enum.pb.d.ts +14 -2
  28. package/dist/custom-objects/generated/proto/vendor/publicapi/feature_enum.pb.d.ts.map +1 -1
  29. package/dist/custom-objects/generated/proto/vendor/publicapi/http_error_status.pb.d.ts +6 -0
  30. package/dist/custom-objects/generated/proto/vendor/publicapi/http_error_status.pb.d.ts.map +1 -1
  31. package/dist/custom-objects/generated/proto/vendor/publicapi/rollout_configs.pb.d.ts +74 -0
  32. package/dist/custom-objects/generated/proto/vendor/publicapi/rollout_configs.pb.d.ts.map +1 -1
  33. package/dist/custom-objects/generated/proto/vendor/publicapi/v2ext.pb.d.ts +10 -3
  34. package/dist/custom-objects/generated/proto/vendor/publicapi/v2ext.pb.d.ts.map +1 -1
  35. package/dist/custom-objects/generated/proto/vendor/vext/privacy_unified_annotations.pb.d.ts +1 -0
  36. package/dist/custom-objects/generated/proto/vendor/vext/privacy_unified_annotations.pb.d.ts.map +1 -1
  37. package/dist/index.cjs +192 -52
  38. package/dist/index.js +174 -34
  39. package/dist/templates/extensions/billing.invoice_collection_options.d.ts +6 -0
  40. package/dist/templates/extensions/billing.invoice_collection_options.d.ts.map +1 -0
  41. package/dist/templates/index.cjs +174 -34
  42. package/dist/templates/index.js +172 -32
  43. package/dist/templates/root/index.d.ts.map +1 -1
  44. package/dist/tsconfig.build.tsbuildinfo +1 -1
  45. package/dist/workspace/index.cjs +183 -43
  46. package/dist/workspace/index.d.ts.map +1 -1
  47. package/dist/workspace/index.js +174 -34
  48. package/dist/workspace-versions.d.ts +26 -0
  49. package/dist/workspace-versions.d.ts.map +1 -0
  50. package/package.json +4 -4
  51. package/templates/extensions/billing.invoice_collection_options/index.test.ts +15 -0
  52. package/templates/extensions/billing.invoice_collection_options/index.ts +16 -0
  53. package/templates/root/custom-objects/eslint.config.mts +89 -0
  54. package/templates/root/custom-objects/package.json.mustache +2 -0
  55. package/templates/root/custom-objects/tsconfig.json +1 -0
  56. package/templates/root/custom-objects/vitest.config.mts +7 -0
  57. package/templates/root/package.json.mustache +1 -1
  58. package/templates/root/tools/test.mts +4 -2
  59. package/dist/templates/extensions/billing.invoice_collection_setting.d.ts +0 -6
  60. package/dist/templates/extensions/billing.invoice_collection_setting.d.ts.map +0 -1
  61. package/templates/extensions/billing.invoice_collection_setting/index.test.ts +0 -15
  62. package/templates/extensions/billing.invoice_collection_setting/index.ts +0 -16
@@ -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_utils7 = require("@stripe/extensibility-tool-utils");
31
32
 
32
33
  // src/custom-objects/build-definitions.ts
33
34
  var fs2 = __toESM(require("fs"), 1);
@@ -391,35 +392,35 @@ export default class MyBalanceApp implements Billing.CustomerBalanceApplication<
391
392
  `
392
393
  },
393
394
  {
394
- path: "extensions/billing.invoice_collection_setting/index.test.ts",
395
+ path: "extensions/billing.invoice_collection_options/index.test.ts",
395
396
  content: `import { beforeEach, describe, it, expect } from 'vitest';
396
397
 
397
- import MyInvoiceCollectionSetting from './index.js';
398
+ import MyInvoiceCollectionOptions from './index.js';
398
399
 
399
- describe('MyInvoiceCollectionSetting', () => {
400
- let instance: MyInvoiceCollectionSetting;
400
+ describe('MyInvoiceCollectionOptions', () => {
401
+ let instance: MyInvoiceCollectionOptions;
401
402
 
402
403
  beforeEach(() => {
403
- instance = new MyInvoiceCollectionSetting();
404
+ instance = new MyInvoiceCollectionOptions();
404
405
  });
405
406
 
406
407
  it('should be constructable', () => {
407
- expect(instance).toBeInstanceOf(MyInvoiceCollectionSetting);
408
+ expect(instance).toBeInstanceOf(MyInvoiceCollectionOptions);
408
409
  });
409
410
  });
410
411
  `
411
412
  },
412
413
  {
413
- path: "extensions/billing.invoice_collection_setting/index.ts",
414
+ path: "extensions/billing.invoice_collection_options/index.ts",
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 MyInvoiceCollectionOptionsConfig {}
418
419
 
419
- export default class MyInvoiceCollectionSetting implements Billing.InvoiceCollectionSetting<MyInvoiceCollectionSettingConfig> {
420
- collectionOverride(
421
- _request: Billing.InvoiceCollectionSetting.InvoiceCollectionRequest,
422
- _config: MyInvoiceCollectionSettingConfig,
420
+ export default class MyInvoiceCollectionOptions implements Billing.InvoiceCollectionOptions<MyInvoiceCollectionOptionsConfig> {
421
+ overrideOptions(
422
+ _request: Billing.InvoiceCollectionOptions.InvoiceCollectionOptionsInput,
423
+ _config: MyInvoiceCollectionOptionsConfig,
423
424
  _context: Context
424
425
  ) {
425
426
  // TODO: implement your collection setting logic here
@@ -891,6 +892,99 @@ install-deps.log
891
892
 
892
893
  # generated schemas
893
894
  generated
895
+ `
896
+ },
897
+ {
898
+ path: "root/custom-objects/eslint.config.mts",
899
+ content: `import eslint from '@eslint/js';
900
+ import { defineConfig } from 'eslint/config';
901
+ import tseslint from 'typescript-eslint';
902
+ import eslintConfigPrettier from 'eslint-config-prettier/flat';
903
+
904
+ import globals from 'globals';
905
+
906
+ import stripeAppsConfig from '@stripe/extensibility-eslint-plugin';
907
+ import customObjectsConfig from '@stripe/extensibility-eslint-plugin/custom-objects';
908
+
909
+ export default defineConfig([
910
+ eslint.configs.recommended,
911
+ ...tseslint.configs.recommended,
912
+ ...stripeAppsConfig,
913
+ ...customObjectsConfig,
914
+
915
+ // Global ignores
916
+ {
917
+ ignores: ['dist', 'generated', 'node_modules'],
918
+ },
919
+
920
+ // TypeScript source files (with type-checking)
921
+ {
922
+ name: 'sources',
923
+ files: ['src/**/*.ts'],
924
+ ignores: ['**/*.test.ts', '**/__tests__/**'],
925
+ languageOptions: {
926
+ globals: {
927
+ ...globals.node,
928
+ },
929
+ parserOptions: {
930
+ projectService: true,
931
+ tsconfigRootDir: import.meta.dirname,
932
+ },
933
+ },
934
+ },
935
+
936
+ // Test files
937
+ {
938
+ name: 'tests',
939
+ files: ['src/**/*.test.ts', 'src/**/__tests__/**/*.ts'],
940
+ languageOptions: {
941
+ globals: {
942
+ ...globals.node,
943
+ },
944
+ parserOptions: {
945
+ projectService: true,
946
+ tsconfigRootDir: import.meta.dirname,
947
+ },
948
+ },
949
+ },
950
+
951
+ // Config files
952
+ {
953
+ name: 'ts-configs',
954
+ files: ['*.config.m?ts', 'eslint.config.mts'],
955
+ languageOptions: {
956
+ globals: {
957
+ ...globals.node,
958
+ },
959
+ parserOptions: {
960
+ projectService: false,
961
+ },
962
+ },
963
+ rules: {
964
+ '@typescript-eslint/no-unused-vars': 'off',
965
+ },
966
+ },
967
+
968
+ // JavaScript/MJS files (scripts, configs) \u2014 no TS project, so only
969
+ // disable the TS-parser-specific rule that doesn't apply without it.
970
+ {
971
+ name: 'js-configs',
972
+ files: ['**/*.js', '**/*.mjs'],
973
+ languageOptions: {
974
+ globals: {
975
+ ...globals.node,
976
+ },
977
+ parserOptions: {
978
+ projectService: false,
979
+ },
980
+ },
981
+ rules: {
982
+ '@typescript-eslint/no-require-imports': 'off',
983
+ },
984
+ },
985
+
986
+ eslintConfigPrettier,
987
+ ]);
894
988
  `
895
989
  },
896
990
  {
@@ -903,7 +997,9 @@ generated
903
997
  "private": true,
904
998
  "scripts": {
905
999
  "build": "test -d src && custom-objects-build --input src --output dist || true",
1000
+ "lint": "pnpm lint:types && pnpm lint:eslint",
906
1001
  "lint:types": "test ! -d src || tsc --noEmit",
1002
+ "lint:eslint": "eslint .",
907
1003
  "test": "vitest run"
908
1004
  },
909
1005
  "dependencies": {
@@ -926,8 +1022,20 @@ generated
926
1022
  "moduleResolution": "bundler",
927
1023
  "types": ["vitest/globals"]
928
1024
  },
1025
+ "include": ["src/**/*.ts"],
929
1026
  "exclude": ["dist"]
930
1027
  }
1028
+ `
1029
+ },
1030
+ {
1031
+ path: "root/custom-objects/vitest.config.mts",
1032
+ content: `import { defineConfig } from 'vitest/config';
1033
+
1034
+ export default defineConfig({
1035
+ test: {
1036
+ globals: true,
1037
+ },
1038
+ });
931
1039
  `
932
1040
  },
933
1041
  {
@@ -1045,7 +1153,7 @@ export default defineConfig([
1045
1153
  "build": "pnpm -r --if-present build",
1046
1154
  "lint": "pnpm lint:types && pnpm lint:eslint && pnpm lint:format",
1047
1155
  "lint:types": "pnpm -r --if-present lint:types",
1048
- "lint:eslint": "eslint . --ignore-pattern 'extensions/**' && pnpm -r --filter './extensions/*' --if-present lint:eslint",
1156
+ "lint:eslint": "eslint . --ignore-pattern 'extensions/**' && pnpm -r --filter './extensions/*' --if-present lint:eslint && pnpm -r --filter './custom-objects' --if-present lint:eslint",
1049
1157
  "lint:format": "prettier --check .",
1050
1158
  "fix:lint": "eslint --fix . --ignore-pattern 'extensions/**' && pnpm -r --filter './extensions/*' --if-present fix:lint",
1051
1159
  "fix:format": "prettier --write .",
@@ -1091,7 +1199,7 @@ declarations:
1091
1199
  content: `#!/usr/bin/env tsx
1092
1200
  /**
1093
1201
  * Runs tests across the workspace:
1094
- * - vitest for script extensions and custom objects (extensions/*)
1202
+ * - vitest for script extensions (extensions/*) and custom objects (custom-objects/)
1095
1203
  * - jest for UI extensions (ui/)
1096
1204
  */
1097
1205
  import { existsSync, readdirSync } from 'node:fs';
@@ -1101,6 +1209,8 @@ const hasExtensions =
1101
1209
  existsSync('extensions') &&
1102
1210
  readdirSync('extensions').some((name) => existsSync(\`extensions/\${name}/package.json\`));
1103
1211
 
1212
+ const hasCustomObjects = existsSync('custom-objects/package.json');
1213
+
1104
1214
  const hasUI = existsSync('ui/package.json');
1105
1215
 
1106
1216
  let exitCode = 0;
@@ -1113,7 +1223,7 @@ function run(cmd: string): void {
1113
1223
  }
1114
1224
  }
1115
1225
 
1116
- if (hasExtensions) {
1226
+ if (hasExtensions || hasCustomObjects) {
1117
1227
  run('vitest run');
1118
1228
  }
1119
1229
 
@@ -1265,11 +1375,33 @@ function _devNpmDep(name, version) {
1265
1375
  return { type: "dev-npm", name, version };
1266
1376
  }
1267
1377
 
1378
+ // src/workspace-versions.json
1379
+ var workspace_versions_default = {
1380
+ "@stripe/extensibility-custom-objects": "0.8.0",
1381
+ "@stripe/extensibility-custom-objects-tools": "0.42.1",
1382
+ "@stripe/extensibility-dev-tools": "0.25.1",
1383
+ "@stripe/extensibility-eslint-plugin": "0.17.1",
1384
+ "@stripe/extensibility-language-server": "0.3.4",
1385
+ "@stripe/extensibility-sdk": "0.27.1",
1386
+ "@stripe/extensibility-test-helpers": "0.2.7"
1387
+ };
1388
+
1389
+ // src/workspace-versions.ts
1390
+ var _workspaceVersions = workspace_versions_default;
1391
+ function _workspaceVersion(packageName) {
1392
+ const v = _workspaceVersions[packageName];
1393
+ if (v === void 0) {
1394
+ throw new Error(
1395
+ `Unknown workspace package "${packageName}". Check workspace-versions.json or run: tsx scripts/src/sync-workspace-versions.ts`
1396
+ );
1397
+ }
1398
+ return v;
1399
+ }
1400
+
1268
1401
  // src/templates/extensions/base.ts
1269
- var import_extensibility_tool_utils6 = require("@stripe/extensibility-tool-utils");
1270
1402
  var SDK_PACKAGE_NAME = "@stripe/extensibility-sdk";
1271
1403
  var LANGUAGE_SERVER_PACKAGE_NAME = "@stripe/extensibility-language-server";
1272
- var LANGUAGE_SERVER_PACKAGE_VERSION = `^${(0, import_extensibility_tool_utils6._workspaceVersion)(LANGUAGE_SERVER_PACKAGE_NAME)}`;
1404
+ var LANGUAGE_SERVER_PACKAGE_VERSION = `^${_workspaceVersion(LANGUAGE_SERVER_PACKAGE_NAME)}`;
1273
1405
  function _createExtensionEslintConfigFile(params, context) {
1274
1406
  const { id, extensionInterfaceId } = params;
1275
1407
  const { fs: fs4 } = context;
@@ -1312,7 +1444,7 @@ function _createBaseOutput(params, context) {
1312
1444
  dependencies: {
1313
1445
  // Exact pin (no caret) — the SDK is tightly coupled to dev-tools and
1314
1446
  // must match the version that generated the extension scaffolding.
1315
- runtime: [_npmDep(SDK_PACKAGE_NAME, (0, import_extensibility_tool_utils6._workspaceVersion)(SDK_PACKAGE_NAME))],
1447
+ runtime: [_npmDep(SDK_PACKAGE_NAME, _workspaceVersion(SDK_PACKAGE_NAME))],
1316
1448
  dev: [_devNpmDep(LANGUAGE_SERVER_PACKAGE_NAME, LANGUAGE_SERVER_PACKAGE_VERSION)]
1317
1449
  },
1318
1450
  postGenerationHooks: [
@@ -1571,14 +1703,14 @@ var billing_bill_discount_calculation_default = {
1571
1703
  [EXTENSION_INTERFACE_ID5]: discountCalculationTemplate
1572
1704
  };
1573
1705
 
1574
- // src/templates/extensions/billing.invoice_collection_setting.ts
1575
- var EXTENSION_INTERFACE_ID6 = "billing.invoice_collection_setting";
1576
- var invoiceCollectionSettingTemplate = {
1706
+ // src/templates/extensions/billing.invoice_collection_options.ts
1707
+ var EXTENSION_INTERFACE_ID6 = "billing.invoice_collection_options";
1708
+ var invoiceCollectionOptionsTemplate = {
1577
1709
  hidden: true,
1578
1710
  methods: {
1579
- collection_override: { implementation_types: ["script"] }
1711
+ override_options: { implementation_types: ["script"] }
1580
1712
  },
1581
- description: "Use Stripe Scripts to create custom invoice collection logic that controls how your integration handles invoices generated from subscriptions.",
1713
+ description: "Use Stripe Scripts to create custom invoice collection options that controls how your integration handles invoices generated from subscriptions.",
1582
1714
  generate: (params, context) => {
1583
1715
  const { id } = params;
1584
1716
  const { fs: fs4 } = context;
@@ -1606,15 +1738,15 @@ var invoiceCollectionSettingTemplate = {
1606
1738
  ...base.files
1607
1739
  ],
1608
1740
  methods: {
1609
- collection_override: {
1741
+ override_options: {
1610
1742
  implementation_type: "script"
1611
1743
  }
1612
1744
  }
1613
1745
  };
1614
1746
  }
1615
1747
  };
1616
- var billing_invoice_collection_setting_default = {
1617
- [EXTENSION_INTERFACE_ID6]: invoiceCollectionSettingTemplate
1748
+ var billing_invoice_collection_options_default = {
1749
+ [EXTENSION_INTERFACE_ID6]: invoiceCollectionOptionsTemplate
1618
1750
  };
1619
1751
 
1620
1752
  // src/templates/extensions/billing.prorations.ts
@@ -1722,7 +1854,7 @@ var DEFAULT_TEMPLATES = {
1722
1854
  ...extend_workflows_custom_action_default,
1723
1855
  ...billing_customer_balance_application_default,
1724
1856
  ...billing_bill_discount_calculation_default,
1725
- ...billing_invoice_collection_setting_default,
1857
+ ...billing_invoice_collection_options_default,
1726
1858
  ...billing_prorations_default,
1727
1859
  ...billing_recurring_billing_item_handling_default
1728
1860
  };
@@ -1788,10 +1920,11 @@ function mapActions(actions) {
1788
1920
  }
1789
1921
  function mapProperties(schema) {
1790
1922
  const result = {};
1791
- const requiredSet = new Set(schema?.required ?? []);
1792
- if (!schema?.properties) return result;
1793
- const defs = schema.$defs ?? {};
1794
- for (const [key, propSchema] of Object.entries(schema.properties)) {
1923
+ const resolvedSchema = schema === null || schema === void 0 ? schema : resolveRef(schema, schema.$defs ?? {});
1924
+ const requiredSet = new Set(resolvedSchema?.required ?? []);
1925
+ if (!resolvedSchema?.properties) return result;
1926
+ const defs = resolvedSchema.$defs ?? {};
1927
+ for (const [key, propSchema] of Object.entries(resolvedSchema.properties)) {
1795
1928
  result[key] = toFieldSchema(resolveRef(propSchema, defs), requiredSet.has(key));
1796
1929
  }
1797
1930
  return result;
@@ -1835,10 +1968,11 @@ function toFieldSchema(schema, required) {
1835
1968
  fieldSchema.valuesPresence = FieldPresence.PRESENT;
1836
1969
  }
1837
1970
  if (schema.default !== void 0) {
1838
- if (dataType === DataType.ENUM_TYPE && enumValues && (typeof schema.default !== "string" || !enumValues.includes(schema.default))) {
1839
- throw new Error(
1840
- `Default value ${JSON.stringify(schema.default)} is not a valid enum value. Expected one of: ${enumValues.join(", ")}`
1841
- );
1971
+ if (dataType === DataType.ENUM_TYPE && enumValues) {
1972
+ validateEnumDefault(schema.default, enumValues);
1973
+ }
1974
+ if (dataType === DataType.DATETIME_TYPE) {
1975
+ validateDatetimeDefault(schema.default);
1842
1976
  }
1843
1977
  fieldSchema.default = toDefaultValue(schema.default, dataType);
1844
1978
  }
@@ -1852,7 +1986,6 @@ function resolveDataType(schema, enumValues, refTarget) {
1852
1986
  if (schema.format === "date-time") return DataType.DATETIME_TYPE;
1853
1987
  return DataType.STRING_TYPE;
1854
1988
  case "integer":
1855
- case "number":
1856
1989
  return DataType.INTEGER_TYPE;
1857
1990
  case "boolean":
1858
1991
  return DataType.BOOLEAN_TYPE;
@@ -1889,14 +2022,31 @@ function extractSingleLiteral(schema) {
1889
2022
  return null;
1890
2023
  }
1891
2024
  function extractEnumValues(schema) {
1892
- if (schema.enum) {
2025
+ if (Array.isArray(schema.enum) && schema.enum.every((value) => typeof value === "string")) {
1893
2026
  return schema.enum.map(String);
1894
2027
  }
1895
- if (Array.isArray(schema.oneOf) && schema.oneOf.length > 0 && schema.oneOf.every((item) => "const" in item)) {
2028
+ if (Array.isArray(schema.oneOf) && schema.oneOf.length > 0 && schema.oneOf.every(
2029
+ (item) => "const" in item && typeof item.const === "string"
2030
+ )) {
1896
2031
  return schema.oneOf.map((item) => String(item.const));
1897
2032
  }
1898
2033
  return null;
1899
2034
  }
2035
+ function validateEnumDefault(value, enumValues) {
2036
+ if (typeof value !== "string" || !enumValues.includes(value)) {
2037
+ throw new Error(
2038
+ `Default value ${JSON.stringify(value)} is not a valid enum value. Expected one of: ${enumValues.join(", ")}`
2039
+ );
2040
+ }
2041
+ }
2042
+ var DATETIME_UTC_MS_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}(Z|\+00:00)$/;
2043
+ function validateDatetimeDefault(value) {
2044
+ if (typeof value !== "string" || !DATETIME_UTC_MS_RE.test(value)) {
2045
+ throw new Error(
2046
+ `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`
2047
+ );
2048
+ }
2049
+ }
1900
2050
  function toValueBoundary(value) {
1901
2051
  if (!Number.isInteger(value)) {
1902
2052
  throw new Error(
@@ -1912,7 +2062,15 @@ function toDefaultValue(value, dataType) {
1912
2062
  if (dataType === DataType.ENUM_TYPE && typeof value === "string") {
1913
2063
  return { stringDefault: value };
1914
2064
  }
2065
+ if (dataType === DataType.DATETIME_TYPE && typeof value === "string") {
2066
+ return { stringDefault: value };
2067
+ }
1915
2068
  if (dataType === DataType.INTEGER_TYPE && typeof value === "number") {
2069
+ if (!Number.isInteger(value)) {
2070
+ throw new Error(
2071
+ `Integer default values must be whole numbers, got ${JSON.stringify(value)}.`
2072
+ );
2073
+ }
1916
2074
  return { integerDefault: value };
1917
2075
  }
1918
2076
  if (dataType === DataType.BOOLEAN_TYPE && typeof value === "boolean") {
@@ -1922,9 +2080,9 @@ function toDefaultValue(value, dataType) {
1922
2080
  }
1923
2081
 
1924
2082
  // src/custom-objects/build-definitions.ts
1925
- var import_extensibility_tool_utils7 = require("@stripe/extensibility-tool-utils");
2083
+ var import_extensibility_tool_utils6 = require("@stripe/extensibility-tool-utils");
1926
2084
  async function analyzeAndInjectManifest(options) {
1927
- const context = options.context ?? (0, import_extensibility_tool_utils7._createCliContext)();
2085
+ const context = options.context ?? (0, import_extensibility_tool_utils6._createCliContext)();
1928
2086
  const manifestPath = options.manifestPath ?? "stripe-app.yaml";
1929
2087
  const projectRoot = options.projectRoot ?? path2.dirname(path2.resolve(manifestPath));
1930
2088
  const resolvedManifestPath = path2.resolve(manifestPath);
@@ -1948,7 +2106,7 @@ async function analyzeAndInjectManifest(options) {
1948
2106
  (diagnostic) => diagnostic.severity === "error"
1949
2107
  );
1950
2108
  if (errorDiagnostics.length > 0) {
1951
- const details = errorDiagnostics.map((diagnostic) => diagnostic.message).join("; ");
2109
+ const details = errorDiagnostics.map((diagnostic) => diagnostic.message).join("\n");
1952
2110
  throw new Error(details);
1953
2111
  }
1954
2112
  const coPackageJsonPath = path2.join(projectRoot, "custom-objects", "package.json");
@@ -2009,7 +2167,7 @@ async function analyzeAndInjectManifest(options) {
2009
2167
  };
2010
2168
  }
2011
2169
  async function writeCustomObjectArtifacts(options, state) {
2012
- const context = options.context ?? (0, import_extensibility_tool_utils7._createCliContext)();
2170
+ const context = options.context ?? (0, import_extensibility_tool_utils6._createCliContext)();
2013
2171
  const targetPath = path2.resolve(options.targetPath);
2014
2172
  const { packageBuild, customObjects, coVersion, coDependencies, projectRoot } = state;
2015
2173
  for (const obj of customObjects) {
@@ -2085,16 +2243,18 @@ function readPackageDependencies(packageJsonPath) {
2085
2243
  }
2086
2244
 
2087
2245
  // src/bin/create-upload-image.ts
2246
+ var logger = (0, import_extensibility_tool_utils7._createLogger)({ name: "create-upload-image" });
2088
2247
  async function main() {
2248
+ const ctx = (0, import_extensibility_tool_utils7._createCliContext)();
2089
2249
  const targetPath = process.argv[2];
2090
2250
  if (!targetPath) {
2091
- console.error("Usage: create-upload-image <target-path>");
2251
+ ctx.ux.error("Usage: create-upload-image <target-path>");
2092
2252
  process.exit(1);
2093
2253
  }
2094
2254
  let state = null;
2095
2255
  const manifestPath = "stripe-app.yaml";
2096
2256
  if (fs3.existsSync(manifestPath)) {
2097
- state = await analyzeAndInjectManifest({ manifestPath });
2257
+ state = await analyzeAndInjectManifest({ manifestPath, context: ctx });
2098
2258
  }
2099
2259
  fs3.mkdirSync(targetPath, { recursive: true });
2100
2260
  const tarball = path3.join(os2.tmpdir(), `upload-image-${String(Date.now())}.tgz`);
@@ -2127,7 +2287,7 @@ async function main() {
2127
2287
  }
2128
2288
  }
2129
2289
  if (state) {
2130
- await writeCustomObjectArtifacts({ targetPath }, state);
2290
+ await writeCustomObjectArtifacts({ targetPath, context: ctx }, state);
2131
2291
  }
2132
2292
  const imageMetadata = JSON.stringify(
2133
2293
  { image: { version: "1.0", built: (/* @__PURE__ */ new Date()).toISOString() } },
@@ -2137,6 +2297,6 @@ async function main() {
2137
2297
  fs3.writeFileSync(path3.join(targetPath, ".image.json"), imageMetadata + "\n");
2138
2298
  }
2139
2299
  main().catch((err) => {
2140
- console.error(err);
2300
+ logger.error({ err }, "Unexpected error");
2141
2301
  process.exit(1);
2142
2302
  });