@sundaeswap/sprinkles 0.5.0 → 0.6.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 (112) hide show
  1. package/dist/cjs/Sprinkle/__tests__/encryption.test.js +3 -1
  2. package/dist/cjs/Sprinkle/__tests__/encryption.test.js.map +1 -1
  3. package/dist/cjs/Sprinkle/__tests__/enhancements.test.js +3 -37
  4. package/dist/cjs/Sprinkle/__tests__/enhancements.test.js.map +1 -1
  5. package/dist/cjs/Sprinkle/__tests__/field-utils.test.js +170 -0
  6. package/dist/cjs/Sprinkle/__tests__/field-utils.test.js.map +1 -0
  7. package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js +377 -84
  8. package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
  9. package/dist/cjs/Sprinkle/__tests__/formatting.test.js +97 -0
  10. package/dist/cjs/Sprinkle/__tests__/formatting.test.js.map +1 -0
  11. package/dist/cjs/Sprinkle/__tests__/show-menu.test.js +9 -5
  12. package/dist/cjs/Sprinkle/__tests__/show-menu.test.js.map +1 -1
  13. package/dist/cjs/Sprinkle/__tests__/tx-dialog.test.js +9 -0
  14. package/dist/cjs/Sprinkle/__tests__/tx-dialog.test.js.map +1 -1
  15. package/dist/cjs/Sprinkle/index.js +174 -94
  16. package/dist/cjs/Sprinkle/index.js.map +1 -1
  17. package/dist/cjs/Sprinkle/menus/array-menu.js +195 -0
  18. package/dist/cjs/Sprinkle/menus/array-menu.js.map +1 -0
  19. package/dist/cjs/Sprinkle/menus/field-menu.js +161 -0
  20. package/dist/cjs/Sprinkle/menus/field-menu.js.map +1 -0
  21. package/dist/cjs/Sprinkle/menus/index.js +33 -0
  22. package/dist/cjs/Sprinkle/menus/index.js.map +1 -0
  23. package/dist/cjs/Sprinkle/menus/object-menu.js +324 -0
  24. package/dist/cjs/Sprinkle/menus/object-menu.js.map +1 -0
  25. package/dist/cjs/Sprinkle/prompts.js +68 -2
  26. package/dist/cjs/Sprinkle/prompts.js.map +1 -1
  27. package/dist/cjs/Sprinkle/type-guards.js +48 -1
  28. package/dist/cjs/Sprinkle/type-guards.js.map +1 -1
  29. package/dist/cjs/Sprinkle/types.js +24 -0
  30. package/dist/cjs/Sprinkle/types.js.map +1 -1
  31. package/dist/cjs/Sprinkle/utils/field-utils.js +154 -0
  32. package/dist/cjs/Sprinkle/utils/field-utils.js.map +1 -0
  33. package/dist/cjs/Sprinkle/utils/formatting.js +126 -0
  34. package/dist/cjs/Sprinkle/utils/formatting.js.map +1 -0
  35. package/dist/cjs/Sprinkle/utils/index.js +56 -0
  36. package/dist/cjs/Sprinkle/utils/index.js.map +1 -0
  37. package/dist/esm/Sprinkle/__tests__/encryption.test.js +3 -1
  38. package/dist/esm/Sprinkle/__tests__/encryption.test.js.map +1 -1
  39. package/dist/esm/Sprinkle/__tests__/enhancements.test.js +3 -37
  40. package/dist/esm/Sprinkle/__tests__/enhancements.test.js.map +1 -1
  41. package/dist/esm/Sprinkle/__tests__/field-utils.test.js +168 -0
  42. package/dist/esm/Sprinkle/__tests__/field-utils.test.js.map +1 -0
  43. package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js +378 -85
  44. package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
  45. package/dist/esm/Sprinkle/__tests__/formatting.test.js +95 -0
  46. package/dist/esm/Sprinkle/__tests__/formatting.test.js.map +1 -0
  47. package/dist/esm/Sprinkle/__tests__/show-menu.test.js +9 -5
  48. package/dist/esm/Sprinkle/__tests__/show-menu.test.js.map +1 -1
  49. package/dist/esm/Sprinkle/__tests__/tx-dialog.test.js +9 -0
  50. package/dist/esm/Sprinkle/__tests__/tx-dialog.test.js.map +1 -1
  51. package/dist/esm/Sprinkle/index.js +141 -96
  52. package/dist/esm/Sprinkle/index.js.map +1 -1
  53. package/dist/esm/Sprinkle/menus/array-menu.js +190 -0
  54. package/dist/esm/Sprinkle/menus/array-menu.js.map +1 -0
  55. package/dist/esm/Sprinkle/menus/field-menu.js +155 -0
  56. package/dist/esm/Sprinkle/menus/field-menu.js.map +1 -0
  57. package/dist/esm/Sprinkle/menus/index.js +8 -0
  58. package/dist/esm/Sprinkle/menus/index.js.map +1 -0
  59. package/dist/esm/Sprinkle/menus/object-menu.js +318 -0
  60. package/dist/esm/Sprinkle/menus/object-menu.js.map +1 -0
  61. package/dist/esm/Sprinkle/prompts.js +59 -1
  62. package/dist/esm/Sprinkle/prompts.js.map +1 -1
  63. package/dist/esm/Sprinkle/type-guards.js +42 -0
  64. package/dist/esm/Sprinkle/type-guards.js.map +1 -1
  65. package/dist/esm/Sprinkle/types.js +24 -0
  66. package/dist/esm/Sprinkle/types.js.map +1 -1
  67. package/dist/esm/Sprinkle/utils/field-utils.js +145 -0
  68. package/dist/esm/Sprinkle/utils/field-utils.js.map +1 -0
  69. package/dist/esm/Sprinkle/utils/formatting.js +118 -0
  70. package/dist/esm/Sprinkle/utils/formatting.js.map +1 -0
  71. package/dist/esm/Sprinkle/utils/index.js +7 -0
  72. package/dist/esm/Sprinkle/utils/index.js.map +1 -0
  73. package/dist/types/Sprinkle/index.d.ts +9 -3
  74. package/dist/types/Sprinkle/index.d.ts.map +1 -1
  75. package/dist/types/Sprinkle/menus/array-menu.d.ts +31 -0
  76. package/dist/types/Sprinkle/menus/array-menu.d.ts.map +1 -0
  77. package/dist/types/Sprinkle/menus/field-menu.d.ts +34 -0
  78. package/dist/types/Sprinkle/menus/field-menu.d.ts.map +1 -0
  79. package/dist/types/Sprinkle/menus/index.d.ts +10 -0
  80. package/dist/types/Sprinkle/menus/index.d.ts.map +1 -0
  81. package/dist/types/Sprinkle/menus/object-menu.d.ts +34 -0
  82. package/dist/types/Sprinkle/menus/object-menu.d.ts.map +1 -0
  83. package/dist/types/Sprinkle/prompts.d.ts +25 -0
  84. package/dist/types/Sprinkle/prompts.d.ts.map +1 -1
  85. package/dist/types/Sprinkle/type-guards.d.ts +24 -1
  86. package/dist/types/Sprinkle/type-guards.d.ts.map +1 -1
  87. package/dist/types/Sprinkle/types.d.ts +53 -0
  88. package/dist/types/Sprinkle/types.d.ts.map +1 -1
  89. package/dist/types/Sprinkle/utils/field-utils.d.ts +47 -0
  90. package/dist/types/Sprinkle/utils/field-utils.d.ts.map +1 -0
  91. package/dist/types/Sprinkle/utils/formatting.d.ts +30 -0
  92. package/dist/types/Sprinkle/utils/formatting.d.ts.map +1 -0
  93. package/dist/types/tsconfig.build.tsbuildinfo +1 -1
  94. package/package.json +1 -1
  95. package/src/Sprinkle/__tests__/encryption.test.ts +2 -0
  96. package/src/Sprinkle/__tests__/enhancements.test.ts +3 -42
  97. package/src/Sprinkle/__tests__/field-utils.test.ts +191 -0
  98. package/src/Sprinkle/__tests__/fill-in-struct.test.ts +393 -100
  99. package/src/Sprinkle/__tests__/formatting.test.ts +115 -0
  100. package/src/Sprinkle/__tests__/show-menu.test.ts +14 -8
  101. package/src/Sprinkle/__tests__/tx-dialog.test.ts +9 -0
  102. package/src/Sprinkle/index.ts +175 -122
  103. package/src/Sprinkle/menus/array-menu.ts +191 -0
  104. package/src/Sprinkle/menus/field-menu.ts +145 -0
  105. package/src/Sprinkle/menus/index.ts +12 -0
  106. package/src/Sprinkle/menus/object-menu.ts +336 -0
  107. package/src/Sprinkle/prompts.ts +71 -1
  108. package/src/Sprinkle/type-guards.ts +42 -0
  109. package/src/Sprinkle/types.ts +43 -0
  110. package/src/Sprinkle/utils/field-utils.ts +158 -0
  111. package/src/Sprinkle/utils/formatting.ts +127 -0
  112. package/src/Sprinkle/utils/index.ts +17 -0
