@kensio/yulin 0.0.2 → 0.1.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 (127) hide show
  1. package/README.md +1 -1
  2. package/dist/command/command-handler.d.ts +4 -0
  3. package/dist/command/command-handler.d.ts.map +1 -0
  4. package/dist/command/command-handler.js +2 -0
  5. package/dist/command/command-handler.js.map +1 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +2 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/service/cloudfront/factory/cloudfront-functions.factory.d.ts +7 -0
  11. package/dist/service/cloudfront/factory/cloudfront-functions.factory.d.ts.map +1 -0
  12. package/dist/service/cloudfront/factory/cloudfront-functions.factory.js +54 -0
  13. package/dist/service/cloudfront/factory/cloudfront-functions.factory.js.map +1 -0
  14. package/dist/service/cloudfront/index.d.ts +3 -0
  15. package/dist/service/cloudfront/index.d.ts.map +1 -0
  16. package/dist/service/cloudfront/index.js +2 -0
  17. package/dist/service/cloudfront/index.js.map +1 -0
  18. package/dist/service/cloudfront/typings/cloudfront-functions.d.ts +37 -0
  19. package/dist/service/cloudfront/typings/cloudfront-functions.d.ts.map +1 -0
  20. package/dist/service/cloudfront/typings/cloudfront-functions.js +2 -0
  21. package/dist/service/cloudfront/typings/cloudfront-functions.js.map +1 -0
  22. package/dist/service/dynamodb/command/create-table/create-table.handler.d.ts +20 -0
  23. package/dist/service/dynamodb/command/create-table/create-table.handler.d.ts.map +1 -0
  24. package/dist/service/dynamodb/command/create-table/create-table.handler.js +47 -0
  25. package/dist/service/dynamodb/command/create-table/create-table.handler.js.map +1 -0
  26. package/dist/service/dynamodb/command/describe-table/describe-table.handler.d.ts +17 -0
  27. package/dist/service/dynamodb/command/describe-table/describe-table.handler.d.ts.map +1 -0
  28. package/dist/service/dynamodb/command/describe-table/describe-table.handler.js +37 -0
  29. package/dist/service/dynamodb/command/describe-table/describe-table.handler.js.map +1 -0
  30. package/dist/service/dynamodb/command/list-tables/list-tables.handler.d.ts +17 -0
  31. package/dist/service/dynamodb/command/list-tables/list-tables.handler.d.ts.map +1 -0
  32. package/dist/service/dynamodb/command/list-tables/list-tables.handler.js +32 -0
  33. package/dist/service/dynamodb/command/list-tables/list-tables.handler.js.map +1 -0
  34. package/dist/service/dynamodb/command/put-item/put-item.handler.d.ts +17 -0
  35. package/dist/service/dynamodb/command/put-item/put-item.handler.d.ts.map +1 -0
  36. package/dist/service/dynamodb/command/put-item/put-item.handler.js +39 -0
  37. package/dist/service/dynamodb/command/put-item/put-item.handler.js.map +1 -0
  38. package/dist/service/dynamodb/dynamodb.d.ts +27 -0
  39. package/dist/service/dynamodb/dynamodb.d.ts.map +1 -0
  40. package/dist/service/dynamodb/dynamodb.js +43 -0
  41. package/dist/service/dynamodb/dynamodb.js.map +1 -0
  42. package/dist/service/dynamodb/index.d.ts +2 -0
  43. package/dist/service/dynamodb/index.d.ts.map +1 -0
  44. package/dist/service/dynamodb/index.js +2 -0
  45. package/dist/service/dynamodb/index.js.map +1 -0
  46. package/dist/service/dynamodb/item/dynamodb-item-attribute.d.ts +21 -0
  47. package/dist/service/dynamodb/item/dynamodb-item-attribute.d.ts.map +1 -0
  48. package/dist/service/dynamodb/item/dynamodb-item-attribute.js +92 -0
  49. package/dist/service/dynamodb/item/dynamodb-item-attribute.js.map +1 -0
  50. package/dist/service/dynamodb/item/dynamodb-item.d.ts +18 -0
  51. package/dist/service/dynamodb/item/dynamodb-item.d.ts.map +1 -0
  52. package/dist/service/dynamodb/item/dynamodb-item.js +29 -0
  53. package/dist/service/dynamodb/item/dynamodb-item.js.map +1 -0
  54. package/dist/service/dynamodb/table/dynamodb-key-schema.d.ts +30 -0
  55. package/dist/service/dynamodb/table/dynamodb-key-schema.d.ts.map +1 -0
  56. package/dist/service/dynamodb/table/dynamodb-key-schema.js +61 -0
  57. package/dist/service/dynamodb/table/dynamodb-key-schema.js.map +1 -0
  58. package/dist/service/dynamodb/table/dynamodb-table.d.ts +34 -0
  59. package/dist/service/dynamodb/table/dynamodb-table.d.ts.map +1 -0
  60. package/dist/service/dynamodb/table/dynamodb-table.js +55 -0
  61. package/dist/service/dynamodb/table/dynamodb-table.js.map +1 -0
  62. package/dist/service/organizations/index.d.ts +2 -0
  63. package/dist/service/organizations/index.d.ts.map +1 -0
  64. package/dist/service/organizations/index.js +2 -0
  65. package/dist/service/organizations/index.js.map +1 -0
  66. package/dist/service/organizations/sim-aws-account.d.ts +19 -0
  67. package/dist/service/organizations/sim-aws-account.d.ts.map +1 -0
  68. package/dist/service/organizations/sim-aws-account.js +26 -0
  69. package/dist/service/organizations/sim-aws-account.js.map +1 -0
  70. package/dist/service/s3/index.d.ts +2 -0
  71. package/dist/service/s3/index.d.ts.map +1 -0
  72. package/dist/service/s3/index.js +3 -0
  73. package/dist/service/s3/index.js.map +1 -0
  74. package/dist/util/background/background.d.ts +28 -0
  75. package/dist/util/background/background.d.ts.map +1 -0
  76. package/dist/util/background/background.js +44 -0
  77. package/dist/util/background/background.js.map +1 -0
  78. package/dist/util/brand.type.d.ts +8 -0
  79. package/dist/util/brand.type.d.ts.map +1 -0
  80. package/dist/util/brand.type.js +2 -0
  81. package/dist/util/brand.type.js.map +1 -0
  82. package/dist/util/defined.d.ts +5 -0
  83. package/dist/util/defined.d.ts.map +1 -0
  84. package/dist/util/defined.js +11 -0
  85. package/dist/util/defined.js.map +1 -0
  86. package/dist/util/memo/memo.d.ts +15 -0
  87. package/dist/util/memo/memo.d.ts.map +1 -0
  88. package/dist/util/memo/memo.js +24 -0
  89. package/dist/util/memo/memo.js.map +1 -0
  90. package/dist/util/sleep.d.ts +10 -0
  91. package/dist/util/sleep.d.ts.map +1 -0
  92. package/dist/util/sleep.js +16 -0
  93. package/dist/util/sleep.js.map +1 -0
  94. package/package.json +38 -19
  95. package/.github/workflows/pr.yml +0 -54
  96. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  97. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  98. package/.idea/jsLinters/eslint.xml +0 -6
  99. package/.idea/modules.xml +0 -8
  100. package/.idea/prettier.xml +0 -7
  101. package/.idea/vcs.xml +0 -6
  102. package/.idea/yulin.iml +0 -8
  103. package/.nvmrc +0 -1
  104. package/.prettierrc +0 -4
  105. package/eslint.config.ts +0 -208
  106. package/pnpm-workspace.yaml +0 -1
  107. package/src/command/command-handler.ts +0 -3
  108. package/src/service/dynamodb/command/create-table/create-table.handler.ts +0 -59
  109. package/src/service/dynamodb/command/create-table/create-table.iso.test.ts +0 -67
  110. package/src/service/dynamodb/command/describe-table/describe-table.handler.ts +0 -50
  111. package/src/service/dynamodb/command/describe-table/describe-table.iso.test.ts +0 -67
  112. package/src/service/dynamodb/command/list-tables/list-tables.handler.ts +0 -51
  113. package/src/service/dynamodb/command/list-tables/list-tables.iso.test.ts +0 -74
  114. package/src/service/dynamodb/dynamodb-table.iso.test.ts +0 -41
  115. package/src/service/dynamodb/dynamodb-table.ts +0 -46
  116. package/src/service/dynamodb/dynamodb.ts +0 -46
  117. package/src/service/organizations/sim-aws-account.ts +0 -36
  118. package/src/util/background/background.iso.test.ts +0 -74
  119. package/src/util/background/background.ts +0 -62
  120. package/src/util/brand.type.ts +0 -11
  121. package/src/util/memo/memo.iso.test.ts +0 -43
  122. package/src/util/memo/memo.ts +0 -26
  123. package/src/util/sleep.ts +0 -16
  124. package/tsconfig.build.json +0 -13
  125. package/tsconfig.json +0 -36
  126. package/typings/eslint-plugin-promise.d.ts +0 -11
  127. package/vitest.config.ts +0 -50
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Async sleep for an approximate number of milliseconds.
3
+ */
4
+ export declare function sleep(ms?: number): Promise<void>;
5
+ /**
6
+ * Sleep for a random but short length of time, e.g. to simulate asynchronous
7
+ * operations completing in a non-deterministic order.
8
+ */
9
+ export declare function jitter(): Promise<void>;
10
+ //# sourceMappingURL=sleep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sleep.d.ts","sourceRoot":"","sources":["../../src/util/sleep.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAsB,KAAK,CAAC,EAAE,SAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjD;AAED;;;GAGG;AACH,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAE5C"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Async sleep for an approximate number of milliseconds.
3
+ */
4
+ export async function sleep(ms = 0) {
5
+ await new Promise((resolve) => {
6
+ setTimeout(resolve, ms);
7
+ });
8
+ }
9
+ /**
10
+ * Sleep for a random but short length of time, e.g. to simulate asynchronous
11
+ * operations completing in a non-deterministic order.
12
+ */
13
+ export async function jitter() {
14
+ await sleep(Math.random());
15
+ }
16
+ //# sourceMappingURL=sleep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sleep.js","sourceRoot":"","sources":["../../src/util/sleep.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,EAAE,GAAG,CAAC;IAChC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC5B,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AAC7B,CAAC"}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@kensio/yulin",
3
- "version": "0.0.2",
3
+ "version": "0.1.1",
4
4
  "description": "AWS system behaviour simulation for isolated unit testing",
