@toolpath/tool-support 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/forms.d.ts +14 -0
- package/dist/forms.js +14 -0
- package/dist/holding.d.ts +19 -1
- package/dist/holding.js +31 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/tool.d.ts +38 -0
- package/dist/tool.js +10 -0
- package/package.json +7 -7
package/dist/forms.d.ts
CHANGED
|
@@ -128,3 +128,17 @@ export type ToolForm = (typeof TOOL_FORMS)[number]['value'] | 'other';
|
|
|
128
128
|
/** The forms that mill — the ones a flute-count suggestion makes sense for. */
|
|
129
129
|
export declare const MILLING_FORMS: ReadonlySet<ToolForm>;
|
|
130
130
|
export declare const isToolForm: (value: string) => value is ToolForm;
|
|
131
|
+
/**
|
|
132
|
+
* The forms that cut a thread with a square-driven tool — the taps.
|
|
133
|
+
*
|
|
134
|
+
* Derived from {@link TOOL_FORMS} by the vocabulary's own naming, the way
|
|
135
|
+
* {@link MILLING_FORMS} is derived from its `group`. A rostered pair of strings
|
|
136
|
+
* beside the list would be a second copy of the vocabulary to disagree with it.
|
|
137
|
+
* `'tapered mill'` is not matched: the prefix is `'tap '` with the space.
|
|
138
|
+
*
|
|
139
|
+
* `'Hole making'` is the wrong axis here — it holds drills, reamers and boring
|
|
140
|
+
* bars — which is why this cannot be a `group` filter.
|
|
141
|
+
*/
|
|
142
|
+
export declare const TAP_FORMS: ReadonlySet<ToolForm>;
|
|
143
|
+
/** Whether a form is a tap, and therefore driven by a square. */
|
|
144
|
+
export declare const isTapForm: (form: string) => boolean;
|
package/dist/forms.js
CHANGED
|
@@ -42,3 +42,17 @@ export const TOOL_FORMS = [
|
|
|
42
42
|
/** The forms that mill — the ones a flute-count suggestion makes sense for. */
|
|
43
43
|
export const MILLING_FORMS = new Set(TOOL_FORMS.filter((form) => form.group === 'Milling').map((form) => form.value));
|
|
44
44
|
export const isToolForm = (value) => value === 'other' || TOOL_FORMS.some((form) => form.value === value);
|
|
45
|
+
/**
|
|
46
|
+
* The forms that cut a thread with a square-driven tool — the taps.
|
|
47
|
+
*
|
|
48
|
+
* Derived from {@link TOOL_FORMS} by the vocabulary's own naming, the way
|
|
49
|
+
* {@link MILLING_FORMS} is derived from its `group`. A rostered pair of strings
|
|
50
|
+
* beside the list would be a second copy of the vocabulary to disagree with it.
|
|
51
|
+
* `'tapered mill'` is not matched: the prefix is `'tap '` with the space.
|
|
52
|
+
*
|
|
53
|
+
* `'Hole making'` is the wrong axis here — it holds drills, reamers and boring
|
|
54
|
+
* bars — which is why this cannot be a `group` filter.
|
|
55
|
+
*/
|
|
56
|
+
export const TAP_FORMS = new Set(TOOL_FORMS.filter((form) => form.value.startsWith('tap ')).map((form) => form.value));
|
|
57
|
+
/** Whether a form is a tap, and therefore driven by a square. */
|
|
58
|
+
export const isTapForm = (form) => TAP_FORMS.has(form);
|
package/dist/holding.d.ts
CHANGED
|
@@ -129,6 +129,19 @@ export interface Collet {
|
|
|
129
129
|
* to be "nobody has said" rather than an invented grip rule.
|
|
130
130
|
*/
|
|
131
131
|
readonly clampLength: number | null;
|
|
132
|
+
/**
|
|
133
|
+
* The square drive this collet grips, across flats, in millimetres.
|
|
134
|
+
*
|
|
135
|
+
* A tap collet's bore is not round: it carries a square that drives the tap,
|
|
136
|
+
* so the part it takes is a tap and nothing else. `null` — and absent — is
|
|
137
|
+
* "nobody has said", which is every collet whose vendor publishes no square,
|
|
138
|
+
* and those go on taking anything their capacity band fits.
|
|
139
|
+
*
|
|
140
|
+
* Optional rather than required because {@link Collet} is a shape consumers
|
|
141
|
+
* build, and a collet crib assembled before this existed states the same
|
|
142
|
+
* thing by saying nothing.
|
|
143
|
+
*/
|
|
144
|
+
readonly squareSize?: number | null;
|
|
132
145
|
readonly provenance?: ProvenanceMap;
|
|
133
146
|
}
|
|
134
147
|
/**
|
|
@@ -176,8 +189,13 @@ export declare const gripsShank: (collet: Pick<Collet, "clampMin" | "clampMax">,
|
|
|
176
189
|
* fit.** This is the one place the domain differs from "what is not stated is
|
|
177
190
|
* not checked", because here the unchecked case is a cutter falling out of a
|
|
178
191
|
* spindle.
|
|
192
|
+
*
|
|
193
|
+
* `form` is read only by {@link Collet.squareSize}'s gate and is optional for
|
|
194
|
+
* that reason: a caller with no form in hand keeps the answer it had for every
|
|
195
|
+
* collet whose vendor publishes no square, which is all of them but the tap
|
|
196
|
+
* collets.
|
|
179
197
|
*/
|
|
180
|
-
export declare const holderTakesTool: (holder: Pick<Holder, "clamping" | "colletSeries" | "boreDiameter">, collet: Collet | null, tool: Pick<Tool, "geometry">) => boolean;
|
|
198
|
+
export declare const holderTakesTool: (holder: Pick<Holder, "clamping" | "colletSeries" | "boreDiameter">, collet: Collet | null, tool: Pick<Tool, "geometry"> & Partial<Pick<Tool, "form">>) => boolean;
|
|
181
199
|
/**
|
|
182
200
|
* The furthest a tool can stand out of its holder, in millimetres: overall
|
|
183
201
|
* length less the length that has to stay gripped.
|
package/dist/holding.js
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
*/
|
|
33
33
|
import { DEFAULT_STICKOUT_POLICY, stickoutRange, } from './stickout.js';
|
|
34
34
|
import { DEFAULT_CLAMPING } from './clamping.js';
|
|
35
|
+
import { isTapForm } from './forms.js';
|
|
35
36
|
/**
|
|
36
37
|
* Which of the two holder forms this is.
|
|
37
38
|
*
|
|
@@ -55,6 +56,27 @@ export const colletFitsHolder = (collet, holder) => holder.clamping === 'collet'
|
|
|
55
56
|
const GRIP_TOLERANCE = 1e-6;
|
|
56
57
|
/** Whether a collet grips a given shank diameter, in millimetres. */
|
|
57
58
|
export const gripsShank = (collet, shank) => shank >= collet.clampMin - GRIP_TOLERANCE && shank <= collet.clampMax + GRIP_TOLERANCE;
|
|
59
|
+
/**
|
|
60
|
+
* Whether the collet's drive suits the tool, which is a second question from
|
|
61
|
+
* whether it grips the shank.
|
|
62
|
+
*
|
|
63
|
+
* A tap collet's square holds one shank diameter exactly, so a shank test alone
|
|
64
|
+
* says yes to an end mill of that size — and an end mill in a square bore is
|
|
65
|
+
* held by nothing. The square is the vendor's own published dimension, so a
|
|
66
|
+
* collet that states one takes a tap and a collet that states none is unchanged.
|
|
67
|
+
*
|
|
68
|
+
* The converse is deliberately **not** enforced: a tap in a plain round collet
|
|
69
|
+
* is how most shops tap, and refusing it would be this package inventing a
|
|
70
|
+
* policy no vendor stated.
|
|
71
|
+
*/
|
|
72
|
+
const driveTakesTool = (collet, tool) => {
|
|
73
|
+
const square = collet.squareSize;
|
|
74
|
+
if (square === null || square === undefined)
|
|
75
|
+
return true;
|
|
76
|
+
// An unstated form is nobody having said, and nobody-has-said does not go in
|
|
77
|
+
// a square bore — the same direction an unstated shank is refused in.
|
|
78
|
+
return tool.form !== undefined && isTapForm(tool.form);
|
|
79
|
+
};
|
|
58
80
|
/**
|
|
59
81
|
* Whether a bore, shrink or hydraulic holder's one diameter is this shank.
|
|
60
82
|
*
|
|
@@ -70,6 +92,11 @@ const boreTakesShank = (bore, shank) => Math.abs(bore - shank) <= GRIP_TOLERANCE
|
|
|
70
92
|
* fit.** This is the one place the domain differs from "what is not stated is
|
|
71
93
|
* not checked", because here the unchecked case is a cutter falling out of a
|
|
72
94
|
* spindle.
|
|
95
|
+
*
|
|
96
|
+
* `form` is read only by {@link Collet.squareSize}'s gate and is optional for
|
|
97
|
+
* that reason: a caller with no form in hand keeps the answer it had for every
|
|
98
|
+
* collet whose vendor publishes no square, which is all of them but the tap
|
|
99
|
+
* collets.
|
|
73
100
|
*/
|
|
74
101
|
export const holderTakesTool = (holder, collet, tool) => {
|
|
75
102
|
const shank = tool.geometry.SFDM;
|
|
@@ -77,7 +104,10 @@ export const holderTakesTool = (holder, collet, tool) => {
|
|
|
77
104
|
return false;
|
|
78
105
|
}
|
|
79
106
|
if (holder.clamping === 'collet') {
|
|
80
|
-
return collet !== null &&
|
|
107
|
+
return (collet !== null &&
|
|
108
|
+
colletFitsHolder(collet, holder) &&
|
|
109
|
+
gripsShank(collet, shank) &&
|
|
110
|
+
driveTakesTool(collet, tool));
|
|
81
111
|
}
|
|
82
112
|
// A holder that states no clamping mode falls here and is refused: absent
|
|
83
113
|
// means nobody has said, and nobody-has-said takes no tool.
|
package/dist/index.d.ts
CHANGED
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
export { MM_PER_INCH, UNIT_ABBREVIATION, UNIT_SYSTEMS, convertArea, convertLength, decimalsFor, formatArea, formatLength, type UnitSystem, } from './units.js';
|
|
48
48
|
export { PROVENANCE, type Provenance, type ProvenanceMap } from './provenance.js';
|
|
49
49
|
export { GEOMETRY_FIELDS, convertGeometry, geometryField, isLengthField, type Geometry, type GeometryCode, type GeometryField, type GeometryUnit, } from './geometry.js';
|
|
50
|
-
export { MILLING_FORMS, TOOL_FORMS, isToolForm, type ToolForm, type ToolFormEntry, } from './forms.js';
|
|
51
|
-
export { hasNeck, shankOf, type Shank, type Tool } from './tool.js';
|
|
50
|
+
export { MILLING_FORMS, TAP_FORMS, TOOL_FORMS, isTapForm, isToolForm, type ToolForm, type ToolFormEntry, } from './forms.js';
|
|
51
|
+
export { THREAD_METHODS, hasNeck, isThreadMethod, shankOf, type Shank, type ThreadMethod, type Tool, } from './tool.js';
|
|
52
52
|
export { PROFILES_VERSION, belowGageLine, type HolderProfile, type ProfileDatum, type ProfilePoint, } from './profile.js';
|
|
53
53
|
export { canHold, colletFitsHolder, defaultStickout, gripRanges, gripsAnyShank, gripsShank, holdBand, holderTakesTool, isHolderProfile, maxStickout, stickoutLimits, type Assembly, type Clamping, type Collet, type GripRanges, type HoldBand, type Holder, } from './holding.js';
|
|
54
54
|
export { DEFAULT_CLAMPING, clampShortfall, clampWanted, headLength, heldDiameter, type ClampingRule, } from './clamping.js';
|
package/dist/index.js
CHANGED
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
export { MM_PER_INCH, UNIT_ABBREVIATION, UNIT_SYSTEMS, convertArea, convertLength, decimalsFor, formatArea, formatLength, } from './units.js';
|
|
48
48
|
export { PROVENANCE } from './provenance.js';
|
|
49
49
|
export { GEOMETRY_FIELDS, convertGeometry, geometryField, isLengthField, } from './geometry.js';
|
|
50
|
-
export { MILLING_FORMS, TOOL_FORMS, isToolForm, } from './forms.js';
|
|
51
|
-
export { hasNeck, shankOf } from './tool.js';
|
|
50
|
+
export { MILLING_FORMS, TAP_FORMS, TOOL_FORMS, isTapForm, isToolForm, } from './forms.js';
|
|
51
|
+
export { THREAD_METHODS, hasNeck, isThreadMethod, shankOf, } from './tool.js';
|
|
52
52
|
export { PROFILES_VERSION, belowGageLine, } from './profile.js';
|
|
53
53
|
export { canHold, colletFitsHolder, defaultStickout, gripRanges, gripsAnyShank, gripsShank, holdBand, holderTakesTool, isHolderProfile, maxStickout, stickoutLimits, } from './holding.js';
|
|
54
54
|
export { DEFAULT_CLAMPING, clampShortfall, clampWanted, headLength, heldDiameter, } from './clamping.js';
|
package/dist/tool.d.ts
CHANGED
|
@@ -24,11 +24,49 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import type { Geometry } from './geometry.js';
|
|
26
26
|
import type { ProvenanceMap } from './provenance.js';
|
|
27
|
+
/**
|
|
28
|
+
* How a tap makes its thread: by cutting it away, or by displacing material
|
|
29
|
+
* into it.
|
|
30
|
+
*
|
|
31
|
+
* **A second axis beside {@link Tool.form}, not two more forms.**
|
|
32
|
+
* `forms.ts`'s vocabulary is Fusion's own, so that a tool exported there lands
|
|
33
|
+
* on the type it already has, and Fusion has no form-tap type — a form tap is a
|
|
34
|
+
* `tap right hand` there like any other. Adding `form tap right hand` would buy
|
|
35
|
+
* a filter chip and cost that guarantee. It is the same call
|
|
36
|
+
* `tool-scraper`'s `families/kennametal.ts` makes for keeping a holder's
|
|
37
|
+
* `contact` off its `taper`: two facts about one part are two fields.
|
|
38
|
+
*
|
|
39
|
+
* The two are genuinely different tools. A former needs a larger hole, evacuates
|
|
40
|
+
* no chip, and runs at its own feed; a cut tap does none of that. Nothing here
|
|
41
|
+
* branches on it yet — a tap goes in on the hole's axis either way, and
|
|
42
|
+
* `tool-drawing` has no publishable shape for either one's lead — but a
|
|
43
|
+
* consumer choosing or feeding a tool cannot ask the question at all until the
|
|
44
|
+
* fact is carried.
|
|
45
|
+
*/
|
|
46
|
+
export type ThreadMethod = 'cutting' | 'forming';
|
|
47
|
+
/**
|
|
48
|
+
* The methods, in the order a control offers them.
|
|
49
|
+
*
|
|
50
|
+
* A list beside the union for the reason `PROVENANCE` is one: `tool-scraper`
|
|
51
|
+
* validates a family's declared value against it rather than redeclaring the
|
|
52
|
+
* two strings, and a filter panel offers it. Cutting leads because it is what
|
|
53
|
+
* most of a catalog is.
|
|
54
|
+
*/
|
|
55
|
+
export declare const THREAD_METHODS: readonly ["cutting", "forming"];
|
|
56
|
+
export declare const isThreadMethod: (value: string) => value is ThreadMethod;
|
|
27
57
|
export interface Tool {
|
|
28
58
|
/** The CAM-library name for what the tool is: `flat end mill`, `drill`, `slot mill`. */
|
|
29
59
|
readonly form: string;
|
|
30
60
|
/** What a machinist calls this one tool — a catalog number, usually. */
|
|
31
61
|
readonly label?: string;
|
|
62
|
+
/**
|
|
63
|
+
* How this tap makes its thread, where it is a tap and somebody has said.
|
|
64
|
+
*
|
|
65
|
+
* Optional, and **absent is nobody having said** rather than a claim of
|
|
66
|
+
* cutting — the rule `holding.ts`'s `Clamping` keeps on a holder and `shankOf` keeps
|
|
67
|
+
* on a shank. A non-tap carries none, because the question does not apply.
|
|
68
|
+
*/
|
|
69
|
+
readonly threadMethod?: ThreadMethod;
|
|
32
70
|
readonly geometry: Geometry;
|
|
33
71
|
readonly provenance?: ProvenanceMap;
|
|
34
72
|
}
|
package/dist/tool.js
CHANGED
|
@@ -28,6 +28,16 @@
|
|
|
28
28
|
* 9.525 on the collet's sheet and 9.524999999999999 on the tool's.
|
|
29
29
|
*/
|
|
30
30
|
const EPSILON = 1e-6;
|
|
31
|
+
/**
|
|
32
|
+
* The methods, in the order a control offers them.
|
|
33
|
+
*
|
|
34
|
+
* A list beside the union for the reason `PROVENANCE` is one: `tool-scraper`
|
|
35
|
+
* validates a family's declared value against it rather than redeclaring the
|
|
36
|
+
* two strings, and a filter panel offers it. Cutting leads because it is what
|
|
37
|
+
* most of a catalog is.
|
|
38
|
+
*/
|
|
39
|
+
export const THREAD_METHODS = ['cutting', 'forming'];
|
|
40
|
+
export const isThreadMethod = (value) => THREAD_METHODS.some((method) => method === value);
|
|
31
41
|
/**
|
|
32
42
|
* Whether the section between the flutes and the shank is a neck: a stated
|
|
33
43
|
* shoulder past the flutes, narrower than the shank.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toolpath/tool-support",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "The cutting-tool domain: what a tool, holder, collet and assembly are",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"engines": {
|
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
"README.md"
|
|
36
36
|
],
|
|
37
37
|
"sideEffects": false,
|
|
38
|
-
"scripts": {
|
|
39
|
-
"build": "tsc -p tsconfig.build.json",
|
|
40
|
-
"check-types": "tsc --noEmit",
|
|
41
|
-
"test": "vitest run"
|
|
42
|
-
},
|
|
43
38
|
"devDependencies": {
|
|
44
39
|
"@types/node": "24.10.1",
|
|
45
40
|
"typescript": "5.9.3",
|
|
46
41
|
"vitest": "4.1.10"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc -p tsconfig.build.json",
|
|
45
|
+
"check-types": "tsc --noEmit",
|
|
46
|
+
"test": "vitest run"
|
|
47
47
|
}
|
|
48
|
-
}
|
|
48
|
+
}
|