@@ -22,7 +22,9 @@ _bunTest.mock.module("../prompts.js", () => ({
22
22
  selectCancellable: mockSelectCancellable,
23
23
  inputCancellable: mockInputCancellable,
24
24
  passwordCancellable: mockPasswordCancellable,
25
- confirmCancellable: (0, _bunTest.mock)()
25
+ confirmCancellable: (0, _bunTest.mock)(),
26
+ searchCancellable: (0, _bunTest.mock)(),
27
+ select: mockSelectCancellable
26
28
  }));
27
29
  (0, _bunTest.describe)("Encryption & Sensitive Fields", () => {
28
30
  let tmpDir;
@@ -1 +1 @@
1
- {"version":3,"file":"encryption.test.js","names":["_bunTest","require","_index","fs","_interopRequireWildcard","path","os","_testHelpers","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","mockSelect","mock","mockInput","mockPassword","mockSelectCancellable","mockInputCancellable","mockPasswordCancellable","module","select","input","password","selectCancellable","inputCancellable","passwordCancellable","confirmCancellable","describe","tmpDir","beforeEach","mkdtempSync","join","tmpdir","mockClear","afterEach","rmSync","recursive","force","test","schema","Type","secret","String","sensitive","title","sprinkle","Sprinkle","mockResolvedValueOnce","result","FillInStruct","expect","toEqual","toHaveBeenCalledTimes","calls","message","toBe","not","toHaveBeenCalled","name","p","defaults","toBeUndefined","withProfile","encryption","encrypt","plain","decrypt","cipher","replace","settings","saveSettings","content","readFileSync","parsed","JSON","parse","sprinkle1","sprinkle2","loadProfile","wallet","key","address","Union","type","Literal","privateKey","outerSchema","network","count","BigInt","opts","Buffer","from","toString","s1","s2","mkdirSync","writeFileSync","stringify","New","c","options","toBeDefined","profileId"],"sources":["../../../../src/Sprinkle/__tests__/encryption.test.ts"],"sourcesContent":["import { describe, expect, test, mock, beforeEach, afterEach } from \"bun:test\";\nimport { Sprinkle, Type } from \"../index.js\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport { withProfile } from \"./test-helpers.js\";\n\nconst mockSelect = mock();\nconst mockInput = mock();\nconst mockPassword = mock();\nconst mockSelectCancellable = mock();\nconst mockInputCancellable = mock();\nconst mockPasswordCancellable = mock();\n\nmock.module(\"@inquirer/prompts\", () => ({\n select: mockSelect,\n input: mockInput,\n password: mockPassword,\n}));\n\nmock.module(\"../prompts.js\", () => ({\n selectCancellable: mockSelectCancellable,\n inputCancellable: mockInputCancellable,\n passwordCancellable: mockPasswordCancellable,\n confirmCancellable: mock(),\n}));\n\ndescribe(\"Encryption & Sensitive Fields\", () => {\n let tmpDir: string;\n\n beforeEach(() => {\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sprinkles-enc-test-\"));\n mockSelect.mockClear();\n mockInput.mockClear();\n mockPassword.mockClear();\n mockSelectCancellable.mockClear();\n mockInputCancellable.mockClear();\n mockPasswordCancellable.mockClear();\n });\n\n afterEach(() => {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n });\n\n describe(\"sensitive field prompts\", () => {\n test(\"uses password() for sensitive string fields\", async () => {\n const schema = Type.Object({\n secret: Type.String({ sensitive: true, title: \"Enter secret\" }),\n });\n const sprinkle = new Sprinkle(schema, tmpDir);\n\n mockPasswordCancellable.mockResolvedValueOnce(\"my-secret\");\n\n const result = await sprinkle.FillInStruct(schema);\n expect(result).toEqual({ secret: \"my-secret\" });\n expect(mockPasswordCancellable).toHaveBeenCalledTimes(1);\n expect(mockPasswordCancellable.mock.calls[0][0].message).toBe(\"Enter secret\");\n expect(mockInputCancellable).not.toHaveBeenCalled();\n });\n\n test(\"uses input() for non-sensitive string fields\", async () => {\n const schema = Type.Object({\n name: Type.String({ title: \"Enter name\" }),\n });\n const sprinkle = new Sprinkle(schema, tmpDir);\n\n mockInputCancellable.mockResolvedValueOnce(\"visible\");\n\n const result = await sprinkle.FillInStruct(schema);\n expect(result).toEqual({ name: \"visible\" });\n expect(mockInputCancellable).toHaveBeenCalledTimes(1);\n expect(mockPasswordCancellable).not.toHaveBeenCalled();\n });\n\n test(\"does not remember sensitive field as default\", async () => {\n const schema = Type.String({ sensitive: true });\n const sprinkle = new Sprinkle(Type.Object({ p: Type.String() }), tmpDir);\n\n mockPasswordCancellable.mockResolvedValueOnce(\"secret-val\");\n\n await sprinkle.FillInStruct(schema);\n expect(sprinkle.defaults[\"string\"]).toBeUndefined();\n });\n });\n\n describe(\"encryption on save/load\", () => {\n test(\"encrypts sensitive fields when saving with encryption configured\", () => {\n const schema = Type.Object({\n name: Type.String(),\n secret: Type.String({ sensitive: true }),\n });\n const sprinkle = withProfile(\n new Sprinkle(schema, tmpDir, {\n encryption: {\n encrypt: (plain) => `ENC:${plain}`,\n decrypt: async (cipher) => cipher.replace(\"ENC:\", \"\"),\n },\n }),\n );\n sprinkle.settings = { name: \"visible\", secret: \"hidden\" } as any;\n\n sprinkle.saveSettings();\n\n const content = fs.readFileSync(\n path.join(tmpDir, \"profiles\", \"test.json\"),\n \"utf-8\",\n );\n const parsed = JSON.parse(content);\n expect(parsed.settings.name).toBe(\"visible\");\n expect(parsed.settings.secret).toBe(\"ENC:hidden\");\n });\n\n test(\"decrypts sensitive fields when loading with encryption configured\", async () => {\n const schema = Type.Object({\n name: Type.String(),\n secret: Type.String({ sensitive: true }),\n });\n\n // First save with encryption\n const sprinkle1 = withProfile(\n new Sprinkle(schema, tmpDir, {\n encryption: {\n encrypt: (plain) => `ENC:${plain}`,\n decrypt: async (cipher) => cipher.replace(\"ENC:\", \"\"),\n },\n }),\n );\n sprinkle1.settings = { name: \"visible\", secret: \"hidden\" } as any;\n sprinkle1.saveSettings();\n\n // Then load with same encryption\n const sprinkle2 = new Sprinkle(schema, tmpDir, {\n encryption: {\n encrypt: (plain) => `ENC:${plain}`,\n decrypt: async (cipher) => cipher.replace(\"ENC:\", \"\"),\n },\n });\n await sprinkle2.loadProfile(\"test\");\n\n expect(sprinkle2.settings).toEqual({ name: \"visible\", secret: \"hidden\" });\n });\n\n test(\"does not encrypt when no encryption configured\", () => {\n const schema = Type.Object({\n secret: Type.String({ sensitive: true }),\n });\n const sprinkle = withProfile(new Sprinkle(schema, tmpDir));\n sprinkle.settings = { secret: \"plain-value\" } as any;\n\n sprinkle.saveSettings();\n\n const content = fs.readFileSync(\n path.join(tmpDir, \"profiles\", \"test.json\"),\n \"utf-8\",\n );\n const parsed = JSON.parse(content);\n expect(parsed.settings.secret).toBe(\"plain-value\");\n });\n\n test(\"encrypts nested sensitive fields\", () => {\n const schema = Type.Object({\n wallet: Type.Object({\n key: Type.String({ sensitive: true }),\n address: Type.String(),\n }),\n });\n const sprinkle = withProfile(\n new Sprinkle(schema, tmpDir, {\n encryption: {\n encrypt: (plain) => `ENC:${plain}`,\n decrypt: async (cipher) => cipher.replace(\"ENC:\", \"\"),\n },\n }),\n );\n sprinkle.settings = {\n wallet: { key: \"secret-key\", address: \"addr1...\" },\n } as any;\n\n sprinkle.saveSettings();\n\n const content = fs.readFileSync(\n path.join(tmpDir, \"profiles\", \"test.json\"),\n \"utf-8\",\n );\n const parsed = JSON.parse(content);\n expect(parsed.settings.wallet.key).toBe(\"ENC:secret-key\");\n expect(parsed.settings.wallet.address).toBe(\"addr1...\");\n });\n\n test(\"handles sensitive fields in union variants\", () => {\n const schema = Type.Union([\n Type.Object({\n type: Type.Literal(\"hot\"),\n privateKey: Type.String({ sensitive: true }),\n }),\n Type.Object({\n type: Type.Literal(\"cold\"),\n address: Type.String(),\n }),\n ]);\n const outerSchema = Type.Object({ wallet: schema });\n const sprinkle = withProfile(\n new Sprinkle(outerSchema, tmpDir, {\n encryption: {\n encrypt: (plain) => `ENC:${plain}`,\n decrypt: async (cipher) => cipher.replace(\"ENC:\", \"\"),\n },\n }),\n );\n sprinkle.settings = {\n wallet: { type: \"hot\", privateKey: \"my-key\" },\n } as any;\n\n sprinkle.saveSettings();\n\n const content = fs.readFileSync(\n path.join(tmpDir, \"profiles\", \"test.json\"),\n \"utf-8\",\n );\n const parsed = JSON.parse(content);\n expect(parsed.settings.wallet.privateKey).toBe(\"ENC:my-key\");\n });\n\n test(\"round-trip with encryption preserves all data\", async () => {\n const schema = Type.Object({\n network: Type.String(),\n secret: Type.String({ sensitive: true }),\n count: Type.BigInt(),\n });\n const opts = {\n encryption: {\n encrypt: (plain: string) => Buffer.from(plain).toString(\"base64\"),\n decrypt: async (cipher: string) =>\n Buffer.from(cipher, \"base64\").toString(),\n },\n };\n const s1 = withProfile(new Sprinkle(schema, tmpDir, opts));\n s1.settings = {\n network: \"mainnet\",\n secret: \"top-secret\",\n count: 42n,\n } as any;\n s1.saveSettings();\n\n const s2 = new Sprinkle(schema, tmpDir, opts);\n await s2.loadProfile(\"test\");\n\n expect(s2.settings).toEqual({\n network: \"mainnet\",\n secret: \"top-secret\",\n count: 42n,\n });\n });\n });\n\n describe(\"Sprinkle.New with options\", () => {\n test(\"passes options through to instance and migrates legacy\", async () => {\n const schema = Type.Object({ name: Type.String() });\n\n // Write legacy settings file so New triggers migration\n fs.mkdirSync(tmpDir, { recursive: true });\n fs.writeFileSync(\n path.join(tmpDir, \"settings.json\"),\n JSON.stringify({ settings: { name: \"test\" }, defaults: {} }),\n );\n\n const sprinkle = await Sprinkle.New(schema, tmpDir, {\n encryption: {\n encrypt: (p) => p,\n decrypt: async (c) => c,\n },\n });\n\n expect(sprinkle.options.encryption).toBeDefined();\n expect(sprinkle.profileId).toBe(\"default\");\n expect(sprinkle.settings).toEqual({ name: \"test\" });\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"encryption.test.js","names":["_bunTest","require","_index","fs","_interopRequireWildcard","path","os","_testHelpers","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","mockSelect","mock","mockInput","mockPassword","mockSelectCancellable","mockInputCancellable","mockPasswordCancellable","module","select","input","password","selectCancellable","inputCancellable","passwordCancellable","confirmCancellable","searchCancellable","describe","tmpDir","beforeEach","mkdtempSync","join","tmpdir","mockClear","afterEach","rmSync","recursive","force","test","schema","Type","secret","String","sensitive","title","sprinkle","Sprinkle","mockResolvedValueOnce","result","FillInStruct","expect","toEqual","toHaveBeenCalledTimes","calls","message","toBe","not","toHaveBeenCalled","name","p","defaults","toBeUndefined","withProfile","encryption","encrypt","plain","decrypt","cipher","replace","settings","saveSettings","content","readFileSync","parsed","JSON","parse","sprinkle1","sprinkle2","loadProfile","wallet","key","address","Union","type","Literal","privateKey","outerSchema","network","count","BigInt","opts","Buffer","from","toString","s1","s2","mkdirSync","writeFileSync","stringify","New","c","options","toBeDefined","profileId"],"sources":["../../../../src/Sprinkle/__tests__/encryption.test.ts"],"sourcesContent":["import { describe, expect, test, mock, beforeEach, afterEach } from \"bun:test\";\nimport { Sprinkle, Type } from \"../index.js\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport { withProfile } from \"./test-helpers.js\";\n\nconst mockSelect = mock();\nconst mockInput = mock();\nconst mockPassword = mock();\nconst mockSelectCancellable = mock();\nconst mockInputCancellable = mock();\nconst mockPasswordCancellable = mock();\n\nmock.module(\"@inquirer/prompts\", () => ({\n select: mockSelect,\n input: mockInput,\n password: mockPassword,\n}));\n\nmock.module(\"../prompts.js\", () => ({\n selectCancellable: mockSelectCancellable,\n inputCancellable: mockInputCancellable,\n passwordCancellable: mockPasswordCancellable,\n confirmCancellable: mock(),\n searchCancellable: mock(),\n select: mockSelectCancellable,\n}));\n\ndescribe(\"Encryption & Sensitive Fields\", () => {\n let tmpDir: string;\n\n beforeEach(() => {\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sprinkles-enc-test-\"));\n mockSelect.mockClear();\n mockInput.mockClear();\n mockPassword.mockClear();\n mockSelectCancellable.mockClear();\n mockInputCancellable.mockClear();\n mockPasswordCancellable.mockClear();\n });\n\n afterEach(() => {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n });\n\n describe(\"sensitive field prompts\", () => {\n test(\"uses password() for sensitive string fields\", async () => {\n const schema = Type.Object({\n secret: Type.String({ sensitive: true, title: \"Enter secret\" }),\n });\n const sprinkle = new Sprinkle(schema, tmpDir);\n\n mockPasswordCancellable.mockResolvedValueOnce(\"my-secret\");\n\n const result = await sprinkle.FillInStruct(schema);\n expect(result).toEqual({ secret: \"my-secret\" });\n expect(mockPasswordCancellable).toHaveBeenCalledTimes(1);\n expect(mockPasswordCancellable.mock.calls[0][0].message).toBe(\"Enter secret\");\n expect(mockInputCancellable).not.toHaveBeenCalled();\n });\n\n test(\"uses input() for non-sensitive string fields\", async () => {\n const schema = Type.Object({\n name: Type.String({ title: \"Enter name\" }),\n });\n const sprinkle = new Sprinkle(schema, tmpDir);\n\n mockInputCancellable.mockResolvedValueOnce(\"visible\");\n\n const result = await sprinkle.FillInStruct(schema);\n expect(result).toEqual({ name: \"visible\" });\n expect(mockInputCancellable).toHaveBeenCalledTimes(1);\n expect(mockPasswordCancellable).not.toHaveBeenCalled();\n });\n\n test(\"does not remember sensitive field as default\", async () => {\n const schema = Type.String({ sensitive: true });\n const sprinkle = new Sprinkle(Type.Object({ p: Type.String() }), tmpDir);\n\n mockPasswordCancellable.mockResolvedValueOnce(\"secret-val\");\n\n await sprinkle.FillInStruct(schema);\n expect(sprinkle.defaults[\"string\"]).toBeUndefined();\n });\n });\n\n describe(\"encryption on save/load\", () => {\n test(\"encrypts sensitive fields when saving with encryption configured\", () => {\n const schema = Type.Object({\n name: Type.String(),\n secret: Type.String({ sensitive: true }),\n });\n const sprinkle = withProfile(\n new Sprinkle(schema, tmpDir, {\n encryption: {\n encrypt: (plain) => `ENC:${plain}`,\n decrypt: async (cipher) => cipher.replace(\"ENC:\", \"\"),\n },\n }),\n );\n sprinkle.settings = { name: \"visible\", secret: \"hidden\" } as any;\n\n sprinkle.saveSettings();\n\n const content = fs.readFileSync(\n path.join(tmpDir, \"profiles\", \"test.json\"),\n \"utf-8\",\n );\n const parsed = JSON.parse(content);\n expect(parsed.settings.name).toBe(\"visible\");\n expect(parsed.settings.secret).toBe(\"ENC:hidden\");\n });\n\n test(\"decrypts sensitive fields when loading with encryption configured\", async () => {\n const schema = Type.Object({\n name: Type.String(),\n secret: Type.String({ sensitive: true }),\n });\n\n // First save with encryption\n const sprinkle1 = withProfile(\n new Sprinkle(schema, tmpDir, {\n encryption: {\n encrypt: (plain) => `ENC:${plain}`,\n decrypt: async (cipher) => cipher.replace(\"ENC:\", \"\"),\n },\n }),\n );\n sprinkle1.settings = { name: \"visible\", secret: \"hidden\" } as any;\n sprinkle1.saveSettings();\n\n // Then load with same encryption\n const sprinkle2 = new Sprinkle(schema, tmpDir, {\n encryption: {\n encrypt: (plain) => `ENC:${plain}`,\n decrypt: async (cipher) => cipher.replace(\"ENC:\", \"\"),\n },\n });\n await sprinkle2.loadProfile(\"test\");\n\n expect(sprinkle2.settings).toEqual({ name: \"visible\", secret: \"hidden\" });\n });\n\n test(\"does not encrypt when no encryption configured\", () => {\n const schema = Type.Object({\n secret: Type.String({ sensitive: true }),\n });\n const sprinkle = withProfile(new Sprinkle(schema, tmpDir));\n sprinkle.settings = { secret: \"plain-value\" } as any;\n\n sprinkle.saveSettings();\n\n const content = fs.readFileSync(\n path.join(tmpDir, \"profiles\", \"test.json\"),\n \"utf-8\",\n );\n const parsed = JSON.parse(content);\n expect(parsed.settings.secret).toBe(\"plain-value\");\n });\n\n test(\"encrypts nested sensitive fields\", () => {\n const schema = Type.Object({\n wallet: Type.Object({\n key: Type.String({ sensitive: true }),\n address: Type.String(),\n }),\n });\n const sprinkle = withProfile(\n new Sprinkle(schema, tmpDir, {\n encryption: {\n encrypt: (plain) => `ENC:${plain}`,\n decrypt: async (cipher) => cipher.replace(\"ENC:\", \"\"),\n },\n }),\n );\n sprinkle.settings = {\n wallet: { key: \"secret-key\", address: \"addr1...\" },\n } as any;\n\n sprinkle.saveSettings();\n\n const content = fs.readFileSync(\n path.join(tmpDir, \"profiles\", \"test.json\"),\n \"utf-8\",\n );\n const parsed = JSON.parse(content);\n expect(parsed.settings.wallet.key).toBe(\"ENC:secret-key\");\n expect(parsed.settings.wallet.address).toBe(\"addr1...\");\n });\n\n test(\"handles sensitive fields in union variants\", () => {\n const schema = Type.Union([\n Type.Object({\n type: Type.Literal(\"hot\"),\n privateKey: Type.String({ sensitive: true }),\n }),\n Type.Object({\n type: Type.Literal(\"cold\"),\n address: Type.String(),\n }),\n ]);\n const outerSchema = Type.Object({ wallet: schema });\n const sprinkle = withProfile(\n new Sprinkle(outerSchema, tmpDir, {\n encryption: {\n encrypt: (plain) => `ENC:${plain}`,\n decrypt: async (cipher) => cipher.replace(\"ENC:\", \"\"),\n },\n }),\n );\n sprinkle.settings = {\n wallet: { type: \"hot\", privateKey: \"my-key\" },\n } as any;\n\n sprinkle.saveSettings();\n\n const content = fs.readFileSync(\n path.join(tmpDir, \"profiles\", \"test.json\"),\n \"utf-8\",\n );\n const parsed = JSON.parse(content);\n expect(parsed.settings.wallet.privateKey).toBe(\"ENC:my-key\");\n });\n\n test(\"round-trip with encryption preserves all data\", async () => {\n const schema = Type.Object({\n network: Type.String(),\n secret: Type.String({ sensitive: true }),\n count: Type.BigInt(),\n });\n const opts = {\n encryption: {\n encrypt: (plain: string) => Buffer.from(plain).toString(\"base64\"),\n decrypt: async (cipher: string) =>\n Buffer.from(cipher, \"base64\").toString(),\n },\n };\n const s1 = withProfile(new Sprinkle(schema, tmpDir, opts));\n s1.settings = {\n network: \"mainnet\",\n secret: \"top-secret\",\n count: 42n,\n } as any;\n s1.saveSettings();\n\n const s2 = new Sprinkle(schema, tmpDir, opts);\n await s2.loadProfile(\"test\");\n\n expect(s2.settings).toEqual({\n network: \"mainnet\",\n secret: \"top-secret\",\n count: 42n,\n });\n });\n });\n\n describe(\"Sprinkle.New with options\", () => {\n test(\"passes options through to instance and migrates legacy\", async () => {\n const schema = Type.Object({ name: Type.String() });\n\n // Write legacy settings file so New triggers migration\n fs.mkdirSync(tmpDir, { recursive: true });\n fs.writeFileSync(\n path.join(tmpDir, \"settings.json\"),\n JSON.stringify({ settings: { name: \"test\" }, defaults: {} }),\n );\n\n const sprinkle = await Sprinkle.New(schema, tmpDir, {\n encryption: {\n encrypt: (p) => p,\n decrypt: async (c) => c,\n },\n });\n\n expect(sprinkle.options.encryption).toBeDefined();\n expect(sprinkle.profileId).toBe(\"default\");\n expect(sprinkle.settings).toEqual({ name: \"test\" });\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
@@ -131,42 +131,8 @@ _bunTest.mock.module("../prompts.js", () => ({
131
131
  (0, _bunTest.expect)(result).toBeNull();
132
132
  });
133
133
  });
134
- (0, _bunTest.describe)("Optional type support (2.4)", () => {
135
- let sprinkle;
136
- (0, _bunTest.beforeEach)(() => {
137
- const schema = _index.Type.Object({
138
- placeholder: _index.Type.String()
139
- });
140
- sprinkle = new _index.Sprinkle(schema, "/tmp/test");
141
- mockSelect.mockClear();
142
- mockInput.mockClear();
143
- mockSelectCancellable.mockClear();
144
- mockInputCancellable.mockClear();
145
- });
146
- (0, _bunTest.test)("skips optional field when user selects Skip", async () => {
147
- const schema = _index.Type.Object({
148
- name: _index.Type.String(),
149
- nickname: _index.Type.Optional(_index.Type.String())
150
- });
151
- mockInputCancellable.mockResolvedValueOnce("Alice"); // name
152
- mockSelectCancellable.mockResolvedValueOnce(false); // skip nickname
153
-
154
- const result = await sprinkle.FillInStruct(schema);
155
- (0, _bunTest.expect)(result.name).toBe("Alice");
156
- (0, _bunTest.expect)(result.nickname).toBeUndefined();
157
- });
158
- (0, _bunTest.test)("fills optional field when user selects Yes", async () => {
159
- const schema = _index.Type.Object({
160
- name: _index.Type.String(),
161
- nickname: _index.Type.Optional(_index.Type.String())
162
- });
163
- mockInputCancellable.mockResolvedValueOnce("Alice") // name
164
- .mockResolvedValueOnce("Ali"); // nickname
165
- mockSelectCancellable.mockResolvedValueOnce(true); // fill nickname
166
134
 
167
- const result = await sprinkle.FillInStruct(schema);
168
- (0, _bunTest.expect)(result.name).toBe("Alice");
169
- (0, _bunTest.expect)(result.nickname).toBe("Ali");
170
- });
171
- });
135
+ // Note: "Optional type support (2.4)" tests removed - they tested the old sequential
136
+ // FillInStruct behavior. The new menu-based FillInStruct handles optional fields
137
+ // differently (via menu selection). See fill-in-struct.test.ts for comprehensive tests.
172
138
  //# sourceMappingURL=enhancements.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"enhancements.test.js","names":["_bunTest","require","_index","mockSelect","mock","mockInput","mockPassword","mockSelectCancellable","mockInputCancellable","mockPasswordCancellable","mockConfirmCancellable","mockSearchCancellable","module","select","input","password","selectCancellable","inputCancellable","passwordCancellable","confirmCancellable","searchCancellable","describe","sprinkle","beforeEach","schema","Type","Object","name","String","Sprinkle","settings","mockClear","test","callOrder","beforeShowFn","push","mockImplementation","menu","title","beforeShow","items","action","showMenu","expect","toHaveBeenCalledTimes","toBe","receivedSprinkle","mockResolvedValueOnce","s","result","SearchSelect","message","source","value","calls","sourceFn","toBeNull","placeholder","nickname","Optional","FillInStruct","toBeUndefined"],"sources":["../../../../src/Sprinkle/__tests__/enhancements.test.ts"],"sourcesContent":["import { describe, expect, test, mock, beforeEach } from \"bun:test\";\nimport { Sprinkle, Type, type IMenu } from \"../index.js\";\n\nconst mockSelect = mock();\nconst mockInput = mock();\nconst mockPassword = mock();\nconst mockSelectCancellable = mock();\nconst mockInputCancellable = mock();\nconst mockPasswordCancellable = mock();\nconst mockConfirmCancellable = mock();\nconst mockSearchCancellable = mock();\n\nmock.module(\"@inquirer/prompts\", () => ({\n select: mockSelect,\n input: mockInput,\n password: mockPassword,\n}));\n\nmock.module(\"../prompts.js\", () => ({\n selectCancellable: mockSelectCancellable,\n inputCancellable: mockInputCancellable,\n passwordCancellable: mockPasswordCancellable,\n confirmCancellable: mockConfirmCancellable,\n searchCancellable: mockSearchCancellable,\n select: mockSelectCancellable,\n}));\n\ndescribe(\"beforeShow hook (2.2)\", () => {\n let sprinkle: Sprinkle<any>;\n\n beforeEach(() => {\n const schema = Type.Object({ name: Type.String() });\n sprinkle = new Sprinkle(schema, \"/tmp/test\");\n sprinkle.settings = { name: \"test\" } as any;\n mockSelect.mockClear();\n mockSelectCancellable.mockClear();\n });\n\n test(\"calls beforeShow before rendering menu\", async () => {\n const callOrder: string[] = [];\n\n const beforeShowFn = mock(async () => {\n callOrder.push(\"beforeShow\");\n });\n\n mockSelectCancellable.mockImplementation(async () => {\n callOrder.push(\"select\");\n return -1; // exit\n });\n\n const menu: IMenu<any> = {\n title: \"Test\",\n beforeShow: beforeShowFn,\n items: [{ title: \"Action\", action: async () => {} }],\n };\n\n await sprinkle.showMenu(menu);\n\n expect(beforeShowFn).toHaveBeenCalledTimes(1);\n expect(callOrder[0]).toBe(\"beforeShow\");\n expect(callOrder[1]).toBe(\"select\");\n });\n\n test(\"passes sprinkle instance to beforeShow\", async () => {\n let receivedSprinkle: any;\n\n mockSelectCancellable.mockResolvedValueOnce(-1);\n\n const menu: IMenu<any> = {\n title: \"Test\",\n beforeShow: async (s) => {\n receivedSprinkle = s;\n },\n items: [{ title: \"Action\", action: async () => {} }],\n };\n\n await sprinkle.showMenu(menu);\n expect(receivedSprinkle).toBe(sprinkle);\n });\n\n test(\"menu works without beforeShow\", async () => {\n mockSelectCancellable.mockResolvedValueOnce(-1);\n\n const menu: IMenu<any> = {\n title: \"Test\",\n items: [{ title: \"Action\", action: async () => {} }],\n };\n\n await sprinkle.showMenu(menu);\n // Should complete without error\n });\n});\n\ndescribe(\"SearchSelect (2.3)\", () => {\n beforeEach(() => {\n mockSearchCancellable.mockClear();\n });\n\n test(\"delegates to search prompt\", async () => {\n mockSearchCancellable.mockResolvedValueOnce(\"selected-value\");\n\n const result = await Sprinkle.SearchSelect({\n message: \"Pick one\",\n source: () => [\n { name: \"Option A\", value: \"a\" },\n { name: \"Option B\", value: \"b\" },\n ],\n });\n\n expect(result).toBe(\"selected-value\");\n expect(mockSearchCancellable).toHaveBeenCalledTimes(1);\n expect(mockSearchCancellable.mock.calls[0][0].message).toBe(\"Pick one\");\n });\n\n test(\"passes source function through\", async () => {\n const sourceFn = mock(() => [{ name: \"X\", value: \"x\" }]);\n mockSearchCancellable.mockResolvedValueOnce(\"x\");\n\n await Sprinkle.SearchSelect({\n message: \"Search\",\n source: sourceFn,\n });\n\n expect(mockSearchCancellable.mock.calls[0][0].source).toBe(sourceFn);\n });\n\n test(\"returns null when cancelled\", async () => {\n mockSearchCancellable.mockResolvedValueOnce(null);\n\n const result = await Sprinkle.SearchSelect({\n message: \"Pick one\",\n source: () => [{ name: \"A\", value: \"a\" }],\n });\n\n expect(result).toBeNull();\n });\n});\n\ndescribe(\"Optional type support (2.4)\", () => {\n let sprinkle: Sprinkle<any>;\n\n beforeEach(() => {\n const schema = Type.Object({ placeholder: Type.String() });\n sprinkle = new Sprinkle(schema, \"/tmp/test\");\n mockSelect.mockClear();\n mockInput.mockClear();\n mockSelectCancellable.mockClear();\n mockInputCancellable.mockClear();\n });\n\n test(\"skips optional field when user selects Skip\", async () => {\n const schema = Type.Object({\n name: Type.String(),\n nickname: Type.Optional(Type.String()),\n });\n\n mockInputCancellable.mockResolvedValueOnce(\"Alice\"); // name\n mockSelectCancellable.mockResolvedValueOnce(false); // skip nickname\n\n const result = await sprinkle.FillInStruct(schema);\n expect(result.name).toBe(\"Alice\");\n expect(result.nickname).toBeUndefined();\n });\n\n test(\"fills optional field when user selects Yes\", async () => {\n const schema = Type.Object({\n name: Type.String(),\n nickname: Type.Optional(Type.String()),\n });\n\n mockInputCancellable\n .mockResolvedValueOnce(\"Alice\") // name\n .mockResolvedValueOnce(\"Ali\"); // nickname\n mockSelectCancellable.mockResolvedValueOnce(true); // fill nickname\n\n const result = await sprinkle.FillInStruct(schema);\n expect(result.name).toBe(\"Alice\");\n expect(result.nickname).toBe(\"Ali\");\n });\n});\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"enhancements.test.js","names":["_bunTest","require","_index","mockSelect","mock","mockInput","mockPassword","mockSelectCancellable","mockInputCancellable","mockPasswordCancellable","mockConfirmCancellable","mockSearchCancellable","module","select","input","password","selectCancellable","inputCancellable","passwordCancellable","confirmCancellable","searchCancellable","describe","sprinkle","beforeEach","schema","Type","Object","name","String","Sprinkle","settings","mockClear","test","callOrder","beforeShowFn","push","mockImplementation","menu","title","beforeShow","items","action","showMenu","expect","toHaveBeenCalledTimes","toBe","receivedSprinkle","mockResolvedValueOnce","s","result","SearchSelect","message","source","value","calls","sourceFn","toBeNull"],"sources":["../../../../src/Sprinkle/__tests__/enhancements.test.ts"],"sourcesContent":["import { describe, expect, test, mock, beforeEach } from \"bun:test\";\nimport { Sprinkle, Type, type IMenu } from \"../index.js\";\n\nconst mockSelect = mock();\nconst mockInput = mock();\nconst mockPassword = mock();\nconst mockSelectCancellable = mock();\nconst mockInputCancellable = mock();\nconst mockPasswordCancellable = mock();\nconst mockConfirmCancellable = mock();\nconst mockSearchCancellable = mock();\n\nmock.module(\"@inquirer/prompts\", () => ({\n select: mockSelect,\n input: mockInput,\n password: mockPassword,\n}));\n\nmock.module(\"../prompts.js\", () => ({\n selectCancellable: mockSelectCancellable,\n inputCancellable: mockInputCancellable,\n passwordCancellable: mockPasswordCancellable,\n confirmCancellable: mockConfirmCancellable,\n searchCancellable: mockSearchCancellable,\n select: mockSelectCancellable,\n}));\n\ndescribe(\"beforeShow hook (2.2)\", () => {\n let sprinkle: Sprinkle<any>;\n\n beforeEach(() => {\n const schema = Type.Object({ name: Type.String() });\n sprinkle = new Sprinkle(schema, \"/tmp/test\");\n sprinkle.settings = { name: \"test\" } as any;\n mockSelect.mockClear();\n mockSelectCancellable.mockClear();\n });\n\n test(\"calls beforeShow before rendering menu\", async () => {\n const callOrder: string[] = [];\n\n const beforeShowFn = mock(async () => {\n callOrder.push(\"beforeShow\");\n });\n\n mockSelectCancellable.mockImplementation(async () => {\n callOrder.push(\"select\");\n return -1; // exit\n });\n\n const menu: IMenu<any> = {\n title: \"Test\",\n beforeShow: beforeShowFn,\n items: [{ title: \"Action\", action: async () => {} }],\n };\n\n await sprinkle.showMenu(menu);\n\n expect(beforeShowFn).toHaveBeenCalledTimes(1);\n expect(callOrder[0]).toBe(\"beforeShow\");\n expect(callOrder[1]).toBe(\"select\");\n });\n\n test(\"passes sprinkle instance to beforeShow\", async () => {\n let receivedSprinkle: any;\n\n mockSelectCancellable.mockResolvedValueOnce(-1);\n\n const menu: IMenu<any> = {\n title: \"Test\",\n beforeShow: async (s) => {\n receivedSprinkle = s;\n },\n items: [{ title: \"Action\", action: async () => {} }],\n };\n\n await sprinkle.showMenu(menu);\n expect(receivedSprinkle).toBe(sprinkle);\n });\n\n test(\"menu works without beforeShow\", async () => {\n mockSelectCancellable.mockResolvedValueOnce(-1);\n\n const menu: IMenu<any> = {\n title: \"Test\",\n items: [{ title: \"Action\", action: async () => {} }],\n };\n\n await sprinkle.showMenu(menu);\n // Should complete without error\n });\n});\n\ndescribe(\"SearchSelect (2.3)\", () => {\n beforeEach(() => {\n mockSearchCancellable.mockClear();\n });\n\n test(\"delegates to search prompt\", async () => {\n mockSearchCancellable.mockResolvedValueOnce(\"selected-value\");\n\n const result = await Sprinkle.SearchSelect({\n message: \"Pick one\",\n source: () => [\n { name: \"Option A\", value: \"a\" },\n { name: \"Option B\", value: \"b\" },\n ],\n });\n\n expect(result).toBe(\"selected-value\");\n expect(mockSearchCancellable).toHaveBeenCalledTimes(1);\n expect(mockSearchCancellable.mock.calls[0][0].message).toBe(\"Pick one\");\n });\n\n test(\"passes source function through\", async () => {\n const sourceFn = mock(() => [{ name: \"X\", value: \"x\" }]);\n mockSearchCancellable.mockResolvedValueOnce(\"x\");\n\n await Sprinkle.SearchSelect({\n message: \"Search\",\n source: sourceFn,\n });\n\n expect(mockSearchCancellable.mock.calls[0][0].source).toBe(sourceFn);\n });\n\n test(\"returns null when cancelled\", async () => {\n mockSearchCancellable.mockResolvedValueOnce(null);\n\n const result = await Sprinkle.SearchSelect({\n message: \"Pick one\",\n source: () => [{ name: \"A\", value: \"a\" }],\n });\n\n expect(result).toBeNull();\n });\n});\n\n// Note: \"Optional type support (2.4)\" tests removed - they tested the old sequential\n// FillInStruct behavior. The new menu-based FillInStruct handles optional fields\n// differently (via menu selection). See fill-in-struct.test.ts for comprehensive tests.\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+
3
+ var _bunTest = require("bun:test");
4
+ var _typebox = require("@sinclair/typebox");
5
+ var _fieldUtils = require("../utils/field-utils.js");
6
+ (0, _bunTest.describe)("isFieldRequired", () => {
7
+ (0, _bunTest.test)("returns true for plain required field", () => {
8
+ (0, _bunTest.expect)((0, _fieldUtils.isFieldRequired)(_typebox.Type.String())).toBe(true);
9
+ });
10
+ (0, _bunTest.test)("returns false for optional field", () => {
11
+ (0, _bunTest.expect)((0, _fieldUtils.isFieldRequired)(_typebox.Type.Optional(_typebox.Type.String()))).toBe(false);
12
+ });
13
+ (0, _bunTest.test)("returns false for field with default", () => {
14
+ (0, _bunTest.expect)((0, _fieldUtils.isFieldRequired)(_typebox.Type.String({
15
+ default: "hello"
16
+ }))).toBe(false);
17
+ });
18
+ (0, _bunTest.test)("returns true for nullable field with default", () => {
19
+ // Nullable fields with defaults are required because the user should
20
+ // explicitly choose whether to use the value or set null
21
+ const schema = _typebox.Type.Union([_typebox.Type.String({
22
+ default: "hello"
23
+ }), _typebox.Type.Null()]);
24
+ (0, _bunTest.expect)((0, _fieldUtils.isFieldRequired)(schema)).toBe(true);
25
+ });
26
+ });
27
+ (0, _bunTest.describe)("countRequiredFields", () => {
28
+ (0, _bunTest.test)("counts fields in simple object", () => {
29
+ const schema = _typebox.Type.Object({
30
+ name: _typebox.Type.String(),
31
+ age: _typebox.Type.BigInt()
32
+ });
33
+ const state = new Map();
34
+ const result = (0, _fieldUtils.countRequiredFields)(schema, state);
35
+ (0, _bunTest.expect)(result.total).toBe(2);
36
+ (0, _bunTest.expect)(result.filled).toBe(0);
37
+ });
38
+ (0, _bunTest.test)("skips optional fields", () => {
39
+ const schema = _typebox.Type.Object({
40
+ name: _typebox.Type.String(),
41
+ nickname: _typebox.Type.Optional(_typebox.Type.String())
42
+ });
43
+ const state = new Map();
44
+ const result = (0, _fieldUtils.countRequiredFields)(schema, state);
45
+ (0, _bunTest.expect)(result.total).toBe(1);
46
+ });
47
+ (0, _bunTest.test)("skips fields with defaults", () => {
48
+ const schema = _typebox.Type.Object({
49
+ name: _typebox.Type.String(),
50
+ timeout: _typebox.Type.BigInt({
51
+ default: 30n
52
+ })
53
+ });
54
+ const state = new Map();
55
+ const result = (0, _fieldUtils.countRequiredFields)(schema, state);
56
+ (0, _bunTest.expect)(result.total).toBe(1);
57
+ });
58
+ (0, _bunTest.test)("counts filled fields", () => {
59
+ const schema = _typebox.Type.Object({
60
+ name: _typebox.Type.String(),
61
+ age: _typebox.Type.BigInt()
62
+ });
63
+ const state = new Map([["name", {
64
+ status: "set",
65
+ value: "Alice"
66
+ }]]);
67
+ const result = (0, _fieldUtils.countRequiredFields)(schema, state);
68
+ (0, _bunTest.expect)(result.total).toBe(2);
69
+ (0, _bunTest.expect)(result.filled).toBe(1);
70
+ });
71
+ (0, _bunTest.test)("counts null as filled for nullable fields", () => {
72
+ const schema = _typebox.Type.Object({
73
+ name: _typebox.Type.Union([_typebox.Type.String(), _typebox.Type.Null()])
74
+ });
75
+ const state = new Map([["name", {
76
+ status: "null"
77
+ }]]);
78
+ const result = (0, _fieldUtils.countRequiredFields)(schema, state);
79
+ (0, _bunTest.expect)(result.filled).toBe(1);
80
+ });
81
+ });
82
+ (0, _bunTest.describe)("buildFieldLabel", () => {
83
+ (0, _bunTest.test)("shows [not set] with asterisk for required unset field", () => {
84
+ const label = (0, _fieldUtils.buildFieldLabel)("name", _typebox.Type.String(), {
85
+ status: "unset"
86
+ });
87
+ (0, _bunTest.expect)(label).toContain("name");
88
+ (0, _bunTest.expect)(label).toContain("[not set]");
89
+ (0, _bunTest.expect)(label).toContain("*");
90
+ });
91
+ (0, _bunTest.test)("shows [not set] without asterisk for optional field", () => {
92
+ const label = (0, _fieldUtils.buildFieldLabel)("nickname", _typebox.Type.Optional(_typebox.Type.String()), {
93
+ status: "unset"
94
+ });
95
+ (0, _bunTest.expect)(label).toContain("[not set]");
96
+ (0, _bunTest.expect)(label).not.toContain("*");
97
+ });
98
+ (0, _bunTest.test)("shows default value for unset field with default", () => {
99
+ const label = (0, _fieldUtils.buildFieldLabel)("timeout", _typebox.Type.BigInt({
100
+ default: 30n
101
+ }), {
102
+ status: "unset"
103
+ });
104
+ (0, _bunTest.expect)(label).toContain("default");
105
+ (0, _bunTest.expect)(label).toContain("30");
106
+ });
107
+ (0, _bunTest.test)("shows null for null state", () => {
108
+ const label = (0, _fieldUtils.buildFieldLabel)("value", _typebox.Type.Union([_typebox.Type.String(), _typebox.Type.Null()]), {
109
+ status: "null"
110
+ });
111
+ (0, _bunTest.expect)(label).toContain("null");
112
+ });
113
+ (0, _bunTest.test)("shows value preview for set field", () => {
114
+ const label = (0, _fieldUtils.buildFieldLabel)("name", _typebox.Type.String(), {
115
+ status: "set",
116
+ value: "Alice"
117
+ });
118
+ (0, _bunTest.expect)(label).toContain("Alice");
119
+ });
120
+ });
121
+ (0, _bunTest.describe)("getInitialFieldState", () => {
122
+ (0, _bunTest.test)("returns unset for undefined", () => {
123
+ (0, _bunTest.expect)((0, _fieldUtils.getInitialFieldState)(_typebox.Type.String(), undefined)).toEqual({
124
+ status: "unset"
125
+ });
126
+ });
127
+ (0, _bunTest.test)("returns null for null value", () => {
128
+ (0, _bunTest.expect)((0, _fieldUtils.getInitialFieldState)(_typebox.Type.String(), null)).toEqual({
129
+ status: "null"
130
+ });
131
+ });
132
+ (0, _bunTest.test)("returns set with value", () => {
133
+ (0, _bunTest.expect)((0, _fieldUtils.getInitialFieldState)(_typebox.Type.String(), "hello")).toEqual({
134
+ status: "set",
135
+ value: "hello"
136
+ });
137
+ });
138
+ });
139
+ (0, _bunTest.describe)("allRequiredFieldsFilled", () => {
140
+ (0, _bunTest.test)("returns true when all required fields filled", () => {
141
+ const schema = _typebox.Type.Object({
142
+ name: _typebox.Type.String(),
143
+ nickname: _typebox.Type.Optional(_typebox.Type.String())
144
+ });
145
+ const state = new Map([["name", {
146
+ status: "set",
147
+ value: "Alice"
148
+ }]]);
149
+ (0, _bunTest.expect)((0, _fieldUtils.allRequiredFieldsFilled)(schema, state)).toBe(true);
150
+ });
151
+ (0, _bunTest.test)("returns false when required field missing", () => {
152
+ const schema = _typebox.Type.Object({
153
+ name: _typebox.Type.String(),
154
+ age: _typebox.Type.BigInt()
155
+ });
156
+ const state = new Map([["name", {
157
+ status: "set",
158
+ value: "Alice"
159
+ }]]);
160
+ (0, _bunTest.expect)((0, _fieldUtils.allRequiredFieldsFilled)(schema, state)).toBe(false);
161
+ });
162
+ (0, _bunTest.test)("returns true for all-optional schema", () => {
163
+ const schema = _typebox.Type.Object({
164
+ nickname: _typebox.Type.Optional(_typebox.Type.String())
165
+ });
166
+ const state = new Map();
167
+ (0, _bunTest.expect)((0, _fieldUtils.allRequiredFieldsFilled)(schema, state)).toBe(true);
168
+ });
169
+ });
170
+ //# sourceMappingURL=field-utils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-utils.test.js","names":["_bunTest","require","_typebox","_fieldUtils","describe","test","expect","isFieldRequired","Type","String","toBe","Optional","default","schema","Union","Null","Object","name","age","BigInt","state","Map","result","countRequiredFields","total","filled","nickname","timeout","status","value","label","buildFieldLabel","toContain","not","getInitialFieldState","undefined","toEqual","allRequiredFieldsFilled"],"sources":["../../../../src/Sprinkle/__tests__/field-utils.test.ts"],"sourcesContent":["import { describe, expect, test } from \"bun:test\";\nimport { Type } from \"@sinclair/typebox\";\nimport {\n countRequiredFields,\n isFieldRequired,\n buildFieldLabel,\n getInitialFieldState,\n allRequiredFieldsFilled,\n} from \"../utils/field-utils.js\";\nimport type { FieldState } from \"../types.js\";\n\ndescribe(\"isFieldRequired\", () => {\n test(\"returns true for plain required field\", () => {\n expect(isFieldRequired(Type.String())).toBe(true);\n });\n\n test(\"returns false for optional field\", () => {\n expect(isFieldRequired(Type.Optional(Type.String()))).toBe(false);\n });\n\n test(\"returns false for field with default\", () => {\n expect(isFieldRequired(Type.String({ default: \"hello\" }))).toBe(false);\n });\n\n test(\"returns true for nullable field with default\", () => {\n // Nullable fields with defaults are required because the user should\n // explicitly choose whether to use the value or set null\n const schema = Type.Union([Type.String({ default: \"hello\" }), Type.Null()]);\n expect(isFieldRequired(schema)).toBe(true);\n });\n});\n\ndescribe(\"countRequiredFields\", () => {\n test(\"counts fields in simple object\", () => {\n const schema = Type.Object({\n name: Type.String(),\n age: Type.BigInt(),\n });\n const state = new Map<string, FieldState>();\n\n const result = countRequiredFields(schema, state);\n expect(result.total).toBe(2);\n expect(result.filled).toBe(0);\n });\n\n test(\"skips optional fields\", () => {\n const schema = Type.Object({\n name: Type.String(),\n nickname: Type.Optional(Type.String()),\n });\n const state = new Map<string, FieldState>();\n\n const result = countRequiredFields(schema, state);\n expect(result.total).toBe(1);\n });\n\n test(\"skips fields with defaults\", () => {\n const schema = Type.Object({\n name: Type.String(),\n timeout: Type.BigInt({ default: 30n }),\n });\n const state = new Map<string, FieldState>();\n\n const result = countRequiredFields(schema, state);\n expect(result.total).toBe(1);\n });\n\n test(\"counts filled fields\", () => {\n const schema = Type.Object({\n name: Type.String(),\n age: Type.BigInt(),\n });\n const state = new Map<string, FieldState>([\n [\"name\", { status: \"set\", value: \"Alice\" }],\n ]);\n\n const result = countRequiredFields(schema, state);\n expect(result.total).toBe(2);\n expect(result.filled).toBe(1);\n });\n\n test(\"counts null as filled for nullable fields\", () => {\n const schema = Type.Object({\n name: Type.Union([Type.String(), Type.Null()]),\n });\n const state = new Map<string, FieldState>([[\"name\", { status: \"null\" }]]);\n\n const result = countRequiredFields(schema, state);\n expect(result.filled).toBe(1);\n });\n});\n\ndescribe(\"buildFieldLabel\", () => {\n test(\"shows [not set] with asterisk for required unset field\", () => {\n const label = buildFieldLabel(\"name\", Type.String(), { status: \"unset\" });\n expect(label).toContain(\"name\");\n expect(label).toContain(\"[not set]\");\n expect(label).toContain(\"*\");\n });\n\n test(\"shows [not set] without asterisk for optional field\", () => {\n const label = buildFieldLabel(\"nickname\", Type.Optional(Type.String()), {\n status: \"unset\",\n });\n expect(label).toContain(\"[not set]\");\n expect(label).not.toContain(\"*\");\n });\n\n test(\"shows default value for unset field with default\", () => {\n const label = buildFieldLabel(\n \"timeout\",\n Type.BigInt({ default: 30n }),\n { status: \"unset\" },\n );\n expect(label).toContain(\"default\");\n expect(label).toContain(\"30\");\n });\n\n test(\"shows null for null state\", () => {\n const label = buildFieldLabel(\n \"value\",\n Type.Union([Type.String(), Type.Null()]),\n { status: \"null\" },\n );\n expect(label).toContain(\"null\");\n });\n\n test(\"shows value preview for set field\", () => {\n const label = buildFieldLabel(\"name\", Type.String(), {\n status: \"set\",\n value: \"Alice\",\n });\n expect(label).toContain(\"Alice\");\n });\n});\n\ndescribe(\"getInitialFieldState\", () => {\n test(\"returns unset for undefined\", () => {\n expect(getInitialFieldState(Type.String(), undefined)).toEqual({\n status: \"unset\",\n });\n });\n\n test(\"returns null for null value\", () => {\n expect(getInitialFieldState(Type.String(), null)).toEqual({\n status: \"null\",\n });\n });\n\n test(\"returns set with value\", () => {\n expect(getInitialFieldState(Type.String(), \"hello\")).toEqual({\n status: \"set\",\n value: \"hello\",\n });\n });\n});\n\ndescribe(\"allRequiredFieldsFilled\", () => {\n test(\"returns true when all required fields filled\", () => {\n const schema = Type.Object({\n name: Type.String(),\n nickname: Type.Optional(Type.String()),\n });\n const state = new Map<string, FieldState>([\n [\"name\", { status: \"set\", value: \"Alice\" }],\n ]);\n\n expect(allRequiredFieldsFilled(schema, state)).toBe(true);\n });\n\n test(\"returns false when required field missing\", () => {\n const schema = Type.Object({\n name: Type.String(),\n age: Type.BigInt(),\n });\n const state = new Map<string, FieldState>([\n [\"name\", { status: \"set\", value: \"Alice\" }],\n ]);\n\n expect(allRequiredFieldsFilled(schema, state)).toBe(false);\n });\n\n test(\"returns true for all-optional schema\", () => {\n const schema = Type.Object({\n nickname: Type.Optional(Type.String()),\n });\n const state = new Map<string, FieldState>();\n\n expect(allRequiredFieldsFilled(schema, state)).toBe(true);\n });\n});\n"],"mappings":"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","ignoreList":[]}