5
5
  "repository": "https://github.com/KensioSoftware/yulin",
6
6
  "type": "module",
7
- "main": "index.js",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
8
9
  "keywords": [
9
10
  "aws",
10
11
  "test",
@@ -13,32 +14,49 @@
13
14
  "simulator",
14
15
  "isolated"
15
16
  ],
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js"
21
+ },
22
+ "./cloudfront": {
23
+ "types": "./dist/service/cloudfront/index.d.ts",
24
+ "import": "./dist/service/cloudfront/index.js"
25
+ },
26
+ "./package.json": "./package.json"
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "README.md",
31
+ "LICENSE"
32
+ ],
16
33
  "author": "Kensio Software",
17
34
  "license": "AGPL-3.0",
18
35
  "devDependencies": {
19
- "@aws-sdk/client-dynamodb": "^3.1001.0",
20
- "@aws-sdk/client-s3": "^3.1001.0",
36
+ "@aws-sdk/client-dynamodb": "^3.1056.0",
37
+ "@aws-sdk/client-s3": "^3.1056.0",
21
38
  "@eslint/js": "^10.0.1",
22
- "@kensio/smartass": "^0.1.4",
23
- "@smithy/smithy-client": "^4.12.1",
24
- "@smithy/types": "^4.13.0",
39
+ "@faker-js/faker": "^10.4.0",
40
+ "@kensio/smartass": "^1.0.0",
41
+ "@smithy/smithy-client": "^4.13.5",
42
+ "@smithy/types": "^4.14.2",
25
43
  "@types/eslint-plugin-security": "^3.0.1",
26
44
  "@types/lodash-es": "^4.17.12",
27
- "@types/node": "^25.3.0",
28
- "@vitest/coverage-v8": "4.0.18",
29
- "@vitest/eslint-plugin": "^1.6.9",
45
+ "@types/node": "^25.9.1",
46
+ "@vitest/coverage-v8": "^4.1.7",
47
+ "@vitest/eslint-plugin": "^1.6.18",
30
48
  "aws-sdk-client-mock": "^4.1.0",
31
- "eslint": "^10.0.1",
49
+ "eslint": "^10.4.0",
32
50
  "eslint-config-prettier": "^10.1.8",
33
- "eslint-plugin-jsdoc": "^62.7.1",
34
- "eslint-plugin-no-secrets": "^2.2.2",
51
+ "eslint-plugin-jsdoc": "^62.9.0",
52
+ "eslint-plugin-no-secrets": "^2.3.3",
35
53
  "eslint-plugin-security": "^4.0.0",
36
54
  "eslint-plugin-unicorn": "^63.0.0",
37
- "globals": "^17.3.0",
38
- "jiti": "^2.6.1",
39
- "prettier": "^3.8.1",
40
- "typescript-eslint": "^8.56.0",
41
- "vitest": "^4.0.18"
55
+ "globals": "^17.6.0",
56
+ "jiti": "^2.7.0",
57
+ "prettier": "^3.8.3",
58
+ "typescript-eslint": "^8.60.0",
59
+ "vitest": "^4.1.7"
42
60
  },
43
61
  "peerDependencies": {
44
62
  "@aws-sdk/client-dynamodb": "^3.1001.0",
@@ -57,7 +75,8 @@
57
75
  }
58
76
  },
59
77
  "dependencies": {
60
- "lodash-es": "^4.17.23"
78
+ "@kensio/part-factory": "^0.1.1",
79
+ "lodash-es": "^4.18.1"
61
80
  },
62
81
  "scripts": {
63
82
  "build": "tsc -p tsconfig.build.json",
@@ -1,54 +0,0 @@
1
- ---
2
- name: PR
3
-
4
- on:
5
- pull_request:
6
- branches:
7
- - main
8
-
9
- defaults:
10
- run:
11
- shell: bash
12
-
13
- env:
14
- CI: true
15
-
16
- jobs:
17
- lint:
18
- name: Lint
19
- runs-on: blacksmith-4vcpu-ubuntu-2404
20
- steps:
21
- - uses: actions/checkout@v6
22
- - uses: pnpm/action-setup@v4
23
- - uses: actions/setup-node@v6
24
- with:
25
- node-version-file: .nvmrc
26
- cache: pnpm
27
- - run: pnpm install --frozen-lockfile
28
- - run: pnpm lint
29
-
30
- test:
31
- name: Test
32
- runs-on: blacksmith-4vcpu-ubuntu-2404
33
- steps:
34
- - uses: actions/checkout@v6
35
- - uses: pnpm/action-setup@v4
36
- - uses: actions/setup-node@v6
37
- with:
38
- node-version-file: .nvmrc
39
- cache: pnpm
40
- - run: pnpm install --frozen-lockfile
41
- - run: pnpm test:coverage
42
-
43
- build:
44
- name: Build
45
- runs-on: blacksmith-4vcpu-ubuntu-2404
46
- steps:
47
- - uses: actions/checkout@v6
48
- - uses: pnpm/action-setup@v4
49
- - uses: actions/setup-node@v6
50
- with:
51
- node-version-file: .nvmrc
52
- cache: pnpm
53
- - run: pnpm install --frozen-lockfile
54
- - run: pnpm build
@@ -1,5 +0,0 @@
1
- <component name="ProjectCodeStyleConfiguration">
2
- <state>
3
- <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
4
- </state>
5
- </component>
@@ -1,6 +0,0 @@
1
- <component name="InspectionProjectProfileManager">
2
- <profile version="1.0">
3
- <option name="myName" value="Project Default" />
4
- <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
5
- </profile>
6
- </component>
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="EslintConfiguration">
4
- <option name="fix-on-save" value="true" />
5
- </component>
6
- </project>
package/.idea/modules.xml DELETED
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectModuleManager">
4
- <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/yulin.iml" filepath="$PROJECT_DIR$/.idea/yulin.iml" />
6
- </modules>
7
- </component>
8
- </project>
@@ -1,7 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="PrettierConfiguration">
4
- <option name="myConfigurationMode" value="AUTOMATIC" />
5
- <option name="myRunOnSave" value="true" />
6
- </component>
7
- </project>
package/.idea/vcs.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="VcsDirectoryMappings">
4
- <mapping directory="" vcs="Git" />
5
- </component>
6
- </project>
package/.idea/yulin.iml DELETED
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="WEB_MODULE" version="4">
3
- <component name="NewModuleRootManager">
4
- <content url="file://$MODULE_DIR$" />
5
- <orderEntry type="inheritedJdk" />
6
- <orderEntry type="sourceFolder" forTests="false" />
7
- </component>
8
- </module>
package/.nvmrc DELETED
@@ -1 +0,0 @@
1
- v24.14.0
package/.prettierrc DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "trailingComma": "all",
3
- "tabWidth": 2
4
- }
package/eslint.config.ts DELETED
@@ -1,208 +0,0 @@
1
- import { dirname } from "node:path";
2
- import { fileURLToPath } from "node:url";
3
-
4
- import eslint from "@eslint/js";
5
- import vitest from "@vitest/eslint-plugin";
6
- import { defineConfig } from "eslint/config";
7
- import prettier from "eslint-config-prettier";
8
- import { jsdoc } from "eslint-plugin-jsdoc";
9
- import noSecrets from "eslint-plugin-no-secrets";
10
- import security from "eslint-plugin-security";
11
- import unicorn from "eslint-plugin-unicorn";
12
- import globals from "globals";
13
- import tseslint from "typescript-eslint";
14
-
15
- const __dirname = dirname(fileURLToPath(import.meta.url));
16
-
17
- export default defineConfig(
18
- // ── Global ignores ──────────────────────────────────────
19
- {
20
- ignores: ["dist/", "**/.coverage/*", "node_modules/", "*.config.ts"],
21
- },
22
-
23
- // ── Base ESLint recommended ─────────────────────────────
24
- eslint.configs.recommended,
25
-
26
- // ── TypeScript (strictest level + type-aware) ───────────
27
- ...tseslint.configs.strictTypeChecked,
28
- ...tseslint.configs.stylisticTypeChecked,
29
-
30
- // ── General settings for all TS files ───────────────────
31
- {
32
- languageOptions: {
33
- ecmaVersion: "latest",
34
- sourceType: "module",
35
- globals: {
36
- ...globals.node,
37
- },
38
- parserOptions: {
39
- projectService: true,
40
- tsconfigRootDir: __dirname,
41
- },
42
- },
43
- rules: {
44
- // ── TypeScript overrides & additions ──────────────
45
- "@typescript-eslint/explicit-function-return-type": "error",
46
- "@typescript-eslint/explicit-module-boundary-types": "error",
47
- "@typescript-eslint/no-explicit-any": "error",
48
- "@typescript-eslint/consistent-type-imports": [
49
- "error",
50
- { prefer: "type-imports", fixStyle: "inline-type-imports" },
51
- ],
52
- "@typescript-eslint/consistent-type-exports": [
53
- "error",
54
- { fixMixedExportsWithInlineTypeSpecifier: true },
55
- ],
56
- "@typescript-eslint/no-import-type-side-effects": "error",
57
- "@typescript-eslint/switch-exhaustiveness-check": "error",
58
- "@typescript-eslint/no-unnecessary-condition": "error",
59
- "@typescript-eslint/prefer-nullish-coalescing": "error",
60
- "@typescript-eslint/strict-boolean-expressions": "error",
61
- "no-await-in-loop": "error", // catches sequential awaits that should be Promise.all()
62
- "no-template-curly-in-string": "error", // catches '${name}' in regular strings (missing backticks)
63
- "no-promise-executor-return": "error", // catches accidental return in new Promise((resolve) => return ...)
64
- "no-unreachable-loop": "error", // catches loops that only ever run once
65
- "no-param-reassign": "error", // prevents mutating function parameters (major bug source)
66
- "prefer-const": "error", // const over let when never reassigned
67
- "object-shorthand": ["error", "always"], // { foo: foo } → { foo }
68
- "prefer-template": "error", // template literals over string concatenation
69
- "@typescript-eslint/prefer-readonly": "error", // flags private fields that are never reassigned
70
- "@typescript-eslint/require-array-sort-compare": "error", // prevents [1, 10, 2].sort() (lexicographic surprise)
71
- "@typescript-eslint/naming-convention": [
72
- "error",
73
- {
74
- selector: ["property", "objectLiteralProperty", "typeProperty"],
75
- format: ["camelCase", "PascalCase"],
76
- leadingUnderscore: "allow",
77
- },
78
- {
79
- selector: "default",
80
- format: ["camelCase"],
81
- leadingUnderscore: "allow",
82
- },
83
- {
84
- selector: "typeLike",
85
- format: ["PascalCase"],
86
- },
87
- {
88
- selector: "enumMember",
89
- format: ["PascalCase"],
90
- },
91
- {
92
- selector: "variable",
93
- modifiers: ["const", "exported"],
94
- format: ["camelCase", "UPPER_CASE"],
95
- },
96
- ],
97
-
98
- // ── General quality ──────────────────────────────
99
- "no-console": "warn",
100
- eqeqeq: ["error", "always"],
101
- curly: ["error", "all"],
102
- "@typescript-eslint/only-throw-error": "error",
103
- },
104
- },
105
-
106
- // ── Security (low cost security checks) ────────────────
107
- // TODO: Remove cast when eslint-plugin-security fixes defineConfig() types
108
- // https://github.com/eslint-community/eslint-plugin-security/issues/175
109
- security.configs.recommended as any,
110
-
111
- // ── Unicorn (modern JS best practices) ──────────────────
112
- // https://github.com/sindresorhus/eslint-plugin-unicorn?tab=readme-ov-file#recommended-config
113
- unicorn.configs.recommended,
114
- {
115
- rules: {
116
- "unicorn/better-regex": "warn",
117
- "unicorn/prevent-abbreviations": "off",
118
- },
119
- },
120
-
121
- // ── Vitest (test files only) ────────────────────────────
122
- {
123
- files: ["**/*.test.ts"],
124
- plugins: {
125
- vitest,
126
- },
127
- rules: {
128
- ...vitest.configs.recommended.rules,
129
- "vitest/consistent-test-it": ["error", { fn: "it" }],
130
- "vitest/no-focused-tests": "error",
131
- "vitest/no-disabled-tests": "warn",
132
- "vitest/no-duplicate-hooks": "error",
133
- "vitest/prefer-to-be": "error",
134
- "vitest/prefer-to-have-length": "error",
135
- "vitest/prefer-strict-equal": "error",
136
- "vitest/require-top-level-describe": "error",
137
- "vitest/expect-expect": "off",
138
-
139
- // Relax some rules that are too strict for test files
140
- "@typescript-eslint/no-explicit-any": "off",
141
- "@typescript-eslint/no-unsafe-assignment": "off",
142
- "@typescript-eslint/no-unsafe-member-access": "off",
143
- "@typescript-eslint/explicit-function-return-type": "off",
144
- "import-x/no-default-export": "off",
145
- },
146
- },
147
-
148
- // ── Config files (allow default exports) ────────────────
149
- {
150
- files: ["*.config.ts", "*.config.js"],
151
- rules: {
152
- "import-x/no-default-export": "off",
153
- },
154
- },
155
-
156
- // ── No Secrets (detect accidental secret inclusion) ────────
157
- {
158
- plugins: { "no-secrets": noSecrets },
159
- rules: {
160
- "no-secrets/no-secrets": "error",
161
- },
162
- },
163
-
164
- // ── JSDoc (enforce minimal doc commenting) ────────────────
165
- jsdoc({
166
- config: "flat/recommended-error",
167
- }),
168
- {
169
- rules: {
170
- "jsdoc/require-param": "off",
171
- "jsdoc/require-returns": "off",
172
- "jsdoc/require-param-description": "off",
173
- "jsdoc/require-returns-description": "off",
174
- "jsdoc/require-yields": "off",
175
- "jsdoc/require-description": [
176
- "error",
177
- {
178
- descriptionStyle: "body",
179
- checkConstructors: false,
180
- checkGetters: false,
181
- checkSetters: false,
182
- },
183
- ],
184
- "jsdoc/require-jsdoc": [
185
- "error",
186
- {
187
- contexts: [
188
- "ClassDeclaration",
189
- "ExportNamedDeclaration > VariableDeclaration[kind='const'] > VariableDeclarator[init.type='ObjectExpression']",
190
- "ExportNamedDeclaration > VariableDeclaration[kind='const'] > VariableDeclarator[init.type='ArrayExpression']",
191
- "ExportNamedDeclaration > VariableDeclaration[kind='const'] > VariableDeclarator[init.type='NewExpression']",
192
- "ExportNamedDeclaration > VariableDeclaration[kind='const'] > VariableDeclarator[init.type='CallExpression']",
193
- ],
194
- publicOnly: true,
195
- checkConstructors: false,
196
- require: {
197
- FunctionDeclaration: true,
198
- MethodDefinition: true,
199
- ClassDeclaration: true,
200
- },
201
- },
202
- ],
203
- },
204
- },
205
-
206
- // ── Prettier (must be last — disables conflicting rules)
207
- prettier,
208
- );
@@ -1 +0,0 @@
1
- useNodeVersion: 24.13.1
@@ -1,3 +0,0 @@
1
- export interface CommandHandler<TCommand, TOutput> {
2
- handle(cmd: TCommand): Promise<TOutput>;
3
- }
@@ -1,59 +0,0 @@
1
- import type { DynamoDbTableName } from "../../dynamodb-table.js";
2
- import { SimDynamoDbTable } from "../../dynamodb-table.js";
3
- import {
4
- type CreateTableCommand,
5
- type CreateTableCommandOutput,
6
- ResourceInUseException,
7
- } from "@aws-sdk/client-dynamodb";
8
- import type { BackgroundScheduler } from "../../../../util/background/background.js";
9
- import type { CommandHandler } from "../../../../command/command-handler.js";
10
- import { jitter } from "../../../../util/sleep.js";
11
-
12
- /**
13
- * DynamoDB CreateTableCommand handler.
14
- */
15
- export class CreateTableCommandHandler implements CommandHandler<
16
- CreateTableCommand,
17
- CreateTableCommandOutput
18
- > {
19
- constructor(
20
- private readonly tables: Map<DynamoDbTableName, SimDynamoDbTable>,
21
- private readonly background: BackgroundScheduler,
22
- ) {}
23
-
24
- /**
25
- * Handle creation of a new DynamoDB Table.
26
- */
27
- async handle(cmd: CreateTableCommand): Promise<CreateTableCommandOutput> {
28
- if (cmd.input.TableName === undefined) {
29
- throw new Error("CreateTableCommand.input.TableName is required");
30
- }
31
-
32
- const tableName = cmd.input.TableName as DynamoDbTableName;
33
- if (this.tables.has(tableName)) {
34
- throw new ResourceInUseException({
35
- message: `DynamoDB Table ${tableName} already exists`,
36
- $metadata: {},
37
- });
38
- }
39
-
40
- await jitter();
41
-
42
- const table = new SimDynamoDbTable(cmd);
43
- this.tables.set(tableName, table);
44
-
45
- this.background.schedule(() => table.activate());
46
-
47
- return {
48
- TableDescription: {
49
- AttributeDefinitions: [],
50
- TableName: tableName,
51
- KeySchema: [],
52
- TableStatus: table.status,
53
- CreationDateTime: table.creationDateTime,
54
- GlobalSecondaryIndexes: [],
55
- },
56
- $metadata: {},
57
- };
58
- }
59
- }
@@ -1,67 +0,0 @@
1
- import { describe, it } from "vitest";
2
- import {
3
- CreateTableCommand,
4
- ListTablesCommand,
5
- ResourceInUseException,
6
- } from "@aws-sdk/client-dynamodb";
7
- import { SimAwsAccount } from "../../../organizations/sim-aws-account.js";
8
- import {
9
- assertArrayLength,
10
- assertIdentical,
11
- assertInstanceOf,
12
- assertNonNullable,
13
- assertThrowsErrorAsync,
14
- } from "@kensio/smartass";
15
-
16
- describe("DynamoDB CreateTableCommand", () => {
17
- it("creates new DynamoDB Table", async () => {
18
- const simAccount = new SimAwsAccount();
19
- const simDynamoDb = simAccount.getDynamoDb();
20
-
21
- const createTableOutput = await simDynamoDb.createTable(
22
- new CreateTableCommand({ TableName: "FoobarTable" }),
23
- );
24
-
25
- assertNonNullable(createTableOutput.TableDescription);
26
- assertIdentical(
27
- createTableOutput.TableDescription.TableName,
28
- "FoobarTable",
29
- );
30
- assertIdentical(createTableOutput.TableDescription.TableStatus, "CREATING");
31
-
32
- const listTablesOutput = await simDynamoDb.listTables(
33
- new ListTablesCommand(),
34
- );
35
-
36
- assertArrayLength(listTablesOutput.TableNames, 1);
37
- assertIdentical(listTablesOutput.TableNames[0], "FoobarTable");
38
-
39
- await simAccount.backgroundTasksComplete();
40
- });
41
-
42
- it("throws on undefined Table name", async () => {
43
- const simAccount = new SimAwsAccount();
44
- const simDynamoDb = simAccount.getDynamoDb();
45
-
46
- await assertThrowsErrorAsync(async () =>
47
- simDynamoDb.createTable(new CreateTableCommand({ TableName: undefined })),
48
- );
49
- });
50
-
51
- it("throws on duplicate Table name", async () => {
52
- const simAccount = new SimAwsAccount();
53
- const simDynamoDb = simAccount.getDynamoDb();
54
-
55
- await simDynamoDb.createTable(
56
- new CreateTableCommand({ TableName: "FoobarTable" }),
57
- );
58
-
59
- const error = await assertThrowsErrorAsync(async () =>
60
- simDynamoDb.createTable(
61
- new CreateTableCommand({ TableName: "FoobarTable" }),
62
- ),
63
- );
64
- assertInstanceOf(error, ResourceInUseException);
65
- assertIdentical(error.$fault, "client");
66
- });
67
- });
@@ -1,50 +0,0 @@
1
- import {
2
- ResourceNotFoundException,
3
- type DescribeTableCommand,
4
- type DescribeTableOutput,
5
- } from "@aws-sdk/client-dynamodb";
6
- import type { CommandHandler } from "../../../../command/command-handler.js";
7
- import type {
8
- DynamoDbTableName,
9
- SimDynamoDbTable,
10
- } from "../../dynamodb-table.js";
11
- import { jitter } from "../../../../util/sleep.js";
12
-
13
- /**
14
- * DynamoDB DescribeTableCommand handler.
15
- */
16
- export class DescribeTableCommandHandler implements CommandHandler<
17
- DescribeTableCommand,
18
- DescribeTableOutput
19
- > {
20
- constructor(
21
- private readonly tables: Map<DynamoDbTableName, SimDynamoDbTable>,
22
- ) {}
23
-
24
- /**
25
- * Simulate describing DynamoDB Table.
26
- */
27
- async handle(cmd: DescribeTableCommand): Promise<DescribeTableOutput> {
28
- if (cmd.input.TableName === undefined) {
29
- throw new Error("DescribeTableCommand.input.TableName is required");
30
- }
31
- const tableName = cmd.input.TableName as DynamoDbTableName;
32
-
33
- await jitter();
34
-
35
- const table = this.tables.get(tableName);
36
- if (table === undefined) {
37
- throw new ResourceNotFoundException({
38
- message: `No DynamoDB Table named ${tableName}`,
39
- $metadata: {},
40
- });
41
- }
42
-
43
- return {
44
- Table: {
45
- TableName: table.tableName,
46
- TableStatus: table.status,
47
- },
48
- };
49
- }
50
